@dcloudio/uni-cli-shared 3.0.0-5000720260410001 → 3.0.0-5010520260709001
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.ts +1 -3
- package/dist/constants.js +2 -6
- package/dist/deps.d.ts +1 -0
- package/dist/deps.js +22 -13
- package/dist/dom2/fontFamily.d.ts +4 -0
- package/dist/dom2/fontFamily.js +21 -0
- package/dist/dom2/index.d.ts +3 -0
- package/dist/dom2/index.js +3 -0
- package/dist/dom2/rootScrollView.d.ts +47 -0
- package/dist/dom2/rootScrollView.js +283 -0
- package/dist/dom2/sharedData.d.ts +4 -0
- package/dist/dom2/sharedData.js +40 -5
- package/dist/dom2/vue.d.ts +16 -0
- package/dist/dom2/vue.js +37 -0
- package/dist/easycom.d.ts +1 -0
- package/dist/easycom.js +23 -9
- package/dist/env/define.d.ts +0 -1
- package/dist/env/define.js +3 -11
- package/dist/hbx/alias.js +64 -10
- package/dist/hbx/log.js +9 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/json/app/manifest/plus.js +9 -1
- package/dist/json/app/pages/definePage.js +3 -1
- package/dist/json/index.d.ts +1 -1
- package/dist/json/index.js +2 -1
- package/dist/json/mp/index.d.ts +2 -0
- package/dist/json/mp/index.js +23 -1
- package/dist/json/mp/jsonFile.d.ts +3 -2
- package/dist/json/mp/jsonFile.js +83 -13
- package/dist/json/mp/pages.d.ts +1 -0
- package/dist/json/mp/pages.js +6 -2
- package/dist/json/mp/subpackage.d.ts +26 -0
- package/dist/json/mp/subpackage.js +236 -0
- package/dist/json/uni-x/index.d.ts +6 -0
- package/dist/json/uni-x/index.js +54 -1
- package/dist/json/uni-x/manifest.d.ts +1 -1
- package/dist/json/uni-x/manifest.js +2 -1
- package/dist/json/utils.js +24 -0
- package/dist/logs/console.js +4 -1
- package/dist/messages/en.d.ts +11 -2
- package/dist/messages/en.js +11 -2
- package/dist/messages/index.d.ts +22 -4
- package/dist/messages/zh_CN.d.ts +11 -2
- package/dist/messages/zh_CN.js +11 -2
- package/dist/mp/style.js +6 -2
- package/dist/mp/usingComponents.d.ts +7 -5
- package/dist/mp/usingComponents.js +63 -34
- package/dist/postcss/plugins/stylePluginExternal.d.ts +9 -10
- package/dist/postcss/plugins/stylePluginExternal.js +51 -45
- package/dist/resolve.d.ts +1 -0
- package/dist/resolve.js +9 -2
- package/dist/uni_modules.cloud.d.ts +7 -1
- package/dist/uni_modules.cloud.js +131 -14
- package/dist/uni_modules.js +3 -2
- package/dist/utils.js +5 -0
- package/dist/uts.d.ts +1 -0
- package/dist/uts.js +90 -6
- package/dist/vite/autoImport.js +7 -4
- package/dist/vite/cloud.js +13 -6
- package/dist/vite/extApi.js +4 -1
- package/dist/vite/plugins/cssScoped.js +11 -2
- package/dist/vite/plugins/easycom.js +3 -1
- package/dist/vite/plugins/inject.js +11 -3
- package/dist/vite/plugins/json.js +2 -69
- package/dist/vite/plugins/jsonJs.js +41 -3
- package/dist/vite/plugins/pre.js +2 -0
- package/dist/vite/plugins/sfc.js +4 -1
- package/dist/vite/plugins/stats.d.ts +5 -1
- package/dist/vite/plugins/stats.js +74 -3
- package/dist/vite/plugins/uts/uni_modules.d.ts +1 -1
- package/dist/vite/plugins/uts/uni_modules.js +30 -12
- package/dist/vite/plugins/vitejs/plugins/asset.js +14 -1
- package/dist/vite/plugins/vitejs/plugins/css.d.ts +2 -2
- package/dist/vite/plugins/vitejs/plugins/css.js +45 -6
- package/dist/vue/transforms/index.d.ts +1 -0
- package/dist/vue/transforms/index.js +2 -1
- package/dist/vue/transforms/transformTeleport.d.ts +2 -0
- package/dist/vue/transforms/transformTeleport.js +68 -0
- package/dist/vue/transforms/x/transformDirection.js +33 -4
- package/dist/workers.d.ts +1 -0
- package/dist/workers.js +12 -5
- package/dist/x.d.ts +11 -0
- package/dist/x.js +43 -0
- package/lib/dom2/app/@vitejs/plugin-vue/dist/index.cjs +0 -7
- package/lib/dom2/app/@vitejs/plugin-vue/dist/index.mjs +0 -7
- package/lib/dom2/app/@vue/compiler-core/dist/compiler-core.cjs.js +58 -63
- package/lib/dom2/app/@vue/compiler-core/dist/compiler-core.cjs.prod.js +58 -63
- package/lib/dom2/app/@vue/compiler-core/dist/compiler-core.d.ts +7 -1
- package/lib/dom2/app/@vue/compiler-core/dist/compiler-core.esm-bundler.js +22 -47
- package/lib/dom2/app/@vue/compiler-dom/dist/compiler-dom.cjs.js +12 -23
- package/lib/dom2/app/@vue/compiler-dom/dist/compiler-dom.cjs.prod.js +12 -22
- package/lib/dom2/app/@vue/compiler-dom/dist/compiler-dom.esm-browser.js +23 -74
- package/lib/dom2/app/@vue/compiler-dom/dist/compiler-dom.esm-browser.prod.js +5 -5
- package/lib/dom2/app/@vue/compiler-dom/dist/compiler-dom.esm-bundler.js +3 -20
- package/lib/dom2/app/@vue/compiler-dom/dist/compiler-dom.global.js +310 -363
- package/lib/dom2/app/@vue/compiler-dom/dist/compiler-dom.global.prod.js +5 -5
- package/lib/dom2/app/@vue/compiler-sfc/dist/compiler-sfc.cjs.js +810 -579
- package/lib/dom2/app/@vue/compiler-sfc/dist/compiler-sfc.d.ts +33 -11114
- package/lib/dom2/app/@vue/compiler-sfc/dist/compiler-sfc.esm-browser.js +1638 -1250
- package/lib/dom2/app/@vue/compiler-vapor/dist/compiler-vapor.cjs.js +1031 -599
- package/lib/dom2/app/@vue/compiler-vapor/dist/compiler-vapor.d.ts +470 -328
- package/lib/dom2/app/@vue/compiler-vapor/dist/compiler-vapor.esm-browser.js +1154 -709
- package/lib/dom2/app/@vue/compiler-vapor-dom2/dist/compiler-vapor-dom2.cjs.js +1 -1
- package/lib/dom2/app/@vue/shared/dist/shared.cjs.js +16 -25
- package/lib/dom2/app/@vue/shared/dist/shared.cjs.prod.js +16 -25
- package/lib/dom2/app/@vue/shared/dist/shared.d.ts +5 -0
- package/lib/dom2/app/@vue/shared/dist/shared.esm-bundler.js +11 -23
- package/package.json +6 -6
|
@@ -12,6 +12,7 @@ const shared_1 = require("@vue/shared");
|
|
|
12
12
|
const magic_string_1 = __importDefault(require("magic-string"));
|
|
13
13
|
const utils_1 = require("../utils");
|
|
14
14
|
const uts_1 = require("../../uts");
|
|
15
|
+
const x_1 = require("../../x");
|
|
15
16
|
const debugInject = (0, debug_1.default)('uni:inject');
|
|
16
17
|
// const debugInjectTry = debug('uni:inject-try')
|
|
17
18
|
function uniViteInjectPlugin(name, options) {
|
|
@@ -39,12 +40,15 @@ function uniViteInjectPlugin(name, options) {
|
|
|
39
40
|
normalizeModulesMap(namespaceModulesMap);
|
|
40
41
|
}
|
|
41
42
|
const firstpass = new RegExp(`(?:${Array.from(modulesMap.keys()).map(escape).join('|')})`, 'g');
|
|
42
|
-
|
|
43
|
+
let sourceMap = options.sourceMap !== false;
|
|
43
44
|
const callback = options.callback;
|
|
44
45
|
return {
|
|
45
46
|
name,
|
|
46
47
|
// 确保在 commonjs 之后,否则会混合 es6 module 与 cjs 的代码,导致 commonjs 失效
|
|
47
48
|
enforce: options.enforce ?? 'post',
|
|
49
|
+
configResolved(config) {
|
|
50
|
+
sourceMap = options.sourceMap !== false && (0, utils_1.withSourcemap)(config);
|
|
51
|
+
},
|
|
48
52
|
transform(code, id) {
|
|
49
53
|
if (!filter(id))
|
|
50
54
|
return null;
|
|
@@ -128,7 +132,7 @@ function uniViteInjectPlugin(name, options) {
|
|
|
128
132
|
}
|
|
129
133
|
(0, estree_walker_1.walk)(ast, {
|
|
130
134
|
enter(node, parent) {
|
|
131
|
-
if (sourceMap) {
|
|
135
|
+
if (sourceMap && (0, x_1.shouldUseHighResolutionSourceMap)()) {
|
|
132
136
|
magicString.addSourcemapLocation(node.start);
|
|
133
137
|
magicString.addSourcemapLocation(node.end);
|
|
134
138
|
}
|
|
@@ -170,7 +174,11 @@ function uniViteInjectPlugin(name, options) {
|
|
|
170
174
|
magicString.prepend(`${importBlock}\n\n`);
|
|
171
175
|
return {
|
|
172
176
|
code: magicString.toString(),
|
|
173
|
-
map: sourceMap
|
|
177
|
+
map: sourceMap
|
|
178
|
+
? magicString.generateMap({
|
|
179
|
+
hires: (0, x_1.shouldUseHighResolutionSourceMap)(),
|
|
180
|
+
})
|
|
181
|
+
: null,
|
|
174
182
|
};
|
|
175
183
|
},
|
|
176
184
|
};
|
|
@@ -9,86 +9,19 @@ const json_1 = require("../../json");
|
|
|
9
9
|
const preprocess_1 = require("../../preprocess");
|
|
10
10
|
const utils_1 = require("../utils");
|
|
11
11
|
function uniJsonPlugin() {
|
|
12
|
-
const UTS_CAST_ARRAY_MARKER = '/*__UTS_CAST_UTSJSON_ARRAY__*/';
|
|
13
|
-
const UTS_CAST_OBJECT_MARKER = '/*__UTS_CAST_UTSJSON_OBJECT__*/';
|
|
14
|
-
const IS_UNI_X_ANDROID = process.env.UNI_APP_X === 'true' &&
|
|
15
|
-
process.env.UNI_UTS_PLATFORM === 'app-android';
|
|
16
12
|
return {
|
|
17
13
|
name: 'uni:json',
|
|
18
14
|
enforce: 'pre',
|
|
19
|
-
generateBundle(options, bundle) {
|
|
20
|
-
if (IS_UNI_X_ANDROID) {
|
|
21
|
-
for (const [fileName, file] of Object.entries(bundle)) {
|
|
22
|
-
if (fileName.endsWith('.json.ts')) {
|
|
23
|
-
if (file.type === 'asset' && file.source) {
|
|
24
|
-
const source = file.source.toString();
|
|
25
|
-
if (source.includes(UTS_CAST_ARRAY_MARKER) ||
|
|
26
|
-
source.includes(UTS_CAST_OBJECT_MARKER)) {
|
|
27
|
-
file.source = source
|
|
28
|
-
.replace(new RegExp(UTS_CAST_ARRAY_MARKER.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), ' as UTSJSONObject[]')
|
|
29
|
-
.replace(new RegExp(UTS_CAST_OBJECT_MARKER.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), ' as UTSJSONObject');
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
15
|
transform(code, id) {
|
|
37
16
|
// 如果已经被其他插件处理过了,就不再处理,比如 commonjs 插件,ICAPRegistrar.json?commonjs-external
|
|
38
17
|
if (id.startsWith('\0')) {
|
|
39
18
|
return;
|
|
40
19
|
}
|
|
41
|
-
|
|
42
|
-
if (path_1.default.extname(filename) !== '.json') {
|
|
20
|
+
if (path_1.default.extname((0, utils_1.parseVueRequest)(id).filename) !== '.json') {
|
|
43
21
|
return;
|
|
44
22
|
}
|
|
45
|
-
let codeObj = (0, json_1.parseJson)((0, preprocess_1.preJson)(code, id), false, id);
|
|
46
|
-
let codeJson = '';
|
|
47
|
-
if (IS_UNI_X_ANDROID) {
|
|
48
|
-
if (Array.isArray(codeObj)) {
|
|
49
|
-
codeJson +=
|
|
50
|
-
'export default JSON.parseArray(`' +
|
|
51
|
-
JSON.stringify(codeObj, null, 2) +
|
|
52
|
-
'`)' +
|
|
53
|
-
UTS_CAST_ARRAY_MARKER +
|
|
54
|
-
';\n';
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
codeJson +=
|
|
58
|
-
'let __jsonObj = JSON.parseObject(`' +
|
|
59
|
-
JSON.stringify(codeObj, null, 2) +
|
|
60
|
-
'`);\n';
|
|
61
|
-
for (const key in codeObj) {
|
|
62
|
-
if (!Object.hasOwn(codeObj, key))
|
|
63
|
-
continue;
|
|
64
|
-
const element = codeObj[key];
|
|
65
|
-
if (Array.isArray(element)) {
|
|
66
|
-
codeJson += `export const ${key} = __jsonObj?.getArray("${key}")${UTS_CAST_ARRAY_MARKER};\n`;
|
|
67
|
-
}
|
|
68
|
-
else if (typeof element === 'object' && element !== null) {
|
|
69
|
-
codeJson += `export const ${key} = __jsonObj?.get("${key}")${UTS_CAST_OBJECT_MARKER};\n`;
|
|
70
|
-
}
|
|
71
|
-
else if (typeof element === 'string') {
|
|
72
|
-
codeJson += `export const ${key} = __jsonObj?.getString("${key}") ?? '';\n`;
|
|
73
|
-
}
|
|
74
|
-
else if (typeof element === 'number') {
|
|
75
|
-
codeJson += `export const ${key} = __jsonObj?.getNumber("${key}") ?? 0;\n`;
|
|
76
|
-
}
|
|
77
|
-
else if (typeof element === 'boolean') {
|
|
78
|
-
codeJson += `export const ${key} = __jsonObj?.getBoolean("${key}") ?? false;\n`;
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
codeJson += `export const ${key} = __jsonObj?.get("${key}")${UTS_CAST_OBJECT_MARKER};\n`;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
codeJson += `export default __jsonObj;`;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
codeJson = JSON.stringify(codeObj, null, 2);
|
|
89
|
-
}
|
|
90
23
|
return {
|
|
91
|
-
code:
|
|
24
|
+
code: JSON.stringify((0, json_1.parseJson)((0, preprocess_1.preJson)(code, id), false, id), null, 2),
|
|
92
25
|
map: {
|
|
93
26
|
mappings: '',
|
|
94
27
|
},
|
|
@@ -7,16 +7,19 @@ exports.defineUniManifestJsonPlugin = exports.defineUniPagesJsonPlugin = void 0;
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const constants_1 = require("../../constants");
|
|
10
|
+
const subpackage_1 = require("../../json/mp/subpackage");
|
|
10
11
|
const utils_1 = require("../../utils");
|
|
11
12
|
exports.defineUniPagesJsonPlugin = createDefineJsonJsPlugin('pages.json');
|
|
12
13
|
exports.defineUniManifestJsonPlugin = createDefineJsonJsPlugin('manifest.json');
|
|
13
14
|
function createDefineJsonJsPlugin(name) {
|
|
14
15
|
const JSON_JS = constants_1.JSON_JS_MAP[name];
|
|
16
|
+
// pages-json-js 仅允许独立分包 root query;manifest-json-js 仍保持 app 级。
|
|
17
|
+
const allowedQuery = name === 'pages.json' ? subpackage_1.MP_INDEPENDENT_ROOT_QUERY : '';
|
|
15
18
|
return function (createVitePlugin) {
|
|
16
19
|
const opts = {
|
|
17
20
|
resolvedConfig: {},
|
|
18
21
|
filter(id) {
|
|
19
|
-
return id
|
|
22
|
+
return !!parseJsonJsRequest(id, JSON_JS, allowedQuery);
|
|
20
23
|
},
|
|
21
24
|
};
|
|
22
25
|
const plugin = createVitePlugin(opts);
|
|
@@ -30,8 +33,9 @@ function createDefineJsonJsPlugin(name) {
|
|
|
30
33
|
if (res) {
|
|
31
34
|
return res;
|
|
32
35
|
}
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
const jsonJsRequest = parseJsonJsRequest(id, JSON_JS, allowedQuery);
|
|
37
|
+
if (jsonJsRequest) {
|
|
38
|
+
return jsonJsPath + jsonJsRequest.query;
|
|
35
39
|
}
|
|
36
40
|
};
|
|
37
41
|
plugin.configResolved = function (config) {
|
|
@@ -53,3 +57,37 @@ function createDefineJsonJsPlugin(name) {
|
|
|
53
57
|
return plugin;
|
|
54
58
|
};
|
|
55
59
|
}
|
|
60
|
+
function parseJsonJsRequest(id, jsonJs, allowedQuery) {
|
|
61
|
+
const queryIndex = id.indexOf('?');
|
|
62
|
+
const query = queryIndex === -1 ? '' : id.slice(queryIndex + 1);
|
|
63
|
+
if (query && !isAllowedJsonJsQuery(query, allowedQuery)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (queryIndex !== -1 && !query) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const filename = queryIndex === -1 ? id : id.slice(0, queryIndex);
|
|
70
|
+
if (!filename.endsWith(jsonJs)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
filename,
|
|
75
|
+
query: queryIndex === -1 ? '' : id.slice(queryIndex),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function isAllowedJsonJsQuery(query, allowedQuery) {
|
|
79
|
+
if (!allowedQuery) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
const items = query.split('&');
|
|
83
|
+
if (items.length !== 1) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const item = items[0];
|
|
87
|
+
const equalIndex = item.indexOf('=');
|
|
88
|
+
if (equalIndex === -1) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
return (item.slice(0, equalIndex) === allowedQuery &&
|
|
92
|
+
item.slice(equalIndex + 1).length > 0);
|
|
93
|
+
}
|
package/dist/vite/plugins/pre.js
CHANGED
|
@@ -8,6 +8,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
8
8
|
const debug_1 = __importDefault(require("debug"));
|
|
9
9
|
const pluginutils_1 = require("@rollup/pluginutils");
|
|
10
10
|
const constants_1 = require("../../constants");
|
|
11
|
+
const dom2_1 = require("../../dom2");
|
|
11
12
|
const preprocess_1 = require("../../preprocess");
|
|
12
13
|
const utils_1 = require("../utils");
|
|
13
14
|
const debugPreJs = (0, debug_1.default)('uni:pre-js');
|
|
@@ -41,6 +42,7 @@ function uniPrePlugin(config, options) {
|
|
|
41
42
|
if (!hasEndif) {
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
45
|
+
(0, dom2_1.warnDom2RootScrollView)(code, filename, !!query.vue);
|
|
44
46
|
// 因为完整的 vue 会先条件编译,而 vue&type=template 等会再次条件编译,如果走error模式会报两次错误,且第二次错误没有正确的位置映射
|
|
45
47
|
const unbalanced = query.vue ? 'skip' : 'error';
|
|
46
48
|
if (isHtml) {
|
package/dist/vite/plugins/sfc.js
CHANGED
|
@@ -9,6 +9,7 @@ const magic_string_1 = __importDefault(require("magic-string"));
|
|
|
9
9
|
const vue_1 = require("../../vue");
|
|
10
10
|
const utils_1 = require("../utils");
|
|
11
11
|
const preprocess_1 = require("../../preprocess");
|
|
12
|
+
const x_1 = require("../../x");
|
|
12
13
|
const SRC_IMPORT_RE = /<(template|script|style)[^>]*src\s*=\s*["']([^"']+)["'][^>]*>/;
|
|
13
14
|
const SRC_IMPORT_VUE_RE = /<(template|script|style)[^>]*src\s*=\s*["'](.*\.uvue|.*\.vue)["'][^>]*>/;
|
|
14
15
|
function isSrcImport(code) {
|
|
@@ -120,7 +121,9 @@ function uniViteSfcSrcImportPlugin({ onlyVue } = { onlyVue: true }) {
|
|
|
120
121
|
}
|
|
121
122
|
return {
|
|
122
123
|
code: s.toString(),
|
|
123
|
-
map: sourceMap
|
|
124
|
+
map: sourceMap
|
|
125
|
+
? s.generateMap({ hires: (0, x_1.shouldUseHighResolutionSourceMap)() })
|
|
126
|
+
: null,
|
|
124
127
|
};
|
|
125
128
|
},
|
|
126
129
|
};
|
|
@@ -9,11 +9,64 @@ const utils_1 = require("../../utils");
|
|
|
9
9
|
const json_1 = require("../../json");
|
|
10
10
|
const messages_1 = require("../../messages");
|
|
11
11
|
const emittedHashMap = new WeakMap();
|
|
12
|
-
function
|
|
12
|
+
function normalizeVaporRenderTarget(target) {
|
|
13
|
+
if (typeof target !== 'string') {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (target.includes('bytecode')) {
|
|
17
|
+
return 'bytecode';
|
|
18
|
+
}
|
|
19
|
+
if (target.includes('nativecode')) {
|
|
20
|
+
return 'nativecode';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function formatVaporRenderTarget(target) {
|
|
24
|
+
return messages_1.M[`view.render.compiler.target.${target}`];
|
|
25
|
+
}
|
|
26
|
+
function getManifestVaporRenderTarget(manifest) {
|
|
27
|
+
return normalizeVaporRenderTarget(manifest['uni-app-x']?.['vapor-render-target']);
|
|
28
|
+
}
|
|
29
|
+
function appendChangedFile(changedFiles, seenFiles, filename) {
|
|
30
|
+
if (seenFiles.has(filename)) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
seenFiles.add(filename);
|
|
34
|
+
changedFiles.push(filename);
|
|
35
|
+
}
|
|
36
|
+
function appendImporterFiles(changedFiles, seenFiles, bundle) {
|
|
37
|
+
const importerMap = new Map();
|
|
38
|
+
Object.keys(bundle).forEach((filename) => {
|
|
39
|
+
const outputFile = bundle[filename];
|
|
40
|
+
if (outputFile.type !== 'chunk') {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const imports = outputFile.imports.concat(outputFile.dynamicImports);
|
|
44
|
+
imports.forEach((file) => {
|
|
45
|
+
const importers = importerMap.get(file);
|
|
46
|
+
if (importers) {
|
|
47
|
+
importers.push(filename);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
importerMap.set(file, [filename]);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
for (let i = 0; i < changedFiles.length; i++) {
|
|
55
|
+
const importers = importerMap.get(changedFiles[i]);
|
|
56
|
+
if (!importers) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
importers.forEach((filename) => {
|
|
60
|
+
appendChangedFile(changedFiles, seenFiles, filename);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function uniStatsPlugin(options = {}) {
|
|
13
65
|
let resolvedConfig;
|
|
14
66
|
let isManifestChanged = false;
|
|
15
|
-
const shouldTrackManifestChange = process.env.
|
|
67
|
+
const shouldTrackManifestChange = process.env.UNI_PLATFORM === 'app' ||
|
|
16
68
|
process.env.UNI_PLATFORM === 'app-harmony';
|
|
69
|
+
const shouldAppendImporterFiles = process.env.UNI_PLATFORM === 'app-harmony';
|
|
17
70
|
let isVapor = shouldTrackManifestChange && process.env.UNI_APP_X_DOM2 === 'true';
|
|
18
71
|
return {
|
|
19
72
|
name: 'uni:app-stats',
|
|
@@ -28,21 +81,36 @@ function uniStatsPlugin() {
|
|
|
28
81
|
try {
|
|
29
82
|
const manifest = (0, json_1.parseJson)(fs_extra_1.default.readFileSync(id, 'utf-8'), true, 'manifest.json');
|
|
30
83
|
const uniAppX = manifest['uni-app-x'] || {};
|
|
84
|
+
const vaporRenderTarget = getManifestVaporRenderTarget(manifest);
|
|
85
|
+
const runtimeVaporRenderTarget = normalizeVaporRenderTarget(process.env.UNI_APP_X_VAPOR_RENDER_TARGET);
|
|
86
|
+
if (vaporRenderTarget &&
|
|
87
|
+
runtimeVaporRenderTarget &&
|
|
88
|
+
vaporRenderTarget !== runtimeVaporRenderTarget) {
|
|
89
|
+
console.warn(messages_1.M['dev.watching.vapor.render.target']
|
|
90
|
+
.replace('{manifestTarget}', formatVaporRenderTarget(vaporRenderTarget))
|
|
91
|
+
.replace('{runtimeTarget}', formatVaporRenderTarget(runtimeVaporRenderTarget)));
|
|
92
|
+
}
|
|
31
93
|
if (uniAppX.vapor !== isVapor) {
|
|
32
94
|
isVapor = uniAppX.vapor === true;
|
|
33
95
|
console.warn(messages_1.M['dev.watching.restart.vapor']);
|
|
96
|
+
// 主动退出,避免后续会打印正在编译中等日志
|
|
97
|
+
process.exit(0);
|
|
34
98
|
}
|
|
35
99
|
}
|
|
36
100
|
catch (e) { }
|
|
37
101
|
}
|
|
38
102
|
},
|
|
39
103
|
writeBundle(_, bundle) {
|
|
104
|
+
if (options.manifestOnly) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
40
107
|
if (resolvedConfig.isProduction) {
|
|
41
108
|
// 仅dev生效
|
|
42
109
|
return;
|
|
43
110
|
}
|
|
44
111
|
const emittedHash = emittedHashMap.get(resolvedConfig);
|
|
45
112
|
const changedFiles = [];
|
|
113
|
+
const seenFiles = new Set();
|
|
46
114
|
Object.keys(bundle).forEach((filename) => {
|
|
47
115
|
// 不处理sourcemap
|
|
48
116
|
if (filename.endsWith('.map')) {
|
|
@@ -58,9 +126,12 @@ function uniStatsPlugin() {
|
|
|
58
126
|
}
|
|
59
127
|
if (emittedHash.get(filename) !== outputFileHash) {
|
|
60
128
|
emittedHash.set(filename, outputFileHash);
|
|
61
|
-
changedFiles
|
|
129
|
+
appendChangedFile(changedFiles, seenFiles, filename);
|
|
62
130
|
}
|
|
63
131
|
});
|
|
132
|
+
if (shouldAppendImporterFiles) {
|
|
133
|
+
appendImporterFiles(changedFiles, seenFiles, bundle);
|
|
134
|
+
}
|
|
64
135
|
if (isManifestChanged) {
|
|
65
136
|
isManifestChanged = false;
|
|
66
137
|
changedFiles.unshift('manifest.json');
|
|
@@ -12,7 +12,7 @@ interface UniUTSPluginOptions {
|
|
|
12
12
|
export declare function getCurrentCompiledUTSPlugins(): Set<string>;
|
|
13
13
|
export declare function getCurrentCompiledUTSProviders(): Set<string>;
|
|
14
14
|
export declare function uniUTSAppUniModulesPlugin(options?: UniUTSPluginOptions): Plugin;
|
|
15
|
-
export declare function buildUniExtApis(): Promise<void>;
|
|
15
|
+
export declare function buildUniExtApis(providerOnly?: boolean): Promise<void>;
|
|
16
16
|
export declare function buildNonTreeShakingUniModules(): Promise<void>;
|
|
17
17
|
export declare function resolveExtApiProvider(pkg: Record<string, any>): {
|
|
18
18
|
name?: string | undefined;
|
|
@@ -12,6 +12,7 @@ const uts_1 = require("../../../uts");
|
|
|
12
12
|
const utils_1 = require("../../utils");
|
|
13
13
|
const uni_modules_1 = require("../../../uni_modules");
|
|
14
14
|
const uni_modules_cloud_1 = require("../../../uni_modules.cloud");
|
|
15
|
+
const x_1 = require("../../../x");
|
|
15
16
|
const utils_2 = require("../../../utils");
|
|
16
17
|
const json_1 = require("../../../json");
|
|
17
18
|
const fs_1 = require("../../../fs");
|
|
@@ -19,6 +20,7 @@ const context_1 = require("../../../preprocess/context");
|
|
|
19
20
|
const hbx_1 = require("../../../hbx");
|
|
20
21
|
const console_1 = require("../../../logs/console");
|
|
21
22
|
const workers_1 = require("../../../workers");
|
|
23
|
+
const dom2_1 = require("../../../dom2");
|
|
22
24
|
/* eslint-disable no-restricted-globals */
|
|
23
25
|
const { preprocess } = require('../../../../lib/preprocess');
|
|
24
26
|
function rewriteUniModulesConsoleExpr(fileName, content) {
|
|
@@ -160,7 +162,7 @@ function getCurrentCompiledUTSProviders() {
|
|
|
160
162
|
return utsProviders;
|
|
161
163
|
}
|
|
162
164
|
exports.getCurrentCompiledUTSProviders = getCurrentCompiledUTSProviders;
|
|
163
|
-
let uniExtApiCompiler = async () => { };
|
|
165
|
+
let uniExtApiCompiler = async (providerOnly = false) => { };
|
|
164
166
|
let nonTreeShakingUniModulesCompiler = async () => { };
|
|
165
167
|
function emptyCacheDir(platform) {
|
|
166
168
|
const uvueOutputDir = (0, uts_1.uvueOutDir)(platform);
|
|
@@ -242,7 +244,10 @@ function uniUTSAppUniModulesPlugin(options = {}) {
|
|
|
242
244
|
const uniXKotlinCompiler = process.env.UNI_APP_X_TSC === 'true' &&
|
|
243
245
|
(process.env.UNI_UTS_PLATFORM === 'app-android' ||
|
|
244
246
|
process.env.UNI_UTS_PLATFORM === 'app')
|
|
245
|
-
? createUniXKotlinCompilerOnce({
|
|
247
|
+
? createUniXKotlinCompilerOnce({
|
|
248
|
+
resolveWorkers,
|
|
249
|
+
sourceFileCallback: (0, dom2_1.initSourceFileCallback)(),
|
|
250
|
+
})
|
|
246
251
|
: null;
|
|
247
252
|
const uniXSwiftCompiler = process.env.UNI_APP_X_TSC === 'true' &&
|
|
248
253
|
(process.env.UNI_UTS_PLATFORM === 'app-ios' ||
|
|
@@ -418,16 +423,20 @@ function uniUTSAppUniModulesPlugin(options = {}) {
|
|
|
418
423
|
return filterAutoImports(autoImports, (0, uts_1.parseSwiftModuleWithPluginId)(pluginId, true));
|
|
419
424
|
});
|
|
420
425
|
},
|
|
426
|
+
iosPreprocessor: createAppIosUniModulesSyncFilePreprocessorOnce(!!options.x),
|
|
427
|
+
androidPreprocessor: createAppAndroidUniModulesSyncFilePreprocessorOnce(!!options.x),
|
|
428
|
+
// harmonyPreprocessor: createAppHarmonyUniModulesSyncFilePreprocessorOnce(!!options.x),
|
|
421
429
|
});
|
|
422
430
|
};
|
|
423
|
-
uniExtApiCompiler = async () => {
|
|
431
|
+
uniExtApiCompiler = async (providerOnly = false) => {
|
|
424
432
|
// 此方法为兜底方法,确保uni_modules中的所有插件都会编译,目前仅用于编译provider
|
|
425
433
|
// 获取 provider 扩展(编译所有uni)
|
|
426
434
|
const plugins = (0, uni_modules_1.getUniExtApiPlugins)().filter((provider) => !utsPlugins.has(provider.plugin));
|
|
435
|
+
const providers = (0, uni_modules_1.getUniExtApiProviders)();
|
|
427
436
|
for (const plugin of plugins) {
|
|
428
437
|
const pluginDir = path_1.default.resolve(inputDir, 'uni_modules', plugin.plugin);
|
|
429
438
|
// 如果是 app-js 环境
|
|
430
|
-
if (
|
|
439
|
+
if ((0, x_1.isUniAppXJsEngine)()) {
|
|
431
440
|
if (fs_extra_1.default.existsSync(path_1.default.resolve(pluginDir, 'utssdk', 'app-js', 'index.uts'))) {
|
|
432
441
|
continue;
|
|
433
442
|
}
|
|
@@ -440,14 +449,18 @@ function uniUTSAppUniModulesPlugin(options = {}) {
|
|
|
440
449
|
continue;
|
|
441
450
|
}
|
|
442
451
|
}
|
|
452
|
+
const isProvider = providers.some((p) => p.plugin === plugin.plugin);
|
|
443
453
|
utsProviders.add(plugin.plugin);
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
// 时机不对,不能addWatch
|
|
447
|
-
// result.deps.forEach((dep) => {
|
|
448
|
-
// this.addWatchFile(dep)
|
|
449
|
-
// })
|
|
454
|
+
if ((providerOnly && isProvider) || !providerOnly) {
|
|
455
|
+
await compilePlugin(pluginDir);
|
|
450
456
|
}
|
|
457
|
+
// const result = await compilePlugin(pluginDir)
|
|
458
|
+
// if (result) {
|
|
459
|
+
// // 时机不对,不能addWatch
|
|
460
|
+
// // result.deps.forEach((dep) => {
|
|
461
|
+
// // this.addWatchFile(dep)
|
|
462
|
+
// // })
|
|
463
|
+
// }
|
|
451
464
|
}
|
|
452
465
|
};
|
|
453
466
|
nonTreeShakingUniModulesCompiler = async () => {
|
|
@@ -570,8 +583,8 @@ function uniUTSAppUniModulesPlugin(options = {}) {
|
|
|
570
583
|
};
|
|
571
584
|
}
|
|
572
585
|
exports.uniUTSAppUniModulesPlugin = uniUTSAppUniModulesPlugin;
|
|
573
|
-
async function buildUniExtApis() {
|
|
574
|
-
await uniExtApiCompiler();
|
|
586
|
+
async function buildUniExtApis(providerOnly = false) {
|
|
587
|
+
await uniExtApiCompiler(providerOnly);
|
|
575
588
|
}
|
|
576
589
|
exports.buildUniExtApis = buildUniExtApis;
|
|
577
590
|
async function buildNonTreeShakingUniModules() {
|
|
@@ -610,8 +623,13 @@ function uniDecryptUniModulesPlugin() {
|
|
|
610
623
|
appname: manifest.name,
|
|
611
624
|
platform: process.env.UNI_UTS_PLATFORM,
|
|
612
625
|
'uni-app-x': isX,
|
|
626
|
+
vapor: process.env.UNI_APP_X_DOM2 === 'true',
|
|
613
627
|
env,
|
|
614
628
|
};
|
|
629
|
+
if (options.vapor) {
|
|
630
|
+
options.vaporRenderTarget =
|
|
631
|
+
process.env.UNI_APP_X_VAPOR_RENDER_TARGET || 'bytecode';
|
|
632
|
+
}
|
|
615
633
|
// 鸿蒙平台需要拆分两次云编译
|
|
616
634
|
if (process.env.UNI_UTS_PLATFORM === 'app-harmony') {
|
|
617
635
|
const harmonyEnv = {
|
|
@@ -37,8 +37,10 @@ const shared_1 = require("@vue/shared");
|
|
|
37
37
|
const utils_1 = require("../utils");
|
|
38
38
|
const utils_2 = require("../../../../vite/utils/utils");
|
|
39
39
|
const utils_3 = require("../../../../utils");
|
|
40
|
+
const x_1 = require("../../../../x");
|
|
40
41
|
const static_1 = require("./static");
|
|
41
42
|
exports.assetUrlRE = /__VITE_ASSET__([a-z\d]{8})__(?:\$_(.*?)__)?/g;
|
|
43
|
+
const assetUrlMarker = '__VITE_ASSET__';
|
|
42
44
|
const rawRE = /(\?|&)raw(?:&|$)/;
|
|
43
45
|
const urlRE = /(\?|&)url(?:&|$)/;
|
|
44
46
|
exports.chunkToEmittedAssetsMap = new WeakMap();
|
|
@@ -106,6 +108,10 @@ function assetPlugin(config, options) {
|
|
|
106
108
|
let match;
|
|
107
109
|
let s;
|
|
108
110
|
exports.assetUrlRE.lastIndex = 0;
|
|
111
|
+
// 部分 chunk 不包含资源占位符,先用低成本字符串查找跳过正则扫描。
|
|
112
|
+
if (code.indexOf(assetUrlMarker) === -1) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
109
115
|
// Urls added with JS using e.g.
|
|
110
116
|
// imgElement.src = "__VITE_ASSET__5aa0ddc0__" are using quotes
|
|
111
117
|
// Urls added in CSS that is imported in JS end up like
|
|
@@ -124,7 +130,9 @@ function assetPlugin(config, options) {
|
|
|
124
130
|
if (s) {
|
|
125
131
|
return {
|
|
126
132
|
code: s.toString(),
|
|
127
|
-
map: (0, utils_2.withSourcemap)(config)
|
|
133
|
+
map: (0, utils_2.withSourcemap)(config)
|
|
134
|
+
? s.generateMap({ hires: shouldUseAssetHighResolutionSourceMap() })
|
|
135
|
+
: null,
|
|
128
136
|
};
|
|
129
137
|
}
|
|
130
138
|
else {
|
|
@@ -134,6 +142,11 @@ function assetPlugin(config, options) {
|
|
|
134
142
|
};
|
|
135
143
|
}
|
|
136
144
|
exports.assetPlugin = assetPlugin;
|
|
145
|
+
function shouldUseAssetHighResolutionSourceMap() {
|
|
146
|
+
// Android dom2 的 app-service 后续会与 esbuild map 合并,低精度 asset map
|
|
147
|
+
// 可能导致原始 .uvue 映射丢失或断点偏移。
|
|
148
|
+
return (0, x_1.isUniAppXAndroid)() || (0, x_1.shouldUseHighResolutionSourceMap)();
|
|
149
|
+
}
|
|
137
150
|
function parseAssets(config, code) {
|
|
138
151
|
let match;
|
|
139
152
|
let s;
|
|
@@ -47,9 +47,9 @@ export declare function cssPostPlugin(config: ResolvedConfig, { platform, isJsCo
|
|
|
47
47
|
isJsCode?: boolean;
|
|
48
48
|
preserveModules?: boolean;
|
|
49
49
|
chunkCssFilename: (id: string) => string | void;
|
|
50
|
-
chunkCssCode: (filename: string, cssCode: string) => Promise<string> | string;
|
|
50
|
+
chunkCssCode: (filename: string, cssCode: string) => Promise<string | Uint8Array> | string;
|
|
51
51
|
includeComponentCss?: boolean;
|
|
52
|
-
emitFile?: (filename: string, cssCode: string) => void;
|
|
52
|
+
emitFile?: (filename: string, cssCode: string | Uint8Array) => void;
|
|
53
53
|
}): Plugin;
|
|
54
54
|
export declare function formatPostcssSourceMap(rawMap: ExistingRawSourceMap, file: string): ExistingRawSourceMap;
|
|
55
55
|
export type CssUrlReplacer = (url: string, importer?: string, source?: PostCSS.Source) => string | Promise<string>;
|
|
@@ -42,7 +42,9 @@ const shared_1 = require("@vue/shared");
|
|
|
42
42
|
const preprocess_1 = require("../../../../preprocess");
|
|
43
43
|
const uniapp_1 = require("../../../../postcss/plugins/uniapp");
|
|
44
44
|
const cleanString_1 = require("../cleanString");
|
|
45
|
+
const x_1 = require("../../../../x");
|
|
45
46
|
const constants_1 = require("../../../../constants");
|
|
47
|
+
const fontFamily_1 = require("../../../../dom2/fontFamily");
|
|
46
48
|
const utils_2 = require("../../../utils/utils");
|
|
47
49
|
const compiler_core_1 = require("@vue/compiler-core");
|
|
48
50
|
const utils_3 = require("../../../../utils");
|
|
@@ -222,8 +224,17 @@ function findCssModuleIds(moduleId, includeComponentCss = true, cssModuleIds, se
|
|
|
222
224
|
function cssPostPlugin(config, { platform, isJsCode, preserveModules, chunkCssFilename, chunkCssCode, includeComponentCss, emitFile, }) {
|
|
223
225
|
// styles initialization in buildStart causes a styling loss in watch
|
|
224
226
|
const styles = new Map();
|
|
227
|
+
// 只缓存 cssCode 的 hash,不缓存完整 css,避免用空间换时间。
|
|
228
|
+
const cssChunkCodeHashCache = new Map();
|
|
225
229
|
let cssChunks;
|
|
226
|
-
const
|
|
230
|
+
const isDom2 = process.env.UNI_APP_X_DOM2 === 'true';
|
|
231
|
+
const isDom2App = isDom2 && platform.startsWith('app');
|
|
232
|
+
// 仅限定鸿蒙 DOM2 开发模式,避免影响其它平台和生产构建。
|
|
233
|
+
const enableCssIncremental = process.env.NODE_ENV === 'development' &&
|
|
234
|
+
process.env.UNI_UTS_PLATFORM === 'app-harmony' &&
|
|
235
|
+
isDom2App &&
|
|
236
|
+
!!isJsCode &&
|
|
237
|
+
!!emitFile;
|
|
227
238
|
return {
|
|
228
239
|
name: 'vite:css-post',
|
|
229
240
|
buildStart() {
|
|
@@ -240,8 +251,8 @@ function cssPostPlugin(config, { platform, isJsCode, preserveModules, chunkCssFi
|
|
|
240
251
|
return {
|
|
241
252
|
code: modulesCode ||
|
|
242
253
|
(isJsCode
|
|
243
|
-
?
|
|
244
|
-
? `export default ${
|
|
254
|
+
? isDom2App
|
|
255
|
+
? `export default ${(0, fontFamily_1.createJsStylePlaceholder)(id)}`
|
|
245
256
|
: 'export default {}'
|
|
246
257
|
: ''),
|
|
247
258
|
map: { mappings: '' },
|
|
@@ -251,7 +262,7 @@ function cssPostPlugin(config, { platform, isJsCode, preserveModules, chunkCssFi
|
|
|
251
262
|
};
|
|
252
263
|
},
|
|
253
264
|
async renderChunk(_code, chunk, _opts) {
|
|
254
|
-
if (
|
|
265
|
+
if (isDom2) {
|
|
255
266
|
// 通过 generateBundle 实现
|
|
256
267
|
return null;
|
|
257
268
|
}
|
|
@@ -337,6 +348,9 @@ function cssPostPlugin(config, { platform, isJsCode, preserveModules, chunkCssFi
|
|
|
337
348
|
});
|
|
338
349
|
}
|
|
339
350
|
if (!cssChunks.size) {
|
|
351
|
+
if (enableCssIncremental) {
|
|
352
|
+
cssChunkCodeHashCache.clear();
|
|
353
|
+
}
|
|
340
354
|
return;
|
|
341
355
|
}
|
|
342
356
|
// resolve asset URL placeholders to their built file URLs and perform
|
|
@@ -365,14 +379,29 @@ function cssPostPlugin(config, { platform, isJsCode, preserveModules, chunkCssFi
|
|
|
365
379
|
.map((id) => styles.get(id) || '')
|
|
366
380
|
.join('\n');
|
|
367
381
|
};
|
|
382
|
+
const currentCssFilenames = enableCssIncremental
|
|
383
|
+
? new Set(cssChunks.keys())
|
|
384
|
+
: undefined;
|
|
368
385
|
for (const filename of cssChunks.keys()) {
|
|
369
386
|
const cssCode = genCssCode(filename);
|
|
387
|
+
const cssCodeHash = enableCssIncremental ? (0, utils_3.hash)(cssCode) : '';
|
|
388
|
+
const hasFontFace = enableCssIncremental && /@font-face\b/i.test(cssCode);
|
|
389
|
+
// 鸿蒙 DOM2 开发模式下,未变化的样式无需重复 parseCss 和写入原生侧。
|
|
390
|
+
// @font-face 会在 chunkCssCode 中写入字体缓存,必须保留原有副作用。
|
|
391
|
+
if (enableCssIncremental &&
|
|
392
|
+
!hasFontFace &&
|
|
393
|
+
cssChunkCodeHashCache.get(filename) === cssCodeHash) {
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
370
396
|
let source = await processChunkCSS(cssCode, {
|
|
371
397
|
filename: filename,
|
|
372
398
|
inlined: false,
|
|
373
399
|
minify: true,
|
|
374
400
|
});
|
|
375
|
-
if (source
|
|
401
|
+
if (typeof source === 'string') {
|
|
402
|
+
source = source.trim();
|
|
403
|
+
}
|
|
404
|
+
if (source) {
|
|
376
405
|
emitFile
|
|
377
406
|
? emitFile(filename, source)
|
|
378
407
|
: this.emitFile({
|
|
@@ -381,6 +410,16 @@ function cssPostPlugin(config, { platform, isJsCode, preserveModules, chunkCssFi
|
|
|
381
410
|
source,
|
|
382
411
|
});
|
|
383
412
|
}
|
|
413
|
+
if (enableCssIncremental) {
|
|
414
|
+
cssChunkCodeHashCache.set(filename, cssCodeHash);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (currentCssFilenames) {
|
|
418
|
+
cssChunkCodeHashCache.forEach((_, filename) => {
|
|
419
|
+
if (!currentCssFilenames.has(filename)) {
|
|
420
|
+
cssChunkCodeHashCache.delete(filename);
|
|
421
|
+
}
|
|
422
|
+
});
|
|
384
423
|
}
|
|
385
424
|
},
|
|
386
425
|
};
|
|
@@ -1170,7 +1209,7 @@ async function getSource(source, filename, additionalData, enableSourcemap, sep
|
|
|
1170
1209
|
const ms = new magic_string_1.default(source);
|
|
1171
1210
|
ms.appendLeft(0, sep);
|
|
1172
1211
|
ms.appendLeft(0, additionalData);
|
|
1173
|
-
const map = ms.generateMap({ hires:
|
|
1212
|
+
const map = ms.generateMap({ hires: (0, x_1.shouldUseHighResolutionSourceMap)() });
|
|
1174
1213
|
map.file = filename;
|
|
1175
1214
|
map.sources = [filename];
|
|
1176
1215
|
return {
|