@aiot-toolkit/aiotpack 2.0.6-beta.9 → 2.1.0-prender.2

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.
Files changed (31) hide show
  1. package/lib/afterCompile/ux/UxAfterCompile.js +25 -2
  2. package/lib/compiler/javascript/JavascriptCompiler.js +11 -4
  3. package/lib/compiler/javascript/TemplateCompiler.d.ts +29 -0
  4. package/lib/compiler/javascript/TemplateCompiler.js +564 -0
  5. package/lib/compiler/javascript/ViteCompiler.d.ts +13 -0
  6. package/lib/compiler/javascript/ViteCompiler.js +449 -0
  7. package/lib/compiler/javascript/interface/IJavascriptCompileOption.d.ts +9 -0
  8. package/lib/compiler/javascript/vela/VelaWebpackConfigurator.d.ts +3 -1
  9. package/lib/compiler/javascript/vela/VelaWebpackConfigurator.js +16 -1
  10. package/lib/compiler/javascript/vela/interface/IManifest.d.ts +12 -0
  11. package/lib/compiler/javascript/vela/plugin/WrapPlugin.d.ts +10 -1
  12. package/lib/compiler/javascript/vela/plugin/WrapPlugin.js +241 -57
  13. package/lib/compiler/javascript/vela/utils/UxCompileUtil.d.ts +3 -2
  14. package/lib/compiler/javascript/vela/utils/UxCompileUtil.js +12 -4
  15. package/lib/compiler/javascript/vela/utils/VruUtil.d.ts +50 -0
  16. package/lib/compiler/javascript/vela/utils/VruUtil.js +128 -0
  17. package/lib/compiler/javascript/vela/utils/ZipUtil.d.ts +9 -0
  18. package/lib/compiler/javascript/vela/utils/ZipUtil.js +112 -6
  19. package/lib/compiler/javascript/vela/utils/webpackLoader/WebpackJsLoader.js +1 -1
  20. package/lib/config/UxConfig.d.ts +12 -5
  21. package/lib/config/UxConfig.js +4 -6
  22. package/lib/loader/ux/JsLoader.d.ts +7 -0
  23. package/lib/loader/ux/JsLoader.js +38 -8
  24. package/lib/loader/ux/vela/HmlLoader.d.ts +6 -6
  25. package/lib/loader/ux/vela/HmlLoader.js +30 -13
  26. package/lib/utils/BeforeCompileUtils.d.ts +1 -1
  27. package/lib/utils/BeforeCompileUtils.js +52 -9
  28. package/lib/utils/ux/ManifestSchema.js +0 -1
  29. package/lib/utils/ux/UxFileUtils.js +1 -1
  30. package/lib/utils/ux/UxLoaderUtils.js +8 -3
  31. package/package.json +9 -6
@@ -0,0 +1,13 @@
1
+ import IJavascriptCompileOption from './interface/IJavascriptCompileOption';
2
+ import ICompileParam from '../interface/ICompileParam';
3
+ import ICompiler from '../interface/ICompiler';
4
+ import { ILog } from '@aiot-toolkit/shared-utils';
5
+ import { IFileLaneContext } from 'file-lane';
6
+ declare class ViteCompiler implements ICompiler {
7
+ private readonly context;
8
+ private readonly onLog?;
9
+ constructor(context: IFileLaneContext, onLog?: ((log: ILog[]) => void) | undefined);
10
+ compile(param: IJavascriptCompileOption): Promise<void>;
11
+ clean(param: ICompileParam & IJavascriptCompileOption): Promise<void>;
12
+ }
13
+ export default ViteCompiler;
@@ -0,0 +1,449 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _TemplateCompiler = require("./TemplateCompiler");
8
+ var _path = _interopRequireDefault(require("path"));
9
+ var _fsExtra = _interopRequireDefault(require("fs-extra"));
10
+ var _UxCompileUtil = _interopRequireDefault(require("./vela/utils/UxCompileUtil"));
11
+ var _UxFileUtils = _interopRequireDefault(require("../../utils/ux/UxFileUtils"));
12
+ var _UxLoaderUtils = _interopRequireDefault(require("../../utils/ux/UxLoaderUtils"));
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ class ViteCompiler {
15
+ constructor(context, onLog) {
16
+ this.context = context;
17
+ this.onLog = onLog;
18
+ }
19
+ async compile(param) {
20
+ await this.clean(param);
21
+ const {
22
+ projectPath,
23
+ sourceRoot,
24
+ outputPath
25
+ } = param;
26
+ const originalProjectPath = projectPath.replace(/\.temp_/, '');
27
+ const buildPath = _path.default.resolve(projectPath, outputPath);
28
+ const srcPath = _path.default.resolve(originalProjectPath, sourceRoot);
29
+ const manifestPath = _UxFileUtils.default.getManifestFilePath(originalProjectPath, sourceRoot);
30
+ const manifest = _fsExtra.default.readJSONSync(manifestPath);
31
+ const entries = _UxCompileUtil.default.resolveEntries(manifest, srcPath, originalProjectPath);
32
+ for (const [entryName, entryValue] of Object.entries(entries)) {
33
+ const entryPath = entryValue.split('?')[0];
34
+ const resolvedEntry = _path.default.resolve(originalProjectPath, entryPath);
35
+ if (!_fsExtra.default.existsSync(resolvedEntry)) continue;
36
+ const outputFile = _path.default.join(buildPath, `${entryName}.js`);
37
+ _fsExtra.default.ensureDirSync(_path.default.dirname(outputFile));
38
+ const allEntryPaths = Object.values(entries).map(v => _path.default.resolve(originalProjectPath, v.split('?')[0]));
39
+ const compilation = {
40
+ entries: allEntryPaths
41
+ };
42
+ try {
43
+ const {
44
+ build
45
+ } = await import('vite');
46
+ const result = await build({
47
+ root: originalProjectPath,
48
+ logLevel: 'silent',
49
+ resolve: {
50
+ extensions: ['.js', '.ts', '.ux', '.json']
51
+ },
52
+ build: {
53
+ write: false,
54
+ lib: {
55
+ entry: resolvedEntry,
56
+ formats: ['es'],
57
+ fileName: () => 'output.js'
58
+ },
59
+ rollupOptions: {
60
+ external: id => id.startsWith('@app-module/') || /^@(system|service|android|hap)\./.test(id),
61
+ output: {
62
+ globals: id => `$app_require$("@app-module/${id.replace(/^@(system|service|android|hap|app-module)\./, '')}")`
63
+ }
64
+ },
65
+ commonjsOptions: {
66
+ transformMixedEsModules: true
67
+ },
68
+ minify: param.mode === 'production' ? 'terser' : false,
69
+ terserOptions: {
70
+ format: {
71
+ comments: false
72
+ }
73
+ }
74
+ },
75
+ plugins: [{
76
+ name: "cjs-shim",
77
+ enforce: "pre",
78
+ load(id) {
79
+ if (id.includes('node_modules') && !id.endsWith('.ux')) {
80
+ const content = _fsExtra.default.readFileSync(id, 'utf-8');
81
+ if (content.includes('module.exports') || content.includes('exports.')) {
82
+ return `var module = {exports:{}}; var exports = module.exports;\n${content}\nexport default module.exports;`;
83
+ }
84
+ }
85
+ return null;
86
+ }
87
+ }, {
88
+ name: 'system-to-app-require',
89
+ enforce: 'pre',
90
+ transform(code, id) {
91
+ if (!/@(system|service|android|hap)\.|@app-module\//.test(code)) return null;
92
+ const NS = '(system|service|android|hap)';
93
+ let t = code;
94
+ t = t.replace(new RegExp(`import\\s+(\\w+)\\s+from\\s+['"]@${NS}\\.([^'"]+)['"]\\s*;?`, 'g'), 'const $1 = $app_require$("@app-module/$2.$3");');
95
+ t = t.replace(new RegExp(`import\\s+\\{([^}]+)\\}\\s+from\\s+['"]@${NS}\\.([^'"]+)['"]\\s*;?`, 'g'), 'const {$1} = $app_require$("@app-module/$2.$3");');
96
+ t = t.replace(/import\s+(\w+)\s+from\s+['"]@app-module\/([^'"]+)['"]\s*;?/g, 'const $1 = $app_require$("@app-module/$2");');
97
+ t = t.replace(/import\s+\{([^}]+)\}\s+from\s+['"]@app-module\/([^'"]+)['"]\s*;?/g, 'const {$1} = $app_require$("@app-module/$2");');
98
+ t = t.replace(/import\s+['"]@app-module\/([^'"]+)['"]\s*;?/g, '$app_require$("@app-module/$1");');
99
+ t = t.replace(new RegExp(`import\\s+['"]@${NS}\\.([^'"]+)['"]\\s*;?`, 'g'), '$app_require$("@app-module/$1.$2");');
100
+ return t !== code ? {
101
+ code: t,
102
+ map: null
103
+ } : null;
104
+ }
105
+ }, {
106
+ name: 'ux-loader',
107
+ resolveId(source, importer) {
108
+ if (source.endsWith('.ux')) {
109
+ return importer ? _path.default.resolve(_path.default.dirname(importer), source) : source;
110
+ }
111
+ },
112
+ async load(id) {
113
+ if (!id.endsWith('.ux')) return null;
114
+ const content = _fsExtra.default.readFileSync(id, 'utf-8');
115
+ const isApp = id.endsWith('/app.ux') && _path.default.basename(_path.default.dirname(id)) === 'src';
116
+ // Generate template.json and css.json
117
+ if (id === resolvedEntry) {
118
+ const parse5 = require("aiot-parse5");
119
+ const doc = parse5.parseFragment(content, {
120
+ scriptingEnabled: false
121
+ });
122
+ let templateNode = null;
123
+ const importMap = {}; // name -> path
124
+ for (const node of doc.childNodes) {
125
+ if (node.nodeName === 'template') templateNode = node;else if (node.nodeName === 'import') {
126
+ const nameAttr = node.attrs?.find(a => a.name === 'name');
127
+ const srcAttr = node.attrs?.find(a => a.name === 'src');
128
+ if (nameAttr && srcAttr) {
129
+ const compAbsPath = _path.default.resolve(_path.default.dirname(resolvedEntry), srcAttr.value).replace(/\.ux$/, '');
130
+ const compPath = _path.default.relative(srcPath, compAbsPath).replace(/\\/g, '/');
131
+ importMap[nameAttr.value.toLowerCase()] = compPath;
132
+ }
133
+ }
134
+ }
135
+ const pageName = _path.default.relative(srcPath, id).replace(/\.ux$/, '');
136
+ // Compute styleObjectId
137
+ const sid = (0, _TemplateCompiler.getStyleObjectId)(entryName);
138
+ // Get style data from UxLoaderUtils compilation (handles LESS/CSS)
139
+ const {
140
+ files: compFiles
141
+ } = await _UxLoaderUtils.default.compileUxToJavascript({
142
+ path: id,
143
+ content
144
+ }, {
145
+ projectPath: originalProjectPath,
146
+ sourceRoot
147
+ }, isApp, param, compilation);
148
+ const compiledCode = compFiles[0]?.content || '';
149
+ // Extract $app_style$ array from compiled code
150
+ let styleSheet = {};
151
+ const styleMatch = compiledCode.match(/var \$app_style\$ = (\[[\s\S]*?\]);?\s*(?:import|export|var |const |$)/);
152
+ if (styleMatch) {
153
+ if (styleMatch) {
154
+ styleSheet = (0, _TemplateCompiler.parseStyleArray)(styleMatch[1]);
155
+ }
156
+ }
157
+ // Write css.json
158
+ const cssPath = _path.default.join(buildPath, `${isApp ? 'app' : pageName}.css.json`);
159
+ _fsExtra.default.ensureDirSync(_path.default.dirname(cssPath));
160
+ _fsExtra.default.writeJSONSync(cssPath, Object.keys(styleSheet).length ? {
161
+ [String(sid)]: styleSheet
162
+ } : {}, param.mode === 'production' ? undefined : {
163
+ spaces: 2
164
+ });
165
+ // Write template.json (with style inlining)
166
+ if (templateNode && !isApp) {
167
+ const tplPath = _path.default.join(buildPath, `${pageName}.template.json`);
168
+ _fsExtra.default.ensureDirSync(_path.default.dirname(tplPath));
169
+ _fsExtra.default.writeJSONSync(tplPath, (0, _TemplateCompiler.uxToTemplateJson)(templateNode, sid, styleSheet, importMap, _path.default.dirname(pageName)), param.mode === 'production' ? undefined : {
170
+ spaces: 2
171
+ });
172
+ // Worklist BFS over nested <import> chain so transitively imported
173
+ // components (entry → compA → compB → compC) also get template.json
174
+ const worklist = [];
175
+ const visited = new Set();
176
+ for (const [compName, compPath] of Object.entries(importMap)) {
177
+ const compUxPath = _path.default.resolve(_path.default.dirname(id), `../../${compPath}.ux`);
178
+ worklist.push({
179
+ compName,
180
+ compPath,
181
+ compUxPath
182
+ });
183
+ }
184
+ while (worklist.length) {
185
+ const {
186
+ compName,
187
+ compPath,
188
+ compUxPath
189
+ } = worklist.shift();
190
+ if (visited.has(compPath)) continue;
191
+ visited.add(compPath);
192
+ if (!_fsExtra.default.existsSync(compUxPath)) continue;
193
+ const compContent = _fsExtra.default.readFileSync(compUxPath, 'utf-8');
194
+ const compDoc = parse5.parseFragment(compContent, {
195
+ scriptingEnabled: false
196
+ });
197
+ let compTpl = null;
198
+ const compImportMap = {};
199
+ for (const node of compDoc.childNodes) {
200
+ if (node.nodeName === 'template') compTpl = node;else if (node.nodeName === 'import') {
201
+ const n = node.attrs?.find(a => a.name === 'name');
202
+ const s = node.attrs?.find(a => a.name === 'src');
203
+ if (n && s) {
204
+ const nestedAbsPath = _path.default.resolve(_path.default.dirname(compUxPath), s.value).replace(/\.ux$/, '');
205
+ const nestedPath = _path.default.relative(srcPath, nestedAbsPath).replace(/\\/g, '/');
206
+ compImportMap[n.value.toLowerCase()] = nestedPath;
207
+ if (!visited.has(nestedPath)) {
208
+ worklist.push({
209
+ compName: n.value.toLowerCase(),
210
+ compPath: nestedPath,
211
+ compUxPath: _path.default.resolve(_path.default.dirname(compUxPath), s.value)
212
+ });
213
+ }
214
+ }
215
+ }
216
+ }
217
+ if (!compTpl) continue;
218
+ const compTplPath = _path.default.join(buildPath, `${compPath}.template.json`);
219
+ _fsExtra.default.ensureDirSync(_path.default.dirname(compTplPath));
220
+ const compResult = await _UxLoaderUtils.default.compileUxToJavascript({
221
+ path: compUxPath,
222
+ content: compContent
223
+ }, {
224
+ projectPath: originalProjectPath,
225
+ sourceRoot
226
+ }, false, param, compilation);
227
+ let compStyleSheet = {};
228
+ const compCode = compResult.files[0]?.content || '';
229
+ const csm = compCode.match(/var \$app_style\$ = (\[[\s\S]*?\]);?\s*(?:import|export|var |const |$)/);
230
+ if (csm) {
231
+ compStyleSheet = (0, _TemplateCompiler.parseStyleArray)(csm[1]);
232
+ }
233
+ const compSid = (0, _TemplateCompiler.getStyleObjectId)(compPath);
234
+ _fsExtra.default.writeJSONSync(compTplPath, (0, _TemplateCompiler.uxToTemplateJson)(compTpl, compSid, compStyleSheet, compImportMap, _path.default.dirname(compPath)), param.mode === 'production' ? undefined : {
235
+ spaces: 2
236
+ });
237
+ const compCssPath = _path.default.join(buildPath, `${compPath}.css.json`);
238
+ _fsExtra.default.writeJSONSync(compCssPath, Object.keys(compStyleSheet).length ? {
239
+ [String(compSid)]: compStyleSheet
240
+ } : {}, param.mode === 'production' ? undefined : {
241
+ spaces: 2
242
+ });
243
+ const compJsPath = _path.default.join(buildPath, `${compPath}.js`);
244
+ const exportMatch = compCode.match(/export\s+default\s+([\s\S]*?);?\s*$/);
245
+ const compObj = exportMatch ? exportMatch[1].trim() : '{}';
246
+ const compVarName = compName.replace(/-/g, '_') + '_default';
247
+ const compJsContent = `let $style$${compSid} = {"@info":{"styleObjectId":${compSid}}};\nconst $app_style$${compSid} = $style$${compSid};\nvar ${compVarName} = ${compObj};\n$app_define$("@app-component/${compName}", [], function($app_require$, $app_exports$, $app_module$) {\n $app_module$.exports = ${compVarName}.default || ${compVarName};\n $app_module$.exports.style = $app_style$${compSid};\n});\n`;
248
+ _fsExtra.default.writeFileSync(compJsPath, compJsContent);
249
+ }
250
+ }
251
+ }
252
+ const {
253
+ files
254
+ } = await _UxLoaderUtils.default.compileUxToJavascript({
255
+ path: id,
256
+ content
257
+ }, {
258
+ projectPath: originalProjectPath,
259
+ sourceRoot
260
+ }, isApp, param, compilation);
261
+ return files[0]?.content || '';
262
+ }
263
+ }]
264
+ });
265
+ // Extract the output code
266
+ if (result && !Array.isArray(result)) {
267
+ const output = result.output;
268
+ if (output?.[0]?.code) {
269
+ const code = wrapOutput(output[0].code, entryName, entryName === 'app');
270
+ _fsExtra.default.writeFileSync(outputFile, code);
271
+ }
272
+ } else if (Array.isArray(result) && result[0]) {
273
+ const output = result[0].output;
274
+ if (output?.[0]?.code) {
275
+ const code = wrapOutput(output[0].code, entryName, entryName === 'app');
276
+ _fsExtra.default.writeFileSync(outputFile, code);
277
+ }
278
+ }
279
+ } catch (err) {
280
+ console.warn(`vite: failed to build ${entryName}:`, err.message);
281
+ }
282
+ }
283
+ // Second pass: compile ALL .ux files that weren't entry pages
284
+ // Each .ux file gets its own template.json + css.json + js
285
+ const allUxFiles = [];
286
+ const findUx = dir => {
287
+ for (const f of _fsExtra.default.readdirSync(dir, {
288
+ withFileTypes: true
289
+ })) {
290
+ const p = _path.default.join(dir, f.name);
291
+ if (f.isDirectory() && f.name !== 'node_modules') findUx(p);else if (f.name.endsWith('.ux')) allUxFiles.push(p);
292
+ }
293
+ };
294
+ findUx(srcPath);
295
+ const compiledEntries = new Set(Object.values(entries).map(v => _path.default.resolve(originalProjectPath, v.split('?')[0])));
296
+ for (const uxFile of allUxFiles) {
297
+ if (compiledEntries.has(uxFile)) continue; // already compiled as entry
298
+ if (uxFile.endsWith('/app.ux')) continue; // app.ux handled separately
299
+ const relPath = _path.default.relative(srcPath, uxFile).replace(/\.ux$/, '');
300
+ const outputJs = _path.default.join(buildPath, `${relPath}.js`);
301
+ const outputTpl = _path.default.join(buildPath, `${relPath}.template.json`);
302
+ const outputCss = _path.default.join(buildPath, `${relPath}.css.json`);
303
+ if (_fsExtra.default.existsSync(outputTpl)) continue; // already generated by parent page
304
+ const content = _fsExtra.default.readFileSync(uxFile, 'utf-8');
305
+ const parse5 = require("aiot-parse5");
306
+ const doc = parse5.parseFragment(content, {
307
+ scriptingEnabled: false
308
+ });
309
+ let templateNode = null;
310
+ const importMap = {};
311
+ for (const node of doc.childNodes) {
312
+ if (node.nodeName === 'template') templateNode = node;else if (node.nodeName === 'import') {
313
+ const nameAttr = node.attrs?.find(a => a.name === 'name');
314
+ const srcAttr = node.attrs?.find(a => a.name === 'src');
315
+ if (nameAttr && srcAttr) {
316
+ const compPath = _path.default.resolve(_path.default.dirname(uxFile), srcAttr.value).replace(/\.ux$/, '');
317
+ importMap[nameAttr.value.toLowerCase()] = _path.default.relative(srcPath, compPath).replace(/\\/g, '/');
318
+ }
319
+ }
320
+ }
321
+ // Compute styleObjectId
322
+ const sid = (0, _TemplateCompiler.getStyleObjectId)(relPath);
323
+ // Compile with UxLoaderUtils to get style data and script
324
+ const compilation = {
325
+ entries: [uxFile]
326
+ };
327
+ try {
328
+ const {
329
+ files
330
+ } = await _UxLoaderUtils.default.compileUxToJavascript({
331
+ path: uxFile,
332
+ content
333
+ }, {
334
+ projectPath: originalProjectPath,
335
+ sourceRoot
336
+ }, false, param, compilation);
337
+ const compCode = files[0]?.content || '';
338
+ // Extract style
339
+ let styleSheet = {};
340
+ const csm = compCode.match(/var \$app_style\$ = (\[[\s\S]*?\]);?\s*(?:import|export|var |const |$)/);
341
+ if (csm) {
342
+ styleSheet = (0, _TemplateCompiler.parseStyleArray)(csm[1]);
343
+ }
344
+ // Generate template.json
345
+ if (templateNode) {
346
+ _fsExtra.default.ensureDirSync(_path.default.dirname(outputTpl));
347
+ _fsExtra.default.writeJSONSync(outputTpl, (0, _TemplateCompiler.uxToTemplateJson)(templateNode, sid, styleSheet, Object.keys(importMap).length ? importMap : undefined, _path.default.dirname(relPath)), param.mode === 'production' ? undefined : {
348
+ spaces: 2
349
+ });
350
+ }
351
+ // Generate css.json
352
+ _fsExtra.default.ensureDirSync(_path.default.dirname(outputCss));
353
+ _fsExtra.default.writeJSONSync(outputCss, Object.keys(styleSheet).length ? {
354
+ [String(sid)]: styleSheet
355
+ } : {}, param.mode === 'production' ? undefined : {
356
+ spaces: 2
357
+ });
358
+ // Generate js
359
+ const exportMatch = compCode.match(/export\s+default\s+([\s\S]*?);?\s*$/);
360
+ const compObj = exportMatch ? exportMatch[1].trim() : '{}';
361
+ const compName = _path.default.basename(relPath).toLowerCase();
362
+ const varName = compName.replace(/-/g, '_') + '_default';
363
+ _fsExtra.default.ensureDirSync(_path.default.dirname(outputJs));
364
+ _fsExtra.default.writeFileSync(outputJs, `let $style$${sid} = {"@info":{"styleObjectId":${sid}}};\nconst $app_style$${sid} = $style$${sid};\nvar ${varName} = ${compObj};\n$app_define$("@app-component/${compName}", [], function($app_require$, $app_exports$, $app_module$) {\n $app_module$.exports = ${varName}.default || ${varName};\n $app_module$.exports.style = $app_style$${sid};\n});\n`);
365
+ } catch {}
366
+ }
367
+ }
368
+ async clean(param) {
369
+ const {
370
+ outputPath,
371
+ releasePath,
372
+ projectPath
373
+ } = param;
374
+ _UxCompileUtil.default.clean([outputPath, releasePath].map(item => _path.default.resolve(projectPath, item)));
375
+ }
376
+ }
377
+ function wrapOutput(code, entryName, isApp) {
378
+ const componentName = _path.default.parse(entryName).name;
379
+ const defineId = isApp ? '@app-component/app' : `@app-component/${componentName}`;
380
+ const bootstrapId = isApp ? '@app-application/app' : `@app-component/${componentName}`;
381
+ // Remove IIFE wrapper: var _page_ = (function(...) { ... return xxx; })(...);
382
+ // Only remove the FIRST line and the LAST return+closing
383
+ if (code.startsWith('var _page_')) {
384
+ // Remove first line (the IIFE opening)
385
+ const firstNewline = code.indexOf('\n');
386
+ code = code.slice(firstNewline + 1);
387
+ // Remove the last return statement and closing })();
388
+ const lastReturn = code.lastIndexOf('\treturn ');
389
+ if (lastReturn !== -1) {
390
+ const afterReturn = code.indexOf('\n', lastReturn);
391
+ code = code.slice(0, lastReturn) + code.slice(afterReturn + 1);
392
+ }
393
+ // Remove the closing })(); or })(...)
394
+ const lastClose = code.lastIndexOf('})();');
395
+ if (lastClose !== -1) {
396
+ code = code.slice(0, lastClose);
397
+ } else {
398
+ const lastClose2 = code.lastIndexOf('})(');
399
+ if (lastClose2 !== -1) {
400
+ code = code.slice(0, lastClose2);
401
+ }
402
+ }
403
+ }
404
+ // Remove rolldown region comments
405
+ code = code.replace(/\/\/#region[^\n]*\n/g, '');
406
+ code = code.replace(/\/\/#endregion[^\n]*/g, '');
407
+ // Remove rolldown runtime helpers (not needed in final output)
408
+ code = code.replace(/var __defProp = Object\.defineProperty;\n?/g, '');
409
+ code = code.replace(/var __exportAll = [\s\S]*?return target;\s*\};\n?/g, '');
410
+ // Inline __exportAll calls: __exportAll({key: () => value, ...}) -> {key: value, ...}
411
+ // Match __exportAll(...) or /* @__PURE__ */ __exportAll(...)
412
+ code = code.replace(/(?:\/\* @__PURE__ \*\/\s*)?__exportAll\(\s*\{([\s\S]*?)\}\s*\)/g, (_match, body) => {
413
+ // Replace each "key: () => value" with "get key() { return value }" for proper live binding
414
+ const inlined = body.replace(/(\w+)\s*:\s*\(\)\s*=>\s*([^,\n}]+?)([,\n])/g, 'get $1() { return $2; }$3');
415
+ return `{${inlined}}`;
416
+ });
417
+ // Remove Object.defineProperty for Symbol.toStringTag
418
+ code = code.replace(/\s*Object\.defineProperty\(\w+,\s*Symbol\.toStringTag[^;]*;\s*/g, '');
419
+ // Extract the default export variable
420
+ let exportVar = '_default';
421
+ const m1 = code.match(/export\s*\{\s*(\w+)\s+as\s+default\s*\}/);
422
+ if (m1) {
423
+ exportVar = m1[1];
424
+ code = code.replace(m1[0], '');
425
+ }
426
+ code = code.replace(/export\s+default\s+(\w+)\s*;?/g, (_, v) => {
427
+ exportVar = v;
428
+ return '';
429
+ });
430
+ code = code.replace(/export\s+\{[^}]*\}\s*;?/g, '');
431
+ // Find the return statement variable (IIFE returns the component)
432
+ const returnMatch = code.match(/return\s+(\w+)\s*;?\s*$/);
433
+ if (returnMatch) {
434
+ exportVar = returnMatch[1];
435
+ code = code.replace(returnMatch[0], '');
436
+ }
437
+ // Generate styleObjectId hash
438
+ const styleId = (0, _TemplateCompiler.getStyleObjectId)(entryName);
439
+ return `let $style$${styleId} = {"@info":{"styleObjectId":${styleId}}};
440
+ const $app_style$${styleId} = $style$${styleId};
441
+ ${code.trim()}
442
+ $app_define$("${defineId}", [], function($app_require$, $app_exports$, $app_module$) {
443
+ $app_module$.exports = ${exportVar}.default || ${exportVar};
444
+ $app_module$.exports.style = $app_style$${styleId};
445
+ });
446
+ $app_bootstrap$("${bootstrapId}");
447
+ `;
448
+ }
449
+ var _default = exports.default = ViteCompiler;
@@ -40,6 +40,10 @@ interface IJavascriptCompileOption extends ICompileParam {
40
40
  * 禁用 jsc
41
41
  */
42
42
  enableJsc?: boolean;
43
+ /**
44
+ * 启用 VRU 包装格式(release 模式生成 manifest+CERT+inner-vru 的双层 RPK)
45
+ */
46
+ enableVru?: boolean;
43
47
  /**
44
48
  * 启用 protobuf
45
49
  */
@@ -48,6 +52,11 @@ interface IJavascriptCompileOption extends ICompileParam {
48
52
  * 启用应用自动化测试
49
53
  */
50
54
  enableE2e?: boolean;
55
+ /**
56
+ * 自动化测试配置文件路径
57
+ *
58
+ */
59
+ e2eConfigPath?: string;
51
60
  /**
52
61
  * 启用 png8 压缩
53
62
  */
@@ -8,7 +8,9 @@ declare class VelaWebpackConfigurator implements IWebpackConfigurator {
8
8
  protected createWrapPlugin(): RspackPluginInstance;
9
9
  protected createBundleAnalyzerPlugin(): any;
10
10
  /**
11
- * 通过读取 manifest.json 生成 entry
11
+ * 生成entry
12
+ * 1. 通过读取 manifest.json 生成 entry
13
+ * 2. 通过自动化测试的entry配置生成entry
12
14
  * @returns
13
15
  */
14
16
  createEntry(): string | EntryObject | string[];
@@ -9,6 +9,7 @@ var _path = _interopRequireDefault(require("path"));
9
9
  var _UxFileUtils = _interopRequireDefault(require("../../../utils/ux/UxFileUtils"));
10
10
  var _WrapPlugin = _interopRequireDefault(require("./plugin/WrapPlugin"));
11
11
  var _UxCompileUtil = _interopRequireDefault(require("./utils/UxCompileUtil"));
12
+ var _UxUtil = _interopRequireDefault(require("@aiot-toolkit/parser/lib/ux/utils/UxUtil"));
12
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
14
  class VelaWebpackConfigurator {
14
15
  createPlugins() {
@@ -34,7 +35,9 @@ class VelaWebpackConfigurator {
34
35
  }
35
36
 
36
37
  /**
37
- * 通过读取 manifest.json 生成 entry
38
+ * 生成entry
39
+ * 1. 通过读取 manifest.json 生成 entry
40
+ * 2. 通过自动化测试的entry配置生成entry
38
41
  * @returns
39
42
  */
40
43
  createEntry() {
@@ -44,7 +47,19 @@ class VelaWebpackConfigurator {
44
47
  } = this.param;
45
48
  const configFilePath = _UxFileUtils.default.getManifestFilePath(this.param.projectPath, this.param.sourceRoot);
46
49
  if (_fsExtra.default.existsSync(configFilePath)) {
50
+ // 1
47
51
  const config = _fsExtra.default.readJSONSync(configFilePath);
52
+ // 2
53
+ if (this.param.e2eConfigPath && this.param.enableE2e) {
54
+ const e2eConfig = _UxUtil.default.getE2eConfig({
55
+ projectPath: this.param.projectPath,
56
+ e2eConfigPath: this.param.e2eConfigPath
57
+ });
58
+ const testPagePath = _path.default.parse(_path.default.relative(_path.default.join(this.param.projectPath, sourceRoot), _path.default.join(e2eConfig.dir, e2eConfig.entry.path)).replaceAll(_path.default.sep, _path.default.posix.sep));
59
+ config.router.pages[testPagePath.dir] = {
60
+ component: testPagePath.name
61
+ };
62
+ }
48
63
  return _UxCompileUtil.default.resolveEntries(config, _path.default.resolve(projectPath, sourceRoot), projectPath);
49
64
  } else {
50
65
  throw new Error(`Configuration file does not exist: ${configFilePath}`);
@@ -8,6 +8,10 @@ interface IWidget {
8
8
  sizes: string[];
9
9
  type?: string;
10
10
  }
11
+ interface IWidgetProvider {
12
+ name: string;
13
+ path: string;
14
+ }
11
15
  /**
12
16
  * vela manifest文件对应的数据结构
13
17
  */
@@ -29,12 +33,20 @@ export default interface IManifest {
29
33
  entry: string;
30
34
  pages: Dictionary<{
31
35
  component?: string;
36
+ launchMode?: string;
32
37
  }>;
38
+ floatingWindows?: any;
33
39
  };
34
40
  services: IService[] | Record<string, IService>;
35
41
  minAPILevel?: number;
36
42
  packageInfo?: Dictionary<string | number>;
43
+ widgetProvider?: IWidgetProvider[];
37
44
  icon: string;
45
+ workers?: {
46
+ entries: {
47
+ file: string;
48
+ }[];
49
+ };
38
50
  }
39
51
  export interface IFeatures {
40
52
  name: string;
@@ -4,7 +4,16 @@ declare class WrapPlugin {
4
4
  private compilerOption;
5
5
  constructor(compilerOption: IJavascriptCompileOption);
6
6
  apply(compiler: Compiler): void;
7
+ private getComponentName;
8
+ private findMatching;
9
+ /**
10
+ * Extract keyed modules from rspack's __webpack_modules__ object
11
+ */
12
+ private extractModules;
13
+ /**
14
+ * Clean a module body into blueos-pack format component block
15
+ */
16
+ private buildBlock;
7
17
  private wrap;
8
- private translateStyleFunc;
9
18
  }
10
19
  export default WrapPlugin;