diff --git a/.eslintignore b/.eslintignore
index c51ed8fb317..b2cf133a583 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -40,4 +40,5 @@ packages/uni-cli-shared/components/ad-fullscreen-video.vue
packages/uni-cli-shared/components/ad-interactive.vue
packages/uni-cli-shared/components/ad-interstitial.vue
packages/uni-cli-shared/components/ad-rewarded-video.vue
-packages/uni-cli-shared/lib/uni_modules/uni_modules.js
+packages/uni-cli-shared/lib/uni_modules/uni_modules.js
+packages/uni-cli-shared/lib/uts/uts.js
diff --git a/packages/uni-app/dist/index.d.ts b/packages/uni-app/dist/index.d.ts
index e127a807942..e03d6e50b4e 100644
--- a/packages/uni-app/dist/index.d.ts
+++ b/packages/uni-app/dist/index.d.ts
@@ -3,6 +3,7 @@
///
///
import { ComponentInternalInstance } from '@vue/composition-api';
+export { initUtsProxyClass, initUtsProxyFunction, initUtsIndexClassName, initUtsClassName, initUtsPackageName, } from './uts';
export declare const onShow: (callback: ((options?: App.LaunchShowOption) => void) | (() => void), target?: ComponentInternalInstance | null) => Function;
export declare const onHide: (callback: (() => void) | (() => void), target?: ComponentInternalInstance | null) => Function;
export declare const onLaunch: (callback: (options?: App.LaunchShowOption) => void, target?: ComponentInternalInstance | null) => Function;
diff --git a/packages/uni-app/dist/index.js b/packages/uni-app/dist/index.js
index c55ca2c2db3..faeef47733c 100644
--- a/packages/uni-app/dist/index.js
+++ b/packages/uni-app/dist/index.js
@@ -1,8 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-exports.onNavigationBarSearchInputClicked = exports.onNavigationBarSearchInputConfirmed = exports.onNavigationBarSearchInputChanged = exports.onBackPress = exports.onNavigationBarButtonTap = exports.onTabItemTap = exports.onResize = exports.onPageScroll = exports.onAddToFavorites = exports.onShareTimeline = exports.onShareAppMessage = exports.onReachBottom = exports.onPullDownRefresh = exports.onUnload = exports.onReady = exports.onLoad = exports.onInit = exports.onUniNViewMessage = exports.onThemeChange = exports.onUnhandledRejection = exports.onPageNotFound = exports.onError = exports.onLaunch = exports.onHide = exports.onShow = void 0;
+exports.onNavigationBarSearchInputClicked = exports.onNavigationBarSearchInputConfirmed = exports.onNavigationBarSearchInputChanged = exports.onBackPress = exports.onNavigationBarButtonTap = exports.onTabItemTap = exports.onResize = exports.onPageScroll = exports.onAddToFavorites = exports.onShareTimeline = exports.onShareAppMessage = exports.onReachBottom = exports.onPullDownRefresh = exports.onUnload = exports.onReady = exports.onLoad = exports.onInit = exports.onUniNViewMessage = exports.onThemeChange = exports.onUnhandledRejection = exports.onPageNotFound = exports.onError = exports.onLaunch = exports.onHide = exports.onShow = exports.initUtsPackageName = exports.initUtsClassName = exports.initUtsIndexClassName = exports.initUtsProxyFunction = exports.initUtsProxyClass = void 0;
var composition_api_1 = require("@vue/composition-api");
var mp = require("./mp");
+var uts_1 = require("./uts");
+Object.defineProperty(exports, "initUtsProxyClass", { enumerable: true, get: function () { return uts_1.initUtsProxyClass; } });
+Object.defineProperty(exports, "initUtsProxyFunction", { enumerable: true, get: function () { return uts_1.initUtsProxyFunction; } });
+Object.defineProperty(exports, "initUtsIndexClassName", { enumerable: true, get: function () { return uts_1.initUtsIndexClassName; } });
+Object.defineProperty(exports, "initUtsClassName", { enumerable: true, get: function () { return uts_1.initUtsClassName; } });
+Object.defineProperty(exports, "initUtsPackageName", { enumerable: true, get: function () { return uts_1.initUtsPackageName; } });
var lifecycles = [];
var createLifeCycle = function (lifecycle) {
lifecycles.push(lifecycle);
diff --git a/packages/uni-app/dist/utils.d.ts b/packages/uni-app/dist/utils.d.ts
new file mode 100644
index 00000000000..64a8ce64669
--- /dev/null
+++ b/packages/uni-app/dist/utils.d.ts
@@ -0,0 +1,9 @@
+export declare const extend: {
+ (target: T, source: U): T & U;
+ (target: T_1, source1: U_1, source2: V): T_1 & U_1 & V;
+ (target: T_2, source1: U_2, source2: V_1, source3: W): T_2 & U_2 & V_1 & W;
+ (target: object, ...sources: any[]): any;
+};
+export declare const hasOwn: (val: object, key: string | symbol) => key is never;
+export declare const isPlainObject: (val: unknown) => val is object;
+export declare const capitalize: (str: string) => string;
diff --git a/packages/uni-app/dist/utils.js b/packages/uni-app/dist/utils.js
new file mode 100644
index 00000000000..bb29e29c985
--- /dev/null
+++ b/packages/uni-app/dist/utils.js
@@ -0,0 +1,23 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.capitalize = exports.isPlainObject = exports.hasOwn = exports.extend = void 0;
+exports.extend = Object.assign;
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+var hasOwn = function (val, key) { return hasOwnProperty.call(val, key); };
+exports.hasOwn = hasOwn;
+var objectToString = Object.prototype.toString;
+var toTypeString = function (value) {
+ return objectToString.call(value);
+};
+var isPlainObject = function (val) {
+ return toTypeString(val) === '[object Object]';
+};
+exports.isPlainObject = isPlainObject;
+var cacheStringFunction = function (fn) {
+ var cache = Object.create(null);
+ return (function (str) {
+ var hit = cache[str];
+ return hit || (cache[str] = fn(str));
+ });
+};
+exports.capitalize = cacheStringFunction(function (str) { return str.charAt(0).toUpperCase() + str.slice(1); });
diff --git a/packages/uni-app/dist/uts.d.ts b/packages/uni-app/dist/uts.d.ts
new file mode 100644
index 00000000000..b068b9fdee6
--- /dev/null
+++ b/packages/uni-app/dist/uts.d.ts
@@ -0,0 +1,42 @@
+export declare function normalizeArg(arg: unknown): unknown;
+interface Parameter {
+ name: string;
+ type: string;
+}
+interface ProxyFunctionOptions {
+ main?: boolean;
+ package: string;
+ class: string;
+ name: string;
+ method?: string;
+ companion?: boolean;
+ params: Parameter[];
+}
+interface ProxyClassOptions {
+ package: string;
+ class: string;
+ constructor: {
+ params: Parameter[];
+ };
+ props: string[];
+ staticProps: string[];
+ methods: {
+ [name: string]: {
+ async?: boolean;
+ params: Parameter[];
+ };
+ };
+ staticMethods: {
+ [name: string]: {
+ async?: boolean;
+ params: Parameter[];
+ };
+ };
+}
+declare function initUtsStaticMethod(async: boolean, opts: ProxyFunctionOptions): (...args: unknown[]) => unknown;
+export declare const initUtsProxyFunction: typeof initUtsStaticMethod;
+export declare function initUtsProxyClass({ package: pkg, class: cls, constructor: { params: constructorParams }, methods, props, staticProps, staticMethods, }: ProxyClassOptions): any;
+export declare function initUtsPackageName(name: string, is_uni_modules: boolean): string;
+export declare function initUtsIndexClassName(moduleName: string, is_uni_modules: boolean): string;
+export declare function initUtsClassName(moduleName: string, className: string, is_uni_modules: boolean): string;
+export {};
diff --git a/packages/uni-app/dist/uts.js b/packages/uni-app/dist/uts.js
new file mode 100644
index 00000000000..601e8e5d8e3
--- /dev/null
+++ b/packages/uni-app/dist/uts.js
@@ -0,0 +1,186 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.initUtsClassName = exports.initUtsIndexClassName = exports.initUtsPackageName = exports.initUtsProxyClass = exports.initUtsProxyFunction = exports.normalizeArg = void 0;
+var utils_1 = require("./utils");
+var callbackId = 1;
+var proxy;
+var callbacks = {};
+function normalizeArg(arg) {
+ if (typeof arg === 'function') {
+ var id = callbackId++;
+ callbacks[id] = arg;
+ return id;
+ }
+ else if ((0, utils_1.isPlainObject)(arg)) {
+ Object.keys(arg).forEach(function (name) {
+ ;
+ arg[name] = normalizeArg(arg[name]);
+ });
+ }
+ return arg;
+}
+exports.normalizeArg = normalizeArg;
+function initUtsInstanceMethod(async, opts, instanceId) {
+ return initProxyFunction(async, opts, instanceId);
+}
+function getProxy() {
+ if (!proxy) {
+ proxy = uni.requireNativePlugin('UTS-Proxy');
+ }
+ return proxy;
+}
+function resolveSyncResult(res) {
+ if (res.errMsg) {
+ throw new Error(res.errMsg);
+ }
+ return res.params;
+}
+function invokePropGetter(args) {
+ return resolveSyncResult(getProxy().invokeSync(args, function () { }));
+}
+function initProxyFunction(async, _a, instanceId) {
+ var pkg = _a.package, cls = _a.class, propOrMethod = _a.name, method = _a.method, companion = _a.companion, methodParams = _a.params;
+ var invokeCallback = function (_a) {
+ var id = _a.id, name = _a.name, params = _a.params, keepAlive = _a.keepAlive;
+ var callback = callbacks[id];
+ if (callback) {
+ callback.apply(void 0, params);
+ if (!keepAlive) {
+ delete callbacks[id];
+ }
+ }
+ else {
+ console.error("".concat(pkg).concat(cls, ".").concat(propOrMethod, " ").concat(name, " is not found"));
+ }
+ };
+ var baseArgs = instanceId
+ ? { id: instanceId, name: propOrMethod, method: methodParams }
+ : {
+ package: pkg,
+ class: cls,
+ name: method || propOrMethod,
+ companion: companion,
+ method: methodParams,
+ };
+ return function () {
+ var args = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ args[_i] = arguments[_i];
+ }
+ var invokeArgs = (0, utils_1.extend)({}, baseArgs, {
+ params: args.map(function (arg) { return normalizeArg(arg); }),
+ });
+ if (async) {
+ return new Promise(function (resolve, reject) {
+ getProxy().invokeAsync(invokeArgs, function (res) {
+ if (res.type !== 'return') {
+ invokeCallback(res);
+ }
+ else {
+ if (res.errMsg) {
+ reject(res.errMsg);
+ }
+ else {
+ resolve(res.params);
+ }
+ }
+ });
+ });
+ }
+ return resolveSyncResult(getProxy().invokeSync(invokeArgs, invokeCallback));
+ };
+}
+function initUtsStaticMethod(async, opts) {
+ if (opts.main && !opts.method) {
+ if (typeof plus !== 'undefined' && plus.os.name === 'iOS') {
+ opts.method = 's_' + opts.name;
+ }
+ }
+ return initProxyFunction(async, opts, 0);
+}
+exports.initUtsProxyFunction = initUtsStaticMethod;
+function initUtsProxyClass(_a) {
+ var pkg = _a.package, cls = _a.class, constructorParams = _a.constructor.params, methods = _a.methods, props = _a.props, staticProps = _a.staticProps, staticMethods = _a.staticMethods;
+ var baseOptions = {
+ package: pkg,
+ class: cls,
+ };
+ var ProxyClass = (function () {
+ function UtsClass() {
+ var params = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ params[_i] = arguments[_i];
+ }
+ var target = {};
+ var instanceId = initProxyFunction(false, (0, utils_1.extend)({ name: 'constructor', params: constructorParams }, baseOptions), 0).apply(null, params);
+ if (!instanceId) {
+ throw new Error("new ".concat(cls, " is failed"));
+ }
+ return new Proxy(this, {
+ get: function (_, name) {
+ if (!target[name]) {
+ if ((0, utils_1.hasOwn)(methods, name)) {
+ var _a = methods[name], async = _a.async, params_1 = _a.params;
+ target[name] = initUtsInstanceMethod(!!async, (0, utils_1.extend)({
+ name: name,
+ params: params_1,
+ }, baseOptions), instanceId);
+ }
+ else if (props.includes(name)) {
+ return invokePropGetter({ id: instanceId, name: name });
+ }
+ }
+ return target[name];
+ },
+ });
+ }
+ return UtsClass;
+ }());
+ var staticMethodCache = {};
+ return new Proxy(ProxyClass, {
+ get: function (target, name, receiver) {
+ if ((0, utils_1.hasOwn)(staticMethods, name)) {
+ if (!staticMethodCache[name]) {
+ var _a = staticMethods[name], async = _a.async, params = _a.params;
+ staticMethodCache[name] = initUtsStaticMethod(!!async, (0, utils_1.extend)({ name: name, companion: true, params: params }, baseOptions));
+ }
+ return staticMethodCache[name];
+ }
+ if (staticProps.includes(name)) {
+ return invokePropGetter((0, utils_1.extend)({ name: name, companion: true }, baseOptions));
+ }
+ return Reflect.get(target, name, receiver);
+ },
+ });
+}
+exports.initUtsProxyClass = initUtsProxyClass;
+function initUtsPackageName(name, is_uni_modules) {
+ if (typeof plus !== 'undefined' && plus.os.name === 'Android') {
+ return 'uts.sdk.' + (is_uni_modules ? 'modules.' : '') + name;
+ }
+ return '';
+}
+exports.initUtsPackageName = initUtsPackageName;
+function initUtsIndexClassName(moduleName, is_uni_modules) {
+ if (typeof plus === 'undefined') {
+ return '';
+ }
+ return initUtsClassName(moduleName, plus.os.name === 'iOS' ? 'IndexSwift' : 'IndexKt', is_uni_modules);
+}
+exports.initUtsIndexClassName = initUtsIndexClassName;
+function initUtsClassName(moduleName, className, is_uni_modules) {
+ if (typeof plus === 'undefined') {
+ return '';
+ }
+ if (plus.os.name === 'Android') {
+ return className;
+ }
+ if (plus.os.name === 'iOS') {
+ return ('UTSSDK' +
+ (is_uni_modules ? 'Modules' : '') +
+ (0, utils_1.capitalize)(moduleName) +
+ (0, utils_1.capitalize)(className));
+ }
+ return '';
+}
+exports.initUtsClassName = initUtsClassName;
diff --git a/packages/uni-app/src/index.ts b/packages/uni-app/src/index.ts
index c9728175a83..bf51a47accf 100644
--- a/packages/uni-app/src/index.ts
+++ b/packages/uni-app/src/index.ts
@@ -1,6 +1,14 @@
///
import { createLifeCycle as createLifeCycleBase, ComponentInternalInstance } from '@vue/composition-api'
import * as mp from './mp'
+
+export {
+ initUtsProxyClass,
+ initUtsProxyFunction,
+ initUtsIndexClassName,
+ initUtsClassName,
+ initUtsPackageName,
+} from './uts'
const lifecycles: string[] = []
diff --git a/packages/uni-app/src/utils.ts b/packages/uni-app/src/utils.ts
new file mode 100644
index 00000000000..ba2c1eb8d21
--- /dev/null
+++ b/packages/uni-app/src/utils.ts
@@ -0,0 +1,26 @@
+export const extend = Object.assign
+
+const hasOwnProperty = Object.prototype.hasOwnProperty
+export const hasOwn = (
+ val: object,
+ key: string | symbol
+): key is keyof typeof val => hasOwnProperty.call(val, key)
+
+const objectToString = Object.prototype.toString
+const toTypeString = (value: unknown): string =>
+ objectToString.call(value)
+
+export const isPlainObject = (val: unknown): val is object =>
+ toTypeString(val) === '[object Object]'
+
+const cacheStringFunction = string>(fn: T): T => {
+ const cache: Record = Object.create(null)
+ return ((str: string) => {
+ const hit = cache[str]
+ return hit || (cache[str] = fn(str))
+ }) as T
+}
+
+export const capitalize = cacheStringFunction(
+ (str: string) => str.charAt(0).toUpperCase() + str.slice(1)
+)
diff --git a/packages/uni-app/src/uts.ts b/packages/uni-app/src/uts.ts
new file mode 100644
index 00000000000..daa9c4cdaed
--- /dev/null
+++ b/packages/uni-app/src/uts.ts
@@ -0,0 +1,351 @@
+import { isPlainObject, hasOwn, extend, capitalize } from './utils'
+declare const uni: any
+declare const plus: any
+let callbackId = 1
+let proxy: any
+const callbacks: Record = {}
+export function normalizeArg(arg: unknown) {
+ if (typeof arg === 'function') {
+ const id = callbackId++
+ callbacks[id] = arg
+ return id
+ } else if (isPlainObject(arg)) {
+ Object.keys(arg).forEach((name) => {
+ ; (arg as any)[name] = normalizeArg((arg as any)[name])
+ })
+ }
+ return arg
+}
+
+function initUtsInstanceMethod(
+ async: boolean,
+ opts: ProxyFunctionOptions,
+ instanceId: number
+) {
+ return initProxyFunction(async, opts, instanceId)
+}
+
+interface Parameter {
+ name: string
+ type: string
+}
+interface ProxyFunctionOptions {
+ /**
+ * 是否是入口类
+ */
+ main?: boolean
+ /**
+ * 包名
+ */
+ package: string
+ /**
+ * 类名
+ */
+ class: string
+ /**
+ * 属性名或方法名
+ */
+ name: string
+ /**
+ * 方法名 指定的方法名(用于 IndexSwift 静态方法,自动补充前缀 s_)
+ */
+ method?: string
+ /**
+ * 是否伴生对象
+ */
+ companion?: boolean
+ /**
+ * 方法参数列表
+ */
+ params: Parameter[]
+}
+
+interface ProxyClassOptions {
+ package: string
+ class: string
+ constructor: {
+ params: Parameter[]
+ }
+ props: string[]
+ staticProps: string[]
+ methods: {
+ [name: string]: {
+ async?: boolean
+ params: Parameter[]
+ }
+ }
+ staticMethods: {
+ [name: string]: {
+ async?: boolean
+ params: Parameter[]
+ }
+ }
+}
+
+interface InvokeInstanceArgs {
+ id: number
+ name: string
+ params?: unknown[]
+ method?: Parameter[]
+}
+interface InvokeStaticArgs {
+ /**
+ * 包名
+ */
+ package: string
+ /**
+ * 类名
+ */
+ class: string
+ /**
+ * 属性名或方法名
+ */
+ name: string
+ /**
+ * 执行方法时的真实参数列表
+ */
+ params?: unknown[]
+ /**
+ * 方法定义的参数列表
+ */
+ method?: Parameter[]
+ /**
+ * 是否是伴生对象
+ */
+ companion?: boolean
+}
+
+type InvokeArgs = InvokeInstanceArgs | InvokeStaticArgs
+
+interface InvokeCallbackReturnRes {
+ type: 'return'
+ params?: unknown[]
+ errMsg?: string
+}
+interface InvokeCallbackParamsRes {
+ type: 'params'
+ id: number
+ name: string
+ params: unknown[]
+ keepAlive?: boolean
+}
+interface InvokeSyncRes {
+ type: 'return'
+ errMsg?: string
+ params: unknown
+}
+type InvokeSyncCallback = (res: InvokeCallbackParamsRes) => void
+type InvokeAsyncCallback = (
+ res: InvokeCallbackReturnRes | InvokeCallbackParamsRes
+) => void
+function getProxy(): {
+ invokeSync: (args: InvokeArgs, callback: InvokeSyncCallback) => InvokeSyncRes
+ invokeAsync: (args: InvokeArgs, callback: InvokeAsyncCallback) => void
+} {
+ if (!proxy) {
+ proxy = uni.requireNativePlugin('UTS-Proxy') as any
+ }
+ return proxy
+}
+
+function resolveSyncResult(res: InvokeSyncRes) {
+ if (res.errMsg) {
+ throw new Error(res.errMsg)
+ }
+ return res.params
+}
+
+function invokePropGetter(args: InvokeArgs) {
+ return resolveSyncResult(getProxy().invokeSync(args, () => { }))
+}
+
+function initProxyFunction(
+ async: boolean,
+ {
+ package: pkg,
+ class: cls,
+ name: propOrMethod,
+ method,
+ companion,
+ params: methodParams,
+ }: ProxyFunctionOptions,
+ instanceId: number
+) {
+ const invokeCallback = ({
+ id,
+ name,
+ params,
+ keepAlive,
+ }: InvokeCallbackParamsRes) => {
+ const callback = callbacks[id!]
+ if (callback) {
+ callback(...params)
+ if (!keepAlive) {
+ delete callbacks[id]
+ }
+ } else {
+ console.error(`${pkg}${cls}.${propOrMethod} ${name} is not found`)
+ }
+ }
+ const baseArgs: InvokeArgs = instanceId
+ ? { id: instanceId, name: propOrMethod, method: methodParams }
+ : {
+ package: pkg,
+ class: cls,
+ name: method || propOrMethod,
+ companion,
+ method: methodParams,
+ }
+ return (...args: unknown[]) => {
+ const invokeArgs = extend({}, baseArgs, {
+ params: args.map((arg) => normalizeArg(arg)),
+ })
+ if (async) {
+ return new Promise((resolve, reject) => {
+ getProxy().invokeAsync(invokeArgs, (res) => {
+ if (res.type !== 'return') {
+ invokeCallback(res)
+ } else {
+ if (res.errMsg) {
+ reject(res.errMsg)
+ } else {
+ resolve(res.params)
+ }
+ }
+ })
+ })
+ }
+ return resolveSyncResult(getProxy().invokeSync(invokeArgs, invokeCallback))
+ }
+}
+
+function initUtsStaticMethod(async: boolean, opts: ProxyFunctionOptions) {
+ if (opts.main && !opts.method) {
+ if (typeof plus !== 'undefined' && plus.os.name === 'iOS') {
+ opts.method = 's_' + opts.name
+ }
+ }
+ return initProxyFunction(async, opts, 0)
+}
+
+export const initUtsProxyFunction = initUtsStaticMethod
+
+export function initUtsProxyClass({
+ package: pkg,
+ class: cls,
+ constructor: { params: constructorParams },
+ methods,
+ props,
+ staticProps,
+ staticMethods,
+}: ProxyClassOptions): any {
+ const baseOptions = {
+ package: pkg,
+ class: cls,
+ }
+ const ProxyClass = class UtsClass {
+ constructor(...params: unknown[]) {
+ const target: Record = {}
+ // 初始化实例 ID
+ const instanceId = initProxyFunction(
+ false,
+ extend({ name: 'constructor', params: constructorParams }, baseOptions),
+ 0
+ ).apply(null, params) as number
+ if (!instanceId) {
+ throw new Error(`new ${cls} is failed`)
+ }
+ return new Proxy(this, {
+ get(_, name) {
+ if (!target[name as string]) {
+ //实例方法
+ if (hasOwn(methods, name)) {
+ const { async, params } = methods[name]
+ target[name] = initUtsInstanceMethod(
+ !!async,
+ extend(
+ {
+ name,
+ params,
+ },
+ baseOptions
+ ),
+ instanceId
+ )
+ } else if (props.includes(name as string)) {
+ // 实例属性
+ return invokePropGetter({ id: instanceId, name: name as string })
+ }
+ }
+ return target[name as string]
+ },
+ })
+ }
+ }
+ const staticMethodCache: Record = {}
+ return new Proxy(ProxyClass, {
+ get(target, name, receiver) {
+ if (hasOwn(staticMethods, name)) {
+ if (!staticMethodCache[name as string]) {
+ const { async, params } = staticMethods[name]
+ // 静态方法
+ staticMethodCache[name] = initUtsStaticMethod(
+ !!async,
+ extend({ name, companion: true, params }, baseOptions)
+ )
+ }
+ return staticMethodCache[name]
+ }
+ if (staticProps.includes(name as string)) {
+ // 静态属性
+ return invokePropGetter(
+ extend({ name: name as string, companion: true }, baseOptions)
+ )
+ }
+ return Reflect.get(target, name, receiver)
+ },
+ })
+}
+
+export function initUtsPackageName(name: string, is_uni_modules: boolean) {
+ if (typeof plus !== 'undefined' && plus.os.name === 'Android') {
+ return 'uts.sdk.' + (is_uni_modules ? 'modules.' : '') + name
+ }
+ return ''
+}
+
+export function initUtsIndexClassName(
+ moduleName: string,
+ is_uni_modules: boolean
+) {
+ if (typeof plus === 'undefined') {
+ return ''
+ }
+ return initUtsClassName(
+ moduleName,
+ plus.os.name === 'iOS' ? 'IndexSwift' : 'IndexKt',
+ is_uni_modules
+ )
+}
+
+export function initUtsClassName(
+ moduleName: string,
+ className: string,
+ is_uni_modules: boolean
+) {
+ if (typeof plus === 'undefined') {
+ return ''
+ }
+ if (plus.os.name === 'Android') {
+ return className
+ }
+ if (plus.os.name === 'iOS') {
+ return (
+ 'UTSSDK' +
+ (is_uni_modules ? 'Modules' : '') +
+ capitalize(moduleName) +
+ capitalize(className)
+ )
+ }
+ return ''
+}
diff --git a/packages/uni-cli-shared/lib/index.js b/packages/uni-cli-shared/lib/index.js
index 287524be42e..6d5b53f7102 100644
--- a/packages/uni-cli-shared/lib/index.js
+++ b/packages/uni-cli-shared/lib/index.js
@@ -63,7 +63,10 @@ const {
getPlatformUniCloud
} = require('./platform')
+const uts = require('./uts')
+
module.exports = {
+ uts,
md5,
tags,
hasOwn,
diff --git a/packages/uni-cli-shared/lib/uni_modules/uni_modules.js b/packages/uni-cli-shared/lib/uni_modules/uni_modules.js
index e1bea8b6f80..644dcef9002 100644
--- a/packages/uni-cli-shared/lib/uni_modules/uni_modules.js
+++ b/packages/uni-cli-shared/lib/uni_modules/uni_modules.js
@@ -25,10 +25,7 @@ function parseUniExtApis(vite = true) {
}
const exports = (_b = (_a = JSON.parse(fs_extra_1.default.readFileSync(pkgPath, 'utf8'))) === null || _a === void 0 ? void 0 : _a.uni_modules) === null || _b === void 0 ? void 0 : _b['uni-ext-api'];
if (exports) {
- Object.assign(injects, parseInjects(vite, process.env.UNI_PLATFORM === 'h5' ? 'web' : process.env.UNI_PLATFORM, `@/uni_modules/${uniModuleDir}` +
- (vite || !process.env.UNI_UTS_PLATFORM
- ? ''
- : `/utssdk/${process.env.UNI_UTS_PLATFORM}/index`), exports));
+ Object.assign(injects, parseInjects(vite, process.env.UNI_PLATFORM === 'h5' ? 'web' : process.env.UNI_PLATFORM, `@/uni_modules/${uniModuleDir}`, exports));
}
});
return injects;
diff --git a/packages/uni-cli-shared/lib/uts/hbx.js b/packages/uni-cli-shared/lib/uts/hbx.js
new file mode 100644
index 00000000000..29030fd993b
--- /dev/null
+++ b/packages/uni-cli-shared/lib/uts/hbx.js
@@ -0,0 +1,8 @@
+const {
+ isInHBuilderX
+} = require('../util')
+module.exports = {
+ isInHBuilderX () {
+ return isInHBuilderX
+ }
+}
diff --git a/packages/uni-cli-shared/lib/uts/index.js b/packages/uni-cli-shared/lib/uts/index.js
new file mode 100644
index 00000000000..640116a145b
--- /dev/null
+++ b/packages/uni-cli-shared/lib/uts/index.js
@@ -0,0 +1,5 @@
+const UTSResolverPlugin = require('./resolver')
+const uts = require('./uts')
+module.exports = Object.assign({
+ UTSResolverPlugin
+}, uts)
diff --git a/packages/uni-cli-shared/lib/uts/resolver.js b/packages/uni-cli-shared/lib/uts/resolver.js
new file mode 100644
index 00000000000..a203797f4a3
--- /dev/null
+++ b/packages/uni-cli-shared/lib/uts/resolver.js
@@ -0,0 +1,29 @@
+const path = require('path')
+const {
+ resolveUtsModule
+} = require('./uts')
+class UTSResolverPlugin {
+ apply (resolver) {
+ resolver.hooks.resolve.tapAsync('UTSResolverPlugin', (request, resolveContext, callback) => {
+ let utsModulePath = ''
+ if (request.request.startsWith('@/uni_modules/')) {
+ utsModulePath = path.resolve(process.env.UNI_INPUT_DIR, request.request.replace('@/', ''))
+ } else if (request.request.includes('uni_modules')) {
+ utsModulePath = path.resolve(request.path, request.request)
+ }
+ if (utsModulePath) {
+ const utsModule = resolveUtsModule(utsModulePath)
+ if (utsModule) {
+ if (process.env.UNI_PLATFORM === 'app-plus') {
+ request.request = utsModule + '/package.json?uts-proxy'
+ } else {
+ request.request = utsModule
+ }
+ }
+ }
+ callback()
+ })
+ }
+}
+
+module.exports = UTSResolverPlugin
diff --git a/packages/uni-cli-shared/lib/uts/utils.js b/packages/uni-cli-shared/lib/uts/utils.js
new file mode 100644
index 00000000000..25e08eb9e71
--- /dev/null
+++ b/packages/uni-cli-shared/lib/uts/utils.js
@@ -0,0 +1,6 @@
+const {
+ normalizePath
+} = require('../util')
+module.exports = {
+ normalizePath
+}
diff --git a/packages/uni-cli-shared/lib/uts/uts-loader.js b/packages/uni-cli-shared/lib/uts/uts-loader.js
new file mode 100644
index 00000000000..4061ca564cb
--- /dev/null
+++ b/packages/uni-cli-shared/lib/uts/uts-loader.js
@@ -0,0 +1,19 @@
+const path = require('path')
+const {
+ resolveUTSCompiler
+} = require('./uts')
+module.exports = function (content) {
+ const callback = this.async()
+ resolveUTSCompiler().compile(path.dirname(this.resourcePath)).then(result => {
+ if (result) {
+ result.deps.forEach((dep) => {
+ this.addDependency(dep)
+ })
+ callback(null, result.code)
+ } else {
+ callback(null, '')
+ }
+ }).catch(err => {
+ callback(err)
+ })
+}
diff --git a/packages/uni-cli-shared/lib/uts/uts.js b/packages/uni-cli-shared/lib/uts/uts.js
new file mode 100644
index 00000000000..9e63999dee7
--- /dev/null
+++ b/packages/uni-cli-shared/lib/uts/uts.js
@@ -0,0 +1,97 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.resolveUTSCompiler = exports.resolveUtsModule = exports.resolveUtsAppModule = void 0;
+const fs_1 = __importDefault(require("fs"));
+const path_1 = __importDefault(require("path"));
+const hbx_1 = require("./hbx");
+const utils_1 = require("./utils");
+/**
+ * 解析 app 平台的 uts 插件,任意平台(android|ios)存在即可
+ * @param id
+ * @param importer
+ * @returns
+ */
+function resolveUtsAppModule(id, importer) {
+ id = path_1.default.resolve(importer, id);
+ if (id.includes('utssdk') || id.includes('uni_modules')) {
+ const parts = (0, utils_1.normalizePath)(id).split('/');
+ const parentDir = parts[parts.length - 2];
+ if (parentDir === 'uni_modules' || parentDir === 'utssdk') {
+ const basedir = parentDir === 'uni_modules' ? 'utssdk' : '';
+ if (fs_1.default.existsSync(path_1.default.resolve(id, basedir, 'index.uts'))) {
+ return id;
+ }
+ const resolvePlatformDir = (p) => {
+ return path_1.default.resolve(id, basedir, p);
+ };
+ const extname = ['.uts'];
+ if (resolveUtsFile(resolvePlatformDir('app-android'), extname)) {
+ return id;
+ }
+ if (resolveUtsFile(resolvePlatformDir('app-ios'), extname)) {
+ return id;
+ }
+ }
+ }
+}
+exports.resolveUtsAppModule = resolveUtsAppModule;
+// 仅限 root/uni_modules/test-plugin | root/utssdk/test-plugin 格式
+function resolveUtsModule(id, importer) {
+ if (process.env.UNI_PLATFORM === 'app' ||
+ process.env.UNI_PLATFORM === 'app-plus') {
+ return resolveUtsAppModule(id, importer);
+ }
+ id = path_1.default.resolve(importer, id);
+ if (id.includes('utssdk') || id.includes('uni_modules')) {
+ const parts = (0, utils_1.normalizePath)(id).split('/');
+ const parentDir = parts[parts.length - 2];
+ if (parentDir === 'uni_modules' || parentDir === 'utssdk') {
+ const basedir = parentDir === 'uni_modules' ? 'utssdk' : '';
+ const resolvePlatformDir = (p) => {
+ return path_1.default.resolve(id, basedir, p);
+ };
+ let index = resolveUtsFile(resolvePlatformDir(process.env.UNI_UTS_PLATFORM));
+ if (index) {
+ return index;
+ }
+ index = path_1.default.resolve(id, basedir, 'index.uts');
+ if (fs_1.default.existsSync(index)) {
+ return index;
+ }
+ }
+ }
+}
+exports.resolveUtsModule = resolveUtsModule;
+function resolveUtsFile(dir, extensions = ['.uts', '.ts', '.js']) {
+ for (let i = 0; i < extensions.length; i++) {
+ const indexFile = path_1.default.join(dir, 'index' + extensions[i]);
+ if (fs_1.default.existsSync(indexFile)) {
+ return indexFile;
+ }
+ }
+}
+function resolveUTSCompiler() {
+ let compilerPath = '';
+ if ((0, hbx_1.isInHBuilderX)()) {
+ try {
+ compilerPath = require.resolve(path_1.default.resolve(process.env.UNI_HBUILDERX_PLUGINS, 'uniapp-uts-v1'));
+ }
+ catch (e) { }
+ }
+ if (!compilerPath) {
+ try {
+ compilerPath = require.resolve('@dcloudio/uni-uts-v1', {
+ paths: [process.env.UNI_CLI_CONTEXT],
+ });
+ }
+ catch (e) { }
+ }
+ if (!compilerPath) {
+ throw 'uts compiler is not found';
+ }
+ return require(compilerPath);
+}
+exports.resolveUTSCompiler = resolveUTSCompiler;
diff --git a/packages/vue-cli-plugin-uni/lib/app-plus/index.js b/packages/vue-cli-plugin-uni/lib/app-plus/index.js
index 4e0e1843045..e96f1d8f2ce 100644
--- a/packages/vue-cli-plugin-uni/lib/app-plus/index.js
+++ b/packages/vue-cli-plugin-uni/lib/app-plus/index.js
@@ -178,6 +178,13 @@ const v3 = {
'../../packages/webpack-uni-app-loader/page-meta')
}]
},
+ {
+ type: 'javascript/auto',
+ resourceQuery: /uts-proxy/,
+ use: [{
+ loader: require.resolve('@dcloudio/uni-cli-shared/lib/uts/uts-loader.js')
+ }]
+ },
...rules
// v3 暂不支持 cache
// createTemplateCacheLoader(api,
diff --git a/packages/vue-cli-plugin-uni/lib/configure-webpack.js b/packages/vue-cli-plugin-uni/lib/configure-webpack.js
index 0ea376e9d21..a2c171b24fc 100644
--- a/packages/vue-cli-plugin-uni/lib/configure-webpack.js
+++ b/packages/vue-cli-plugin-uni/lib/configure-webpack.js
@@ -24,7 +24,8 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
isInHBuilderX, // 在 HBuilderX 的插件中
hasModule,
jsPreprocessOptions,
- htmlPreprocessOptions
+ htmlPreprocessOptions,
+ uts
} = require('@dcloudio/uni-cli-shared')
const {
@@ -252,13 +253,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
.parseUniExtApis(false)
const keys = Object.keys(uniExtApis)
if (keys.length) {
- if (process.env.UNI_PLATFORM === 'app-plus') {
- keys.forEach(key => {
- console.warn(`[${uniExtApis[key][0].split('/')[2]}]: uts目前仅支持vue3`)
- })
- } else {
- plugins.push(new webpack.ProvidePlugin(uniExtApis))
- }
+ plugins.push(new webpack.ProvidePlugin(uniExtApis))
}
}
if (!process.env.UNI_SUBPACKGE || !process.env.UNI_MP_PLUGIN) {
@@ -281,7 +276,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
plugins.push(new CopyWebpackPlugin(CopyWebpackPluginVersion > 5 ? {
patterns
} : patterns))
- } catch (e) { }
+ } catch (e) {}
}
if (process.UNI_SCRIPT_ENV && Object.keys(process.UNI_SCRIPT_ENV).length) {
@@ -380,7 +375,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
dir: process.env.UNI_INPUT_DIR
}))
}
- } catch (e) { }
+ } catch (e) {}
const resolveLoaderAlias = {}
const modules = ['@vue/cli-plugin-babel', '@vue/cli-service']
@@ -415,6 +410,9 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
modules: [
process.env.UNI_INPUT_DIR,
path.resolve(process.env.UNI_INPUT_DIR, 'node_modules')
+ ],
+ plugins: [
+ new uts.UTSResolverPlugin()
]
},
module: {
@@ -433,4 +431,4 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
watchOptions: require('./util').getWatchOptions()
}, platformWebpackConfig)
}
-}
+}