@aiot-toolkit/aiotpack 2.1.0-prender.17 → 2.1.0-prender.18

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.
@@ -32,7 +32,21 @@ class UxAfterCompile {
32
32
  compilerOption,
33
33
  onLog
34
34
  } = params;
35
- return new _ViteCompiler.default(context, onLog).compile({
35
+ // The legacy format needs the rspack pipeline: its page JS carries the template
36
+ // and style inline (`$app_template$`/`$app_style$`) instead of the separate
37
+ // template.json/css.json the Vite pipeline emits. Required lazily so a
38
+ // default build never loads rspack's native binding (~180ms, ~47MB RSS), and
39
+ // so rspack only has to be installed by projects that ask for this format.
40
+ let Compiler = _ViteCompiler.default;
41
+ if (compilerOption?.legacy) {
42
+ try {
43
+ Compiler = require('../../compiler/javascript/JavascriptCompiler').default;
44
+ } catch (e) {
45
+ if (!/@rspack\/core/.test(e?.message ?? '')) throw e;
46
+ throw new Error(`--legacy needs @rspack/core, which is not installed. ` + `Run \`npm i @rspack/core\`, or drop --legacy to build the default format.`);
47
+ }
48
+ }
49
+ return new Compiler(context, onLog).compile({
36
50
  projectPath: _path.default.join(context.projectPath, context.output),
37
51
  mode: _CompileMode.default.DEVELOPMENT,
38
52
  devtool: false,
@@ -101,9 +115,9 @@ class UxAfterCompile {
101
115
  } = params;
102
116
  if (compilerOption) {
103
117
  const buildPath = _path.default.join(context.projectPath, context.output, compilerOption.outputPath);
104
- _Jsc.default.wrapAllJsWithIife(buildPath);
118
+ _Jsc.default.wrapAllJsWithIife(buildPath, compilerOption.legacy);
105
119
  if (compilerOption.enableJsc === true) {
106
- return new _Jsc.default(context.projectPath, buildPath).jsc();
120
+ return new _Jsc.default(context.projectPath, buildPath, compilerOption.legacy).jsc();
107
121
  }
108
122
  }
109
123
  };
@@ -353,6 +367,9 @@ class UxAfterCompile {
353
367
  onLog
354
368
  } = params;
355
369
  if (!compilerOption) return;
370
+ // Moving the icon to the build root is part of the new format; the legacy
371
+ // format keeps it where manifest.icon points.
372
+ if (compilerOption.legacy) return;
356
373
  const {
357
374
  projectPath,
358
375
  outputPath
@@ -135,13 +135,18 @@ class JavascriptCompiler {
135
135
  let result = {
136
136
  context: projectPath,
137
137
  mode,
138
- devtool: devtool || false,
138
+ // `devtool: 'none'` is the webpack 4 spelling for "no source map" and still
139
+ // appears in project configs; rspack rejects it, so normalize to false.
140
+ devtool: (devtool === 'none' ? false : devtool) || false,
139
141
  output: {
140
142
  globalObject: 'global',
141
143
  filename: '[name].js',
142
144
  publicPath: './',
143
145
  path: buildPath,
144
- iife: false,
146
+ // The legacy wrapper emits `return <bundle>`, so the bundle has to be an
147
+ // expression. Without this rspack emits a bare `var __webpack_exports__ = {}`
148
+ // statement and the wrapper becomes `return var ...`, a syntax error.
149
+ iife: Boolean(param.legacy),
145
150
  library: {
146
151
  type: 'commonjs2'
147
152
  }
@@ -19,6 +19,14 @@ declare function resolveImportSrc(fromUxFile: string, src: string): string | nul
19
19
  * can open.
20
20
  */
21
21
  declare function collectReachableUx(entryUxFiles: string[]): Set<string>;
22
+ /**
23
+ * The e2e test entry `.ux` that `--enable-e2e` turns into `router.entry`.
24
+ *
25
+ * It is absent from the source manifest — UxAfterCompile registers it only
26
+ * after compilation — so route-based reachability cannot see it and would skip
27
+ * it, leaving `router.entry` pointing at a page the package does not contain.
28
+ */
29
+ declare function resolveE2eEntryUx(param: IJavascriptCompileOption, originalProjectPath: string): string | null;
22
30
  /**
23
31
  * Relative ESM imports a sub-component declares that nothing downstream can
24
32
  * resolve: `.ux` imports are loader-generated and dropped later, and
@@ -116,5 +124,6 @@ export declare const __test: {
116
124
  hoistNamespaceObjects: typeof hoistNamespaceObjects;
117
125
  assertNamespaceObjectsInlined: typeof assertNamespaceObjectsInlined;
118
126
  assertNoEagerForwardRead: typeof assertNoEagerForwardRead;
127
+ resolveE2eEntryUx: typeof resolveE2eEntryUx;
119
128
  };
120
129
  export default ViteCompiler;
@@ -267,6 +267,27 @@ function collectReachableUx(entryUxFiles) {
267
267
  }
268
268
  return reachable;
269
269
  }
270
+
271
+ /**
272
+ * The e2e test entry `.ux` that `--enable-e2e` turns into `router.entry`.
273
+ *
274
+ * It is absent from the source manifest — UxAfterCompile registers it only
275
+ * after compilation — so route-based reachability cannot see it and would skip
276
+ * it, leaving `router.entry` pointing at a page the package does not contain.
277
+ */
278
+ function resolveE2eEntryUx(param, originalProjectPath) {
279
+ if (!param.enableE2e || !param.e2eConfigPath) return null;
280
+ try {
281
+ const UxUtil = require('@aiot-toolkit/parser/lib/ux/utils/UxUtil').default;
282
+ const cfg = UxUtil.getE2eConfig({
283
+ projectPath: originalProjectPath,
284
+ e2eConfigPath: param.e2eConfigPath
285
+ });
286
+ return _path.default.resolve(cfg.dir, `${cfg.entry.path}.ux`);
287
+ } catch {
288
+ return null;
289
+ }
290
+ }
270
291
  function extractAppStyleLiteral(code) {
271
292
  const m = code.match(/var\s+\$app_style\$\s*=\s*\[/);
272
293
  if (!m) return null;
@@ -755,7 +776,8 @@ class ViteCompiler {
755
776
  };
756
777
  findUx(srcPath);
757
778
  const compiledEntries = new Set(Object.values(entries).map(v => _path.default.resolve(originalProjectPath, v.split('?')[0])));
758
- const reachableUx = collectReachableUx([...compiledEntries]);
779
+ const e2eEntryUx = resolveE2eEntryUx(param, originalProjectPath);
780
+ const reachableUx = collectReachableUx([...compiledEntries, ...(e2eEntryUx ? [e2eEntryUx] : [])]);
759
781
  const skippedUx = [];
760
782
  for (const uxFile of allUxFiles) {
761
783
  if (compiledEntries.has(uxFile)) continue; // already compiled as entry
@@ -838,6 +860,12 @@ class ViteCompiler {
838
860
  console.warn(`vite: failed to emit component ${relPath}:`, e?.message ?? e);
839
861
  }
840
862
  }
863
+ if (e2eEntryUx) {
864
+ const e2eOutJs = _path.default.join(buildPath, `${_path.default.relative(srcPath, e2eEntryUx).replace(/\.ux$/, '')}.js`);
865
+ if (!_fsExtra.default.existsSync(e2eOutJs)) {
866
+ throw new Error(`[e2e] --enable-e2e makes ${_path.default.relative(originalProjectPath, e2eEntryUx)} the app entry, ` + `but it produced no output at ${_path.default.relative(buildPath, e2eOutJs)}. ` + `Check that the entry path in ${param.e2eConfigPath} resolves to a .ux under the source root.`);
867
+ }
868
+ }
841
869
  if (skippedUx.length) {
842
870
  this.onLog?.([{
843
871
  level: 3,
@@ -1260,6 +1288,7 @@ const __test = exports.__test = {
1260
1288
  stripRolldownArtifacts,
1261
1289
  hoistNamespaceObjects,
1262
1290
  assertNamespaceObjectsInlined,
1263
- assertNoEagerForwardRead
1291
+ assertNoEagerForwardRead,
1292
+ resolveE2eEntryUx
1264
1293
  };
1265
1294
  var _default = exports.default = ViteCompiler;
@@ -44,6 +44,10 @@ interface IJavascriptCompileOption extends ICompileParam {
44
44
  * 启用 VRU 包装格式(release 模式生成 manifest+CERT+inner-vru 的双层 RPK)
45
45
  */
46
46
  enableVru?: boolean;
47
+ /**
48
+ * 输出旧包格式:模板与样式内联进 webpack 打包的 JS,不生成 template.json / css.json
49
+ */
50
+ legacy?: boolean;
47
51
  /**
48
52
  * 启用 protobuf
49
53
  */
@@ -14,6 +14,13 @@ declare class WrapPlugin {
14
14
  * Clean a module body into blueos-pack format component block
15
15
  */
16
16
  private buildBlock;
17
+ /**
18
+ * The legacy entry wrapper: a plain IIFE that hands the runtime globals to the
19
+ * bundle. It performs no rewriting of the bundle body, so the inlined
20
+ * `$app_template$`/`$app_style$` and the `module.exports` the page script relies
21
+ * on survive — which is exactly what the legacy format needs.
22
+ */
23
+ private wrapLegacy;
17
24
  private wrap;
18
25
  }
19
26
  export default WrapPlugin;
@@ -178,7 +178,47 @@ class WrapPlugin {
178
178
  const lines = [`let $style$${styleId} = {"@info":{"styleObjectId":${styleId}}};`, `const $app_style$${styleId} = $style$${styleId};`, ...(s.trim() ? [s.trim()] : []), ...(templateCode ? [templateCode] : []), `const $app_script$${styleId} = ${obj};`, `$app_define$("${defineId}", [], function($app_require$, $app_exports$, $app_module$) {`, ` $app_module$.exports = $app_script$${styleId}.default || $app_script$${styleId};`, ` $app_module$.exports.style = $app_style$${styleId};`, ...(templateCode ? [` $app_module$.exports.template = $app_template$;`] : []), `});`];
179
179
  return lines.join('\n');
180
180
  }
181
+ /**
182
+ * The legacy entry wrapper: a plain IIFE that hands the runtime globals to the
183
+ * bundle. It performs no rewriting of the bundle body, so the inlined
184
+ * `$app_template$`/`$app_style$` and the `module.exports` the page script relies
185
+ * on survive — which is exactly what the legacy format needs.
186
+ */
187
+ wrapLegacy(compilation) {
188
+ const {
189
+ enableE2e
190
+ } = this.compilerOption;
191
+ const entrys = Object.keys(compilation.options.entry).map(item => `${item}.js`);
192
+ entrys.forEach(entry => {
193
+ if (!compilation.assets[entry]) return;
194
+ const source = compilation.assets[entry];
195
+ const isApp = entry === 'app.js';
196
+ const createFuncnName = isApp ? 'createAppHandler' : 'createPageHandler';
197
+ compilation.assets[entry] = new _webpackSources.ConcatSource(`export default function(global, globalThis, window, $app_exports$, $app_evaluate$){
198
+ var org_app_require = $app_require$;
199
+
200
+ (function(global, globalThis, window, $app_exports$, $app_evaluate$){
201
+ var setTimeout = global.setTimeout;
202
+ var setInterval = global.setInterval;
203
+ var clearTimeout = global.clearTimeout;
204
+ var clearInterval = global.clearInterval;
205
+ var $app_require$ = global.$app_require$ || org_app_require
206
+
207
+ ${enableE2e ? `globalThis = undefined; \n global = typeof window === "undefined" ? global.__proto__ : window;` : ''}
208
+ var ${createFuncnName} = function() {
209
+ return `, source, `
210
+ }
211
+
212
+ return ${createFuncnName}();
213
+ })(global, globalThis, window, $app_exports$, $app_evaluate$)
214
+ }`);
215
+ });
216
+ }
181
217
  wrap(compilation) {
218
+ if (this.compilerOption.legacy) {
219
+ this.wrapLegacy(compilation);
220
+ return;
221
+ }
182
222
  const entrys = Object.keys(compilation.options.entry).map(item => `${item}.js`);
183
223
  entrys.forEach(entry => {
184
224
  if (!compilation.assets[entry]) return;
@@ -1,13 +1,17 @@
1
1
  declare class Jsc {
2
2
  readonly projectPath: string;
3
3
  readonly buildPath: string;
4
- constructor(projectPath: string, buildPath: string);
4
+ /** The legacy format carries its own entry wrapper from WrapPlugin. */
5
+ readonly legacy: boolean;
6
+ constructor(projectPath: string, buildPath: string,
7
+ /** The legacy format carries its own entry wrapper from WrapPlugin. */
8
+ legacy?: boolean);
5
9
  jsc(deleteJs?: boolean): Promise<boolean>;
6
10
  private logBeforeInvoke;
7
11
  private logAfterInvoke;
8
12
  private static listFiles;
9
13
  private assertJscVersion;
10
- static wrapAllJsWithIife(buildPath: string): void;
14
+ static wrapAllJsWithIife(buildPath: string, legacy?: boolean): void;
11
15
  private static assertLegacyGlobalBinding;
12
16
  private static compareSemver;
13
17
  }
@@ -9,7 +9,7 @@ var path = _interopRequireWildcard(require("path"));
9
9
  var _sharedUtils = require("@aiot-toolkit/shared-utils");
10
10
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
11
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
- const REQUIRED_JSC_VERSION = '1.0.9';
12
+ const REQUIRED_JSC_VERSION = '1.0.10';
13
13
 
14
14
  // `__ctx` is the page scope whose prototype is `ferryGlobal` (where the runtime
15
15
  // registers `runGC` and friends). A bare `global` in legacy page source resolves
@@ -28,8 +28,10 @@ const IIFE_WRAP_SUFFIX = '\n});\n';
28
28
  const JSC_ARGS = ['-s'];
29
29
  class Jsc {
30
30
  constructor(projectPath, buildPath) {
31
+ let legacy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
31
32
  this.projectPath = projectPath;
32
33
  this.buildPath = buildPath;
34
+ this.legacy = legacy;
33
35
  }
34
36
  jsc() {
35
37
  let deleteJs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
@@ -41,7 +43,7 @@ class Jsc {
41
43
  return _sharedUtils.CommonUtil.requireNodeModule(projectPath, `@aiot-toolkit/jsc`).then(async module => {
42
44
  this.logBeforeInvoke();
43
45
  this.assertJscVersion();
44
- Jsc.wrapAllJsWithIife(buildPath);
46
+ Jsc.wrapAllJsWithIife(buildPath, this.legacy);
45
47
  const start = Date.now();
46
48
  const msg = await module.default(buildPath, JSC_ARGS);
47
49
  const elapsed = Date.now() - start;
@@ -158,6 +160,10 @@ class Jsc {
158
160
  }
159
161
  }
160
162
  static wrapAllJsWithIife(buildPath) {
163
+ let legacy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
164
+ // The legacy format is already wrapped by WrapPlugin into the
165
+ // `export default function(global, globalThis, window, ...)` entry shape.
166
+ if (legacy) return;
161
167
  for (const {
162
168
  rel
163
169
  } of Jsc.listFiles(buildPath, '.js')) {
@@ -394,7 +394,11 @@ class ZipUtil {
394
394
  platform: process.platform,
395
395
  arch: process.arch,
396
396
  component: true,
397
- json: true
397
+ // Runtimes pick the package format from this marker: `json=true` selects the
398
+ // JSON-template pipeline, its absence the legacy one.
399
+ ...(param.legacy ? {} : {
400
+ json: true
401
+ })
398
402
  };
399
403
  return obj;
400
404
  }
@@ -120,7 +120,9 @@ class UxLoaderUtils {
120
120
  if (_fsExtra.default.existsSync(manifestPath)) {
121
121
  manifestContent = _fsExtra.default.readFileSync(manifestPath, 'utf-8').trim();
122
122
  }
123
- const manifestJson = `JSON.parse('${manifestContent.replace(/'/g, "\\'").replace(/\n/g, '')}')`;
123
+ // webpack resolves the require; rolldown cannot, so the Vite pipeline inlines
124
+ // the parsed content instead.
125
+ const manifestJson = compilerOption.legacy ? `require('./manifest.json')` : `JSON.parse('${manifestContent.replace(/'/g, "\\'").replace(/\n/g, '')}')`;
124
126
  function translateStyleFunc() {
125
127
  return `
126
128
  var $translateStyle$ = function (value) {
@@ -159,9 +161,15 @@ class UxLoaderUtils {
159
161
 
160
162
  // script代码放在第三个位置不能变化,影响更新source map
161
163
  const createAppWrapper = () => {
164
+ if (compilerOption.legacy) {
165
+ return [`${appImport.join('\n')}`, `var $app_style$ = ${UxLoaderUtils.wrapStyle(appStyleTree, file, compilerOption)}`, hasScript ? `var $app_script$ = ${UxLoaderUtils.wrapScript(false, appScriptTree)}` : '', hasScript ? `$app_script$({}, $app_exports$, $app_require$);` : `$app_exports$.default = {}`, `$app_exports$.default.style = $app_style$;`, `$app_exports$.default.manifest = ${manifestJson}`, translateStyleFunc()];
166
+ }
162
167
  return [`${appImport.join('\n')}`, `var $app_style$ = ${UxLoaderUtils.wrapStyle(appStyleTree, file, compilerOption)}`, hasScript ? appScriptTree.getFullText() : 'export default {};'];
163
168
  };
164
169
  const createComponentWrapper = () => {
170
+ if (compilerOption.legacy) {
171
+ return [`${appImport.join('\n')}`, `var $app_style$ = ${UxLoaderUtils.wrapStyle(appStyleTree, file, compilerOption)}`, hasScript ? `var $app_script$ = ${UxLoaderUtils.wrapScript(isPageUx, appScriptTree)}` : '', `var $app_template$ = ${UxLoaderUtils.wrapTempalte(appTemplateTree, file, compilerOption)}`, `${UxLoaderUtils.getReturnType(isPageUx)} function ($app_exports$) {`, hasScript ? `$app_script$({}, $app_exports$, $app_require$);` : `$app_exports$.default = {}`, `$app_exports$.default.template = $app_template$;`, `$app_exports$.default.style = $app_style$;`, `}`];
172
+ }
165
173
  return [`${appImport.join('\n')}`, `var $app_style$ = ${UxLoaderUtils.wrapStyle(appStyleTree, file, compilerOption)}`, hasScript ? appScriptTree.getFullText() : 'export default {};'];
166
174
  };
167
175
  if (isAppUx) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiot-toolkit/aiotpack",
3
- "version": "2.1.0-prender.17",
3
+ "version": "2.1.0-prender.18",
4
4
  "description": "The process tool for packaging aiot projects.",
5
5
  "keywords": [
6
6
  "aiotpack"
@@ -19,16 +19,15 @@
19
19
  "test": "node ./__tests__/aiotpack.test.js"
20
20
  },
21
21
  "dependencies": {
22
- "@aiot-toolkit/generator": "2.1.0-prender.17",
23
- "@aiot-toolkit/parser": "2.1.0-prender.17",
24
- "@aiot-toolkit/shared-utils": "2.1.0-prender.17",
22
+ "@aiot-toolkit/generator": "2.1.0-prender.18",
23
+ "@aiot-toolkit/parser": "2.1.0-prender.18",
24
+ "@aiot-toolkit/shared-utils": "2.1.0-prender.18",
25
25
  "@hap-toolkit/aaptjs": "^2.0.0",
26
- "@rspack/core": "^1.3.9",
27
26
  "acorn": "^8.16.0",
28
27
  "aiot-parse5": "^1.0.2",
29
28
  "astring": "^1.9.0",
30
29
  "babel-loader": "^9.1.3",
31
- "file-lane": "2.1.0-prender.17",
30
+ "file-lane": "2.1.0-prender.18",
32
31
  "file-loader": "^6.2.0",
33
32
  "fs-extra": "^11.2.0",
34
33
  "jsrsasign": "^11.1.0",
@@ -40,6 +39,14 @@
40
39
  "webpack-bundle-analyzer": "^4.10.2",
41
40
  "webpack-sources": "^3.2.3"
42
41
  },
42
+ "peerDependencies": {
43
+ "@rspack/core": "^1.3.9"
44
+ },
45
+ "peerDependenciesMeta": {
46
+ "@rspack/core": {
47
+ "optional": true
48
+ }
49
+ },
43
50
  "devDependencies": {
44
51
  "@types/fs-extra": "^11.0.4",
45
52
  "@types/jsrsasign": "^10.5.12",