@aiot-toolkit/aiotpack 2.0.6-beta.8 → 2.1.0-prender.1
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/lib/afterCompile/ux/UxAfterCompile.d.ts +4 -0
- package/lib/afterCompile/ux/UxAfterCompile.js +90 -2
- package/lib/compiler/javascript/JavascriptCompiler.js +11 -4
- package/lib/compiler/javascript/TemplateCompiler.d.ts +29 -0
- package/lib/compiler/javascript/TemplateCompiler.js +564 -0
- package/lib/compiler/javascript/ViteCompiler.d.ts +13 -0
- package/lib/compiler/javascript/ViteCompiler.js +414 -0
- package/lib/compiler/javascript/interface/IJavascriptCompileOption.d.ts +26 -0
- package/lib/compiler/javascript/vela/VelaWebpackConfigurator.d.ts +3 -1
- package/lib/compiler/javascript/vela/VelaWebpackConfigurator.js +16 -1
- package/lib/compiler/javascript/vela/interface/IManifest.d.ts +12 -0
- package/lib/compiler/javascript/vela/plugin/WrapPlugin.d.ts +10 -1
- package/lib/compiler/javascript/vela/plugin/WrapPlugin.js +241 -57
- package/lib/compiler/javascript/vela/utils/UxCompileUtil.d.ts +3 -2
- package/lib/compiler/javascript/vela/utils/UxCompileUtil.js +12 -4
- package/lib/compiler/javascript/vela/utils/VruUtil.d.ts +50 -0
- package/lib/compiler/javascript/vela/utils/VruUtil.js +128 -0
- package/lib/compiler/javascript/vela/utils/ZipUtil.d.ts +9 -0
- package/lib/compiler/javascript/vela/utils/ZipUtil.js +112 -6
- package/lib/compiler/javascript/vela/utils/webpackLoader/WebpackJsLoader.js +1 -1
- package/lib/config/UxConfig.d.ts +12 -5
- package/lib/config/UxConfig.js +7 -6
- package/lib/loader/ux/JsLoader.d.ts +9 -0
- package/lib/loader/ux/JsLoader.js +47 -8
- package/lib/loader/ux/vela/HmlLoader.d.ts +6 -6
- package/lib/loader/ux/vela/HmlLoader.js +30 -13
- package/lib/prerender/PrerenderVM.d.ts +86 -0
- package/lib/prerender/PrerenderVM.js +677 -0
- package/lib/prerender/StyleSerializer.d.ts +18 -0
- package/lib/prerender/StyleSerializer.js +92 -0
- package/lib/prerender/TemplateSerializer.d.ts +26 -0
- package/lib/prerender/TemplateSerializer.js +122 -0
- package/lib/prerender/index.d.ts +20 -0
- package/lib/prerender/index.js +519 -0
- package/lib/prerender/interface/IPrerenderOption.d.ts +15 -0
- package/lib/prerender/interface/IPrerenderOption.js +1 -0
- package/lib/utils/BeforeCompileUtils.d.ts +1 -1
- package/lib/utils/BeforeCompileUtils.js +52 -9
- package/lib/utils/ux/ManifestSchema.js +0 -1
- package/lib/utils/ux/UxFileUtils.js +1 -1
- package/lib/utils/ux/UxLoaderUtils.d.ts +6 -0
- package/lib/utils/ux/UxLoaderUtils.js +22 -10
- package/package.json +9 -6
|
@@ -0,0 +1,414 @@
|
|
|
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/') || id.startsWith('@system.'),
|
|
61
|
+
output: {
|
|
62
|
+
globals: id => `$app_require$("@app-module/${id.replace(/^@(system|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 (!code.includes('@system.')) return null;
|
|
92
|
+
let t = code;
|
|
93
|
+
t = t.replace(/import\s+(\w+)\s+from\s+['"]@system\.([^'"]+)['"]\s*;?/g, 'const $1 = $app_require$("@app-module/system.$2");');
|
|
94
|
+
t = t.replace(/import\s+\{([^}]+)\}\s+from\s+['"]@system\.([^'"]+)['"]\s*;?/g, 'const {$1} = $app_require$("@app-module/system.$2");');
|
|
95
|
+
return t !== code ? {
|
|
96
|
+
code: t,
|
|
97
|
+
map: null
|
|
98
|
+
} : null;
|
|
99
|
+
}
|
|
100
|
+
}, {
|
|
101
|
+
name: 'ux-loader',
|
|
102
|
+
resolveId(source, importer) {
|
|
103
|
+
if (source.endsWith('.ux')) {
|
|
104
|
+
return importer ? _path.default.resolve(_path.default.dirname(importer), source) : source;
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
async load(id) {
|
|
108
|
+
if (!id.endsWith('.ux')) return null;
|
|
109
|
+
const content = _fsExtra.default.readFileSync(id, 'utf-8');
|
|
110
|
+
const isApp = id.endsWith('/app.ux') && _path.default.basename(_path.default.dirname(id)) === 'src';
|
|
111
|
+
// Generate template.json and css.json
|
|
112
|
+
if (id === resolvedEntry) {
|
|
113
|
+
const parse5 = require("aiot-parse5");
|
|
114
|
+
const doc = parse5.parseFragment(content, {
|
|
115
|
+
scriptingEnabled: false
|
|
116
|
+
});
|
|
117
|
+
let templateNode = null;
|
|
118
|
+
const importMap = {}; // name -> path
|
|
119
|
+
for (const node of doc.childNodes) {
|
|
120
|
+
if (node.nodeName === 'template') templateNode = node;else if (node.nodeName === 'import') {
|
|
121
|
+
const nameAttr = node.attrs?.find(a => a.name === 'name');
|
|
122
|
+
const srcAttr = node.attrs?.find(a => a.name === 'src');
|
|
123
|
+
if (nameAttr && srcAttr) {
|
|
124
|
+
const compAbsPath = _path.default.resolve(_path.default.dirname(resolvedEntry), srcAttr.value).replace(/\.ux$/, '');
|
|
125
|
+
const compPath = _path.default.relative(srcPath, compAbsPath).replace(/\\/g, '/');
|
|
126
|
+
importMap[nameAttr.value.toLowerCase()] = compPath;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const pageName = _path.default.relative(srcPath, id).replace(/\.ux$/, '');
|
|
131
|
+
// Compute styleObjectId
|
|
132
|
+
const sid = (0, _TemplateCompiler.getStyleObjectId)(entryName);
|
|
133
|
+
// Get style data from UxLoaderUtils compilation (handles LESS/CSS)
|
|
134
|
+
const {
|
|
135
|
+
files: compFiles
|
|
136
|
+
} = await _UxLoaderUtils.default.compileUxToJavascript({
|
|
137
|
+
path: id,
|
|
138
|
+
content
|
|
139
|
+
}, {
|
|
140
|
+
projectPath: originalProjectPath,
|
|
141
|
+
sourceRoot
|
|
142
|
+
}, isApp, param, compilation);
|
|
143
|
+
const compiledCode = compFiles[0]?.content || '';
|
|
144
|
+
// Extract $app_style$ array from compiled code
|
|
145
|
+
let styleSheet = {};
|
|
146
|
+
const styleMatch = compiledCode.match(/var \$app_style\$ = (\[[\s\S]*?\]);?\s*(?:import|export|var |const |$)/);
|
|
147
|
+
if (styleMatch) {
|
|
148
|
+
if (styleMatch) {
|
|
149
|
+
styleSheet = (0, _TemplateCompiler.parseStyleArray)(styleMatch[1]);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Write css.json
|
|
153
|
+
const cssPath = _path.default.join(buildPath, `${isApp ? 'app' : pageName}.css.json`);
|
|
154
|
+
_fsExtra.default.ensureDirSync(_path.default.dirname(cssPath));
|
|
155
|
+
_fsExtra.default.writeJSONSync(cssPath, Object.keys(styleSheet).length ? {
|
|
156
|
+
[String(sid)]: styleSheet
|
|
157
|
+
} : {}, param.mode === 'production' ? undefined : {
|
|
158
|
+
spaces: 2
|
|
159
|
+
});
|
|
160
|
+
// Write template.json (with style inlining)
|
|
161
|
+
if (templateNode && !isApp) {
|
|
162
|
+
const tplPath = _path.default.join(buildPath, `${pageName}.template.json`);
|
|
163
|
+
_fsExtra.default.ensureDirSync(_path.default.dirname(tplPath));
|
|
164
|
+
_fsExtra.default.writeJSONSync(tplPath, (0, _TemplateCompiler.uxToTemplateJson)(templateNode, sid, styleSheet, importMap, _path.default.dirname(pageName)), param.mode === 'production' ? undefined : {
|
|
165
|
+
spaces: 2
|
|
166
|
+
});
|
|
167
|
+
// Generate sub-component template.json files
|
|
168
|
+
for (const [compName, compPath] of Object.entries(importMap)) {
|
|
169
|
+
const compUxPath = _path.default.resolve(_path.default.dirname(id), `../../${compPath}.ux`);
|
|
170
|
+
if (_fsExtra.default.existsSync(compUxPath)) {
|
|
171
|
+
const compContent = _fsExtra.default.readFileSync(compUxPath, 'utf-8');
|
|
172
|
+
const compDoc = parse5.parseFragment(compContent, {
|
|
173
|
+
scriptingEnabled: false
|
|
174
|
+
});
|
|
175
|
+
const compTpl = compDoc.childNodes.find(n => n.nodeName === 'template');
|
|
176
|
+
if (compTpl) {
|
|
177
|
+
const compTplPath = _path.default.join(buildPath, `${compPath}.template.json`);
|
|
178
|
+
_fsExtra.default.ensureDirSync(_path.default.dirname(compTplPath));
|
|
179
|
+
// Get component styles
|
|
180
|
+
const compResult = await _UxLoaderUtils.default.compileUxToJavascript({
|
|
181
|
+
path: compUxPath,
|
|
182
|
+
content: compContent
|
|
183
|
+
}, {
|
|
184
|
+
projectPath: originalProjectPath,
|
|
185
|
+
sourceRoot
|
|
186
|
+
}, false, param, compilation);
|
|
187
|
+
let compStyleSheet = {};
|
|
188
|
+
const compCode = compResult.files[0]?.content || '';
|
|
189
|
+
const csm = compCode.match(/var \$app_style\$ = (\[[\s\S]*?\]);?\s*(?:import|export|var |const |$)/);
|
|
190
|
+
if (csm) {
|
|
191
|
+
compStyleSheet = (0, _TemplateCompiler.parseStyleArray)(csm[1]);
|
|
192
|
+
}
|
|
193
|
+
const compSid = (0, _TemplateCompiler.getStyleObjectId)(compPath);
|
|
194
|
+
_fsExtra.default.writeJSONSync(compTplPath, (0, _TemplateCompiler.uxToTemplateJson)(compTpl, compSid, compStyleSheet, undefined, _path.default.dirname(compPath)), param.mode === 'production' ? undefined : {
|
|
195
|
+
spaces: 2
|
|
196
|
+
});
|
|
197
|
+
// Generate component css.json
|
|
198
|
+
const compCssPath = _path.default.join(buildPath, `${compPath}.css.json`);
|
|
199
|
+
_fsExtra.default.writeJSONSync(compCssPath, Object.keys(compStyleSheet).length ? {
|
|
200
|
+
[String(compSid)]: compStyleSheet
|
|
201
|
+
} : {}, param.mode === 'production' ? undefined : {
|
|
202
|
+
spaces: 2
|
|
203
|
+
});
|
|
204
|
+
// Generate component js (script only)
|
|
205
|
+
const compJsPath = _path.default.join(buildPath, `${compPath}.js`);
|
|
206
|
+
// Extract the component object from the compiled code
|
|
207
|
+
const exportMatch = compCode.match(/export\s+default\s+([\s\S]*?);?\s*$/);
|
|
208
|
+
const compObj = exportMatch ? exportMatch[1].trim() : '{}';
|
|
209
|
+
const compVarName = compName.replace(/-/g, '_') + '_default';
|
|
210
|
+
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`;
|
|
211
|
+
_fsExtra.default.writeFileSync(compJsPath, compJsContent);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const {
|
|
218
|
+
files
|
|
219
|
+
} = await _UxLoaderUtils.default.compileUxToJavascript({
|
|
220
|
+
path: id,
|
|
221
|
+
content
|
|
222
|
+
}, {
|
|
223
|
+
projectPath: originalProjectPath,
|
|
224
|
+
sourceRoot
|
|
225
|
+
}, isApp, param, compilation);
|
|
226
|
+
return files[0]?.content || '';
|
|
227
|
+
}
|
|
228
|
+
}]
|
|
229
|
+
});
|
|
230
|
+
// Extract the output code
|
|
231
|
+
if (result && !Array.isArray(result)) {
|
|
232
|
+
const output = result.output;
|
|
233
|
+
if (output?.[0]?.code) {
|
|
234
|
+
const code = wrapOutput(output[0].code, entryName, entryName === 'app');
|
|
235
|
+
_fsExtra.default.writeFileSync(outputFile, code);
|
|
236
|
+
}
|
|
237
|
+
} else if (Array.isArray(result) && result[0]) {
|
|
238
|
+
const output = result[0].output;
|
|
239
|
+
if (output?.[0]?.code) {
|
|
240
|
+
const code = wrapOutput(output[0].code, entryName, entryName === 'app');
|
|
241
|
+
_fsExtra.default.writeFileSync(outputFile, code);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
} catch (err) {
|
|
245
|
+
console.warn(`vite: failed to build ${entryName}:`, err.message);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Second pass: compile ALL .ux files that weren't entry pages
|
|
249
|
+
// Each .ux file gets its own template.json + css.json + js
|
|
250
|
+
const allUxFiles = [];
|
|
251
|
+
const findUx = dir => {
|
|
252
|
+
for (const f of _fsExtra.default.readdirSync(dir, {
|
|
253
|
+
withFileTypes: true
|
|
254
|
+
})) {
|
|
255
|
+
const p = _path.default.join(dir, f.name);
|
|
256
|
+
if (f.isDirectory() && f.name !== 'node_modules') findUx(p);else if (f.name.endsWith('.ux')) allUxFiles.push(p);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
findUx(srcPath);
|
|
260
|
+
const compiledEntries = new Set(Object.values(entries).map(v => _path.default.resolve(originalProjectPath, v.split('?')[0])));
|
|
261
|
+
for (const uxFile of allUxFiles) {
|
|
262
|
+
if (compiledEntries.has(uxFile)) continue; // already compiled as entry
|
|
263
|
+
if (uxFile.endsWith('/app.ux')) continue; // app.ux handled separately
|
|
264
|
+
const relPath = _path.default.relative(srcPath, uxFile).replace(/\.ux$/, '');
|
|
265
|
+
const outputJs = _path.default.join(buildPath, `${relPath}.js`);
|
|
266
|
+
const outputTpl = _path.default.join(buildPath, `${relPath}.template.json`);
|
|
267
|
+
const outputCss = _path.default.join(buildPath, `${relPath}.css.json`);
|
|
268
|
+
if (_fsExtra.default.existsSync(outputTpl)) continue; // already generated by parent page
|
|
269
|
+
const content = _fsExtra.default.readFileSync(uxFile, 'utf-8');
|
|
270
|
+
const parse5 = require("aiot-parse5");
|
|
271
|
+
const doc = parse5.parseFragment(content, {
|
|
272
|
+
scriptingEnabled: false
|
|
273
|
+
});
|
|
274
|
+
let templateNode = null;
|
|
275
|
+
const importMap = {};
|
|
276
|
+
for (const node of doc.childNodes) {
|
|
277
|
+
if (node.nodeName === 'template') templateNode = node;else if (node.nodeName === 'import') {
|
|
278
|
+
const nameAttr = node.attrs?.find(a => a.name === 'name');
|
|
279
|
+
const srcAttr = node.attrs?.find(a => a.name === 'src');
|
|
280
|
+
if (nameAttr && srcAttr) {
|
|
281
|
+
const compPath = _path.default.resolve(_path.default.dirname(uxFile), srcAttr.value).replace(/\.ux$/, '');
|
|
282
|
+
importMap[nameAttr.value.toLowerCase()] = _path.default.relative(srcPath, compPath).replace(/\\/g, '/');
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// Compute styleObjectId
|
|
287
|
+
const sid = (0, _TemplateCompiler.getStyleObjectId)(relPath);
|
|
288
|
+
// Compile with UxLoaderUtils to get style data and script
|
|
289
|
+
const compilation = {
|
|
290
|
+
entries: [uxFile]
|
|
291
|
+
};
|
|
292
|
+
try {
|
|
293
|
+
const {
|
|
294
|
+
files
|
|
295
|
+
} = await _UxLoaderUtils.default.compileUxToJavascript({
|
|
296
|
+
path: uxFile,
|
|
297
|
+
content
|
|
298
|
+
}, {
|
|
299
|
+
projectPath: originalProjectPath,
|
|
300
|
+
sourceRoot
|
|
301
|
+
}, false, param, compilation);
|
|
302
|
+
const compCode = files[0]?.content || '';
|
|
303
|
+
// Extract style
|
|
304
|
+
let styleSheet = {};
|
|
305
|
+
const csm = compCode.match(/var \$app_style\$ = (\[[\s\S]*?\]);?\s*(?:import|export|var |const |$)/);
|
|
306
|
+
if (csm) {
|
|
307
|
+
styleSheet = (0, _TemplateCompiler.parseStyleArray)(csm[1]);
|
|
308
|
+
}
|
|
309
|
+
// Generate template.json
|
|
310
|
+
if (templateNode) {
|
|
311
|
+
_fsExtra.default.ensureDirSync(_path.default.dirname(outputTpl));
|
|
312
|
+
_fsExtra.default.writeJSONSync(outputTpl, (0, _TemplateCompiler.uxToTemplateJson)(templateNode, sid, styleSheet, Object.keys(importMap).length ? importMap : undefined, _path.default.dirname(relPath)), param.mode === 'production' ? undefined : {
|
|
313
|
+
spaces: 2
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
// Generate css.json
|
|
317
|
+
_fsExtra.default.ensureDirSync(_path.default.dirname(outputCss));
|
|
318
|
+
_fsExtra.default.writeJSONSync(outputCss, Object.keys(styleSheet).length ? {
|
|
319
|
+
[String(sid)]: styleSheet
|
|
320
|
+
} : {}, param.mode === 'production' ? undefined : {
|
|
321
|
+
spaces: 2
|
|
322
|
+
});
|
|
323
|
+
// Generate js
|
|
324
|
+
const exportMatch = compCode.match(/export\s+default\s+([\s\S]*?);?\s*$/);
|
|
325
|
+
const compObj = exportMatch ? exportMatch[1].trim() : '{}';
|
|
326
|
+
const compName = _path.default.basename(relPath).toLowerCase();
|
|
327
|
+
const varName = compName.replace(/-/g, '_') + '_default';
|
|
328
|
+
_fsExtra.default.ensureDirSync(_path.default.dirname(outputJs));
|
|
329
|
+
_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`);
|
|
330
|
+
} catch {}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
async clean(param) {
|
|
334
|
+
const {
|
|
335
|
+
outputPath,
|
|
336
|
+
releasePath,
|
|
337
|
+
projectPath
|
|
338
|
+
} = param;
|
|
339
|
+
_UxCompileUtil.default.clean([outputPath, releasePath].map(item => _path.default.resolve(projectPath, item)));
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
function wrapOutput(code, entryName, isApp) {
|
|
343
|
+
const componentName = _path.default.parse(entryName).name;
|
|
344
|
+
const defineId = isApp ? '@app-component/app' : `@app-component/${componentName}`;
|
|
345
|
+
const bootstrapId = isApp ? '@app-application/app' : `@app-component/${componentName}`;
|
|
346
|
+
// Remove IIFE wrapper: var _page_ = (function(...) { ... return xxx; })(...);
|
|
347
|
+
// Only remove the FIRST line and the LAST return+closing
|
|
348
|
+
if (code.startsWith('var _page_')) {
|
|
349
|
+
// Remove first line (the IIFE opening)
|
|
350
|
+
const firstNewline = code.indexOf('\n');
|
|
351
|
+
code = code.slice(firstNewline + 1);
|
|
352
|
+
// Remove the last return statement and closing })();
|
|
353
|
+
const lastReturn = code.lastIndexOf('\treturn ');
|
|
354
|
+
if (lastReturn !== -1) {
|
|
355
|
+
const afterReturn = code.indexOf('\n', lastReturn);
|
|
356
|
+
code = code.slice(0, lastReturn) + code.slice(afterReturn + 1);
|
|
357
|
+
}
|
|
358
|
+
// Remove the closing })(); or })(...)
|
|
359
|
+
const lastClose = code.lastIndexOf('})();');
|
|
360
|
+
if (lastClose !== -1) {
|
|
361
|
+
code = code.slice(0, lastClose);
|
|
362
|
+
} else {
|
|
363
|
+
const lastClose2 = code.lastIndexOf('})(');
|
|
364
|
+
if (lastClose2 !== -1) {
|
|
365
|
+
code = code.slice(0, lastClose2);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
// Remove rolldown region comments
|
|
370
|
+
code = code.replace(/\/\/#region[^\n]*\n/g, '');
|
|
371
|
+
code = code.replace(/\/\/#endregion[^\n]*/g, '');
|
|
372
|
+
// Remove rolldown runtime helpers (not needed in final output)
|
|
373
|
+
code = code.replace(/var __defProp = Object\.defineProperty;\n?/g, '');
|
|
374
|
+
code = code.replace(/var __exportAll = [\s\S]*?return target;\s*\};\n?/g, '');
|
|
375
|
+
// Inline __exportAll calls: __exportAll({key: () => value, ...}) -> {key: value, ...}
|
|
376
|
+
// Match __exportAll(...) or /* @__PURE__ */ __exportAll(...)
|
|
377
|
+
code = code.replace(/(?:\/\* @__PURE__ \*\/\s*)?__exportAll\(\s*\{([\s\S]*?)\}\s*\)/g, (_match, body) => {
|
|
378
|
+
// Replace each "key: () => value" with "get key() { return value }" for proper live binding
|
|
379
|
+
const inlined = body.replace(/(\w+)\s*:\s*\(\)\s*=>\s*([^,\n}]+?)([,\n])/g, 'get $1() { return $2; }$3');
|
|
380
|
+
return `{${inlined}}`;
|
|
381
|
+
});
|
|
382
|
+
// Remove Object.defineProperty for Symbol.toStringTag
|
|
383
|
+
code = code.replace(/\s*Object\.defineProperty\(\w+,\s*Symbol\.toStringTag[^;]*;\s*/g, '');
|
|
384
|
+
// Extract the default export variable
|
|
385
|
+
let exportVar = '_default';
|
|
386
|
+
const m1 = code.match(/export\s*\{\s*(\w+)\s+as\s+default\s*\}/);
|
|
387
|
+
if (m1) {
|
|
388
|
+
exportVar = m1[1];
|
|
389
|
+
code = code.replace(m1[0], '');
|
|
390
|
+
}
|
|
391
|
+
code = code.replace(/export\s+default\s+(\w+)\s*;?/g, (_, v) => {
|
|
392
|
+
exportVar = v;
|
|
393
|
+
return '';
|
|
394
|
+
});
|
|
395
|
+
code = code.replace(/export\s+\{[^}]*\}\s*;?/g, '');
|
|
396
|
+
// Find the return statement variable (IIFE returns the component)
|
|
397
|
+
const returnMatch = code.match(/return\s+(\w+)\s*;?\s*$/);
|
|
398
|
+
if (returnMatch) {
|
|
399
|
+
exportVar = returnMatch[1];
|
|
400
|
+
code = code.replace(returnMatch[0], '');
|
|
401
|
+
}
|
|
402
|
+
// Generate styleObjectId hash
|
|
403
|
+
const styleId = (0, _TemplateCompiler.getStyleObjectId)(entryName);
|
|
404
|
+
return `let $style$${styleId} = {"@info":{"styleObjectId":${styleId}}};
|
|
405
|
+
const $app_style$${styleId} = $style$${styleId};
|
|
406
|
+
${code.trim()}
|
|
407
|
+
$app_define$("${defineId}", [], function($app_require$, $app_exports$, $app_module$) {
|
|
408
|
+
$app_module$.exports = ${exportVar}.default || ${exportVar};
|
|
409
|
+
$app_module$.exports.style = $app_style$${styleId};
|
|
410
|
+
});
|
|
411
|
+
$app_bootstrap$("${bootstrapId}");
|
|
412
|
+
`;
|
|
413
|
+
}
|
|
414
|
+
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
|
*/
|
|
@@ -71,6 +80,23 @@ interface IJavascriptCompileOption extends ICompileParam {
|
|
|
71
80
|
* @example log,warn
|
|
72
81
|
*/
|
|
73
82
|
dropConsole?: boolean | string;
|
|
83
|
+
/**
|
|
84
|
+
* 启用预渲染
|
|
85
|
+
*
|
|
86
|
+
* 编译后在 VM 沙箱中执行模板函数,生成 .template.json + .css.json
|
|
87
|
+
* @default true
|
|
88
|
+
*/
|
|
89
|
+
enablePrerender?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* 是否预渲染子组件(import 引用的组件)
|
|
92
|
+
* @default true
|
|
93
|
+
*/
|
|
94
|
+
prerenderSubComp?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* 排除不预渲染的页面路径列表
|
|
97
|
+
* 支持前缀匹配,如 ['pages/Dynamic'] 会排除 pages/Dynamic/index 等
|
|
98
|
+
*/
|
|
99
|
+
prerenderExclude?: string[];
|
|
74
100
|
/**
|
|
75
101
|
* 启动页
|
|
76
102
|
*/
|
|
@@ -8,7 +8,9 @@ declare class VelaWebpackConfigurator implements IWebpackConfigurator {
|
|
|
8
8
|
protected createWrapPlugin(): RspackPluginInstance;
|
|
9
9
|
protected createBundleAnalyzerPlugin(): any;
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
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
|
-
*
|
|
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;
|