diff --git a/jest.config.js b/jest.config.js index f5de6fad3e71530dd29dd00f270370f7b80e5acc..e526d5087d94577d321071a8683ea01bc792826f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -10,6 +10,11 @@ module.exports = { __GLOBAL__: false, __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false, + uni: { + requireNativePlugin(name) { + return {} + }, + }, }, coverageDirectory: 'coverage', coverageReporters: ['html', 'lcov', 'text'], diff --git a/packages/uni-uts-vite/__tests__/module.spec.ts b/packages/uni-uts-vite/__tests__/module.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..faf8b76cabad7fc9d09bf3e978bdd885c43022e2 --- /dev/null +++ b/packages/uni-uts-vite/__tests__/module.spec.ts @@ -0,0 +1,42 @@ +import { normalizeArg } from '../module' + +describe('uts-module', () => { + test('normalize args', () => { + expect(normalizeArg(1)).toBe(1) + expect(normalizeArg('hello')).toBe('hello') + expect(normalizeArg(true)).toBe(true) + expect(normalizeArg({ callback: () => {} })).toEqual({ + callback: { $$type: 'function', value: 1 }, + }) + expect( + normalizeArg({ success: () => {}, fail: () => {}, complete: () => {} }) + ).toEqual({ + success: { $$type: 'function', value: 2 }, + fail: { $$type: 'function', value: 3 }, + complete: { $$type: 'function', value: 4 }, + }) + expect( + normalizeArg({ + user: { + name: 'test', + age: 10, + callback() {}, + }, + success() {}, + }) + ).toEqual({ + user: { + name: 'test', + age: 10, + callback: { + $$type: 'function', + value: 5, + }, + }, + success: { + $$type: 'function', + value: 6, + }, + }) + }) +}) diff --git a/packages/uni-uts-vite/build.json b/packages/uni-uts-vite/build.json new file mode 100644 index 0000000000000000000000000000000000000000..2c89cf8cd38f19b8c52320a2abee2fb39df1ea64 --- /dev/null +++ b/packages/uni-uts-vite/build.json @@ -0,0 +1,11 @@ +[ + { + "input": { + "module.ts": "lib/module.js" + }, + "treeshake": false, + "compilerOptions": { + "module": "ESNext" + } + } +] diff --git a/packages/uni-uts-vite/lib/module.js b/packages/uni-uts-vite/lib/module.js new file mode 100644 index 0000000000000000000000000000000000000000..20f458912ce2d1de8c624eedd3e76f089abb9ef6 --- /dev/null +++ b/packages/uni-uts-vite/lib/module.js @@ -0,0 +1,42 @@ +// @ts-expect-error +const proxy = uni.requireNativePlugin('proxy-module') +// @ts-expect-error +const moduleName = __MODULE_NAME__ +// @ts-expect-error +const moduleDefine = __MODULE_DEFINE__ +var module = initModule(moduleDefine) +let callbackId = 0 +const objectToString = Object.prototype.toString +const toTypeString = (value) => objectToString.call(value) +const isPlainObject = (val) => toTypeString(val) === '[object Object]' +function normalizeArg(arg) { + if (typeof arg === 'function') { + return { + type: 'function', + value: callbackId++, + } + } else if (isPlainObject(arg)) { + Object.keys(arg).forEach((name) => { + arg[name] = normalizeArg(arg[name]) + }) + } + return arg +} +function moduleGetter(module, method) { + return (...args) => { + const params = args.map((arg) => normalizeArg(arg)) + proxy.invoke({ module, method, params }, () => {}) + } +} +function initModule(moduleDefine) { + const moduleProxy = {} + for (const methodName in moduleDefine) { + Object.defineProperty(moduleProxy, methodName, { + enumerable: true, + configurable: true, + get: () => moduleGetter(moduleName, methodName), + }) + } +} + +export { module as default, normalizeArg } diff --git a/packages/uni-uts-vite/module.ts b/packages/uni-uts-vite/module.ts new file mode 100644 index 0000000000000000000000000000000000000000..2aa2536686fa2692a8a2718c3dbc1b0447421d9c --- /dev/null +++ b/packages/uni-uts-vite/module.ts @@ -0,0 +1,50 @@ +declare const uni: { + requireNativePlugin(name: string): { invoke: Function } +} + +const moduleName = '__MODULE_NAME__' + +const moduleDefine = '__MODULE_DEFINE__' + +export default initModule(moduleDefine as unknown as Record) + +let callbackId = 1 + +const objectToString = Object.prototype.toString +const toTypeString = (value: unknown): string => objectToString.call(value) + +const isPlainObject = (val: unknown): val is object => + toTypeString(val) === '[object Object]' + +export function normalizeArg(arg: unknown) { + if (typeof arg === 'function') { + return { + $$type: 'function', + value: callbackId++, + } + } else if (isPlainObject(arg)) { + Object.keys(arg).forEach((name) => { + ;(arg as any)[name] = normalizeArg((arg as any)[name]) + }) + } + return arg +} + +function moduleGetter(proxy: any, module: string, method: string) { + return (...args: unknown[]) => { + const params = args.map((arg) => normalizeArg(arg)) + proxy.invoke({ module, method, params }, () => {}) + } +} + +function initModule(moduleDefine: Record) { + const proxy = uni.requireNativePlugin('proxy-module') + const moduleProxy = {} + for (const methodName in moduleDefine) { + Object.defineProperty(moduleProxy, methodName, { + enumerable: true, + configurable: true, + get: () => moduleGetter(proxy, moduleName, methodName), + }) + } +} diff --git a/packages/uni-uts-vite/src/plugins/uts.ts b/packages/uni-uts-vite/src/plugins/uts.ts index 648dc9232d8bf52ee1445c1365db1fb5cfa33718..f5f353b0cbf0b0409204fd4b22191fdbaa2f348c 100644 --- a/packages/uni-uts-vite/src/plugins/uts.ts +++ b/packages/uni-uts-vite/src/plugins/uts.ts @@ -25,8 +25,8 @@ export function uniUtsPlugin(): Plugin { if (pkg.uni_modules?.type !== 'uts') { return } - // TODO 根据平台加载 - return path.join(id, 'app-android/index.uts') + // 加载接口类 + return path.join(id, pkg.main || 'interface.uts') }, transform(code, id, opts) { if (opts && opts.ssr) { diff --git a/packages/uts/src/api.ts b/packages/uts/src/api.ts index 27c9833f15fae09aaaa9b766ad3e4b9db1fa7863..6195e16a51faa37721fc4f753dc5bf3fb0cb5120 100644 --- a/packages/uts/src/api.ts +++ b/packages/uts/src/api.ts @@ -1,5 +1,5 @@ import { resolve } from 'path' -import type { UtsOptions, UtsResult } from './types' +import type { UtsOptions, UtsParseOptions, UtsResult } from './types' import { normalizePath } from './utils' const bindingsOverride = process.env['UTS_BINARY_PATH'] @@ -36,6 +36,12 @@ function resolveOptions(options: UtsOptions) { return options } +export function parse(source: string, options: UtsParseOptions = {}) { + return bindings + .parse(source, toBuffer(options)) + .then((res: string) => JSON.parse(res)) +} + export function toKotlin(options: UtsOptions): Promise { const kotlinOptions = resolveOptions(options) if (!kotlinOptions) { diff --git a/packages/uts/src/index.ts b/packages/uts/src/index.ts index 69989176ff154c171403faeffe1738fde73350fc..85af8b318a98b7a34acd19a8f281a512792c89ad 100644 --- a/packages/uts/src/index.ts +++ b/packages/uts/src/index.ts @@ -343,6 +343,8 @@ function buildFile( }) } +export { parse } from './api' + export function runDev(target: UtsTarget, opts: ToOptions) { opts = parseOptions('dev', target, opts) !opts.silent && printStartup(target, 'development') diff --git a/rollup.config.js b/rollup.config.js index a195328da01d17456f772b43ab49a6e16a0f773c..a67b420e573b88be28764242b65e5230fed1819b 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -90,6 +90,7 @@ function createConfig(entryFile, output, buildOption) { declaration: shouldEmitDeclarations, declarationMap: false, skipLibCheck: true, + ...(buildOption.compilerOptions || {}), }, exclude: ['**/__tests__', 'test-dts'], }, diff --git a/scripts/build.js b/scripts/build.js index 7f6efc8fb28d4bd072764bbf895c0d2891150d11..d1a415e3c9593ca28a16025a123c9fcd98baf9e4 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -166,7 +166,7 @@ async function build(target) { ], { stdio: 'inherit' } ) - if (types) { + if (types && target !== 'uni-uts-vite') { await extract(target) } } diff --git a/scripts/test.js b/scripts/test.js index ae762c650b292e1c239e0c7e5e8d4ce42285ddf3..2197049c7156b65570e8a7e448e95cfb3602731a 100644 --- a/scripts/test.js +++ b/scripts/test.js @@ -1,6 +1,19 @@ +const fs = require('fs') const path = require('path') -const { runBuild, UtsTarget } = require('../packages/uts/dist') +const { parse, runBuild, UtsTarget } = require('../packages/uts/dist') const projectDir = path.resolve(__dirname, '../packages/playground/uts') + +const start = Date.now() +parse( + fs.readFileSync( + path.resolve(projectDir, 'uni_modules/test-uniplugin/interface.uts'), + 'utf8' + ) +).then((res) => { + console.log('parse: ' + (Date.now() - start) + 'ms') + console.log(JSON.stringify(res)) +}) + // uts runBuild(UtsTarget.KOTLIN, { silent: false,