@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,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.StyleSerializer = void 0;
|
|
7
|
+
var _crypto = _interopRequireDefault(require("crypto"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
/** css.json format: { [styleObjectId]: { ".class": { prop: value } } } */
|
|
10
|
+
|
|
11
|
+
const SELECTOR_CLASS = 0;
|
|
12
|
+
const SELECTOR_ID = 1;
|
|
13
|
+
const SELECTOR_TAG = 2;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* StyleSerializer - Converts compiled IStyleNode[] ($app_style$) into css.json format.
|
|
17
|
+
*/
|
|
18
|
+
class StyleSerializer {
|
|
19
|
+
cache = (() => new Map())();
|
|
20
|
+
selectorToString(selectors) {
|
|
21
|
+
return selectors.map(_ref => {
|
|
22
|
+
let [type, name] = _ref;
|
|
23
|
+
switch (type) {
|
|
24
|
+
case SELECTOR_CLASS:
|
|
25
|
+
return `.${name}`;
|
|
26
|
+
case SELECTOR_ID:
|
|
27
|
+
return `#${name}`;
|
|
28
|
+
case SELECTOR_TAG:
|
|
29
|
+
return `${name}`;
|
|
30
|
+
default:
|
|
31
|
+
return `${name}`;
|
|
32
|
+
}
|
|
33
|
+
}).join('');
|
|
34
|
+
}
|
|
35
|
+
parseStyleNodes(styleNodes) {
|
|
36
|
+
const result = {};
|
|
37
|
+
for (const node of styleNodes) {
|
|
38
|
+
if (!Array.isArray(node) || node.length < 2) continue;
|
|
39
|
+
const selectorPart = node[0];
|
|
40
|
+
const stylePart = node[1];
|
|
41
|
+
if (!Array.isArray(selectorPart)) continue;
|
|
42
|
+
const selectors = selectorPart;
|
|
43
|
+
if (!selectors.length || !Array.isArray(selectors[0])) continue;
|
|
44
|
+
const selectorStr = this.selectorToString(selectors);
|
|
45
|
+
if (!selectorStr) continue;
|
|
46
|
+
const styleMap = {};
|
|
47
|
+
if (stylePart && typeof stylePart === 'object' && !Array.isArray(stylePart)) {
|
|
48
|
+
for (const [prop, value] of Object.entries(stylePart)) {
|
|
49
|
+
// Keep numeric values as numbers (flex, order, z-index, opacity, etc.)
|
|
50
|
+
if (typeof value === 'number') {
|
|
51
|
+
styleMap[prop] = value;
|
|
52
|
+
} else {
|
|
53
|
+
styleMap[prop] = String(value);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
result[selectorStr] = styleMap;
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
generateId(content) {
|
|
62
|
+
return _crypto.default.createHash('md5').update(content).digest('hex').slice(0, 6);
|
|
63
|
+
}
|
|
64
|
+
serialize(styleNodes) {
|
|
65
|
+
const cacheKey = JSON.stringify(styleNodes);
|
|
66
|
+
const cached = this.cache.get(cacheKey);
|
|
67
|
+
if (cached) return cached;
|
|
68
|
+
const styles = this.parseStyleNodes(styleNodes);
|
|
69
|
+
const id = this.generateId(cacheKey);
|
|
70
|
+
const entry = {
|
|
71
|
+
id,
|
|
72
|
+
styles
|
|
73
|
+
};
|
|
74
|
+
this.cache.set(cacheKey, entry);
|
|
75
|
+
return entry;
|
|
76
|
+
}
|
|
77
|
+
toCssJson() {
|
|
78
|
+
const result = {};
|
|
79
|
+
for (const {
|
|
80
|
+
id,
|
|
81
|
+
styles
|
|
82
|
+
} of this.cache.values()) {
|
|
83
|
+
result[id] = styles;
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
reset() {
|
|
88
|
+
this.cache.clear();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.StyleSerializer = StyleSerializer;
|
|
92
|
+
var _default = exports.default = StyleSerializer;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PrerenderNode } from './PrerenderVM';
|
|
2
|
+
/**
|
|
3
|
+
* TemplateSerializer - 将 PrerenderVM 的渲染结果序列化为 template.json + css.json
|
|
4
|
+
*/
|
|
5
|
+
export default class TemplateSerializer {
|
|
6
|
+
private styleSerializer;
|
|
7
|
+
/**
|
|
8
|
+
* 将 DOM 树序列化为 template.json 格式
|
|
9
|
+
* 解析 class 列表,从 css.json 样式表中查找并内联 style
|
|
10
|
+
*/
|
|
11
|
+
serializeTemplate(tree: PrerenderNode, styleSheet: Record<string, Record<string, string>>, styleObjectId?: number): Record<string, any>;
|
|
12
|
+
/**
|
|
13
|
+
* 将样式表序列化为 css.json 格式
|
|
14
|
+
* 格式: { [styleObjectId]: { ".className": { prop: value } } }
|
|
15
|
+
*
|
|
16
|
+
* Input: { [numericId]: rawStyleArray }
|
|
17
|
+
* Output: { [stringId]: { ".class": { prop: value } } }
|
|
18
|
+
*/
|
|
19
|
+
serializeCss(styles: Record<number, any>): Record<string, Record<string, Record<string, string>>>;
|
|
20
|
+
private serializeNode;
|
|
21
|
+
/**
|
|
22
|
+
* 从 class 列表和 styleSheet 解析出内联 style
|
|
23
|
+
* 优先级: class 样式 < inline style(后者覆盖前者)
|
|
24
|
+
*/
|
|
25
|
+
private resolveStyles;
|
|
26
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _StyleSerializer = require("./StyleSerializer");
|
|
8
|
+
/**
|
|
9
|
+
* TemplateSerializer - 将 PrerenderVM 的渲染结果序列化为 template.json + css.json
|
|
10
|
+
*/
|
|
11
|
+
class TemplateSerializer {
|
|
12
|
+
styleSerializer = (() => new _StyleSerializer.StyleSerializer())();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 将 DOM 树序列化为 template.json 格式
|
|
16
|
+
* 解析 class 列表,从 css.json 样式表中查找并内联 style
|
|
17
|
+
*/
|
|
18
|
+
serializeTemplate(tree, styleSheet, styleObjectId) {
|
|
19
|
+
return this.serializeNode(tree, styleSheet, styleObjectId);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 将样式表序列化为 css.json 格式
|
|
24
|
+
* 格式: { [styleObjectId]: { ".className": { prop: value } } }
|
|
25
|
+
*
|
|
26
|
+
* Input: { [numericId]: rawStyleArray }
|
|
27
|
+
* Output: { [stringId]: { ".class": { prop: value } } }
|
|
28
|
+
*/
|
|
29
|
+
serializeCss(styles) {
|
|
30
|
+
const result = {};
|
|
31
|
+
for (const [id, styleData] of Object.entries(styles)) {
|
|
32
|
+
if (Array.isArray(styleData)) {
|
|
33
|
+
result[String(id)] = this.styleSerializer.parseStyleNodes(styleData);
|
|
34
|
+
} else if (styleData && typeof styleData === 'object' && Object.keys(styleData).length > 0) {
|
|
35
|
+
// Already normalized by PrerenderVM.normalizeStyleSheet (Vela format)
|
|
36
|
+
result[String(id)] = styleData;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
serializeNode(node, styleSheet, styleObjectId) {
|
|
42
|
+
const result = {
|
|
43
|
+
type: node.type
|
|
44
|
+
};
|
|
45
|
+
if (styleObjectId !== undefined) {
|
|
46
|
+
result.styleObjectId = styleObjectId;
|
|
47
|
+
}
|
|
48
|
+
if (node.attr && Object.keys(node.attr).length) {
|
|
49
|
+
result.attr = node.attr;
|
|
50
|
+
}
|
|
51
|
+
if (node.bind) {
|
|
52
|
+
result.bind = node.bind;
|
|
53
|
+
}
|
|
54
|
+
if (node.class) {
|
|
55
|
+
result.class = node.class;
|
|
56
|
+
}
|
|
57
|
+
const resolvedStyle = this.resolveStyles(node.class, node.style, styleSheet);
|
|
58
|
+
if (resolvedStyle && Object.keys(resolvedStyle).length) {
|
|
59
|
+
result.style = resolvedStyle;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Events: simple events use method name, dynamic use $event + function string
|
|
63
|
+
if (node.events && Object.keys(node.events).length) {
|
|
64
|
+
const events = {};
|
|
65
|
+
for (const [key, handler] of Object.entries(node.events)) {
|
|
66
|
+
const eventName = key.startsWith('$') ? key.slice(1) : key;
|
|
67
|
+
const handlerStr = String(handler).replace(/_vm_\./g, 'this.');
|
|
68
|
+
// Check if it's a simple method call: function(evt) { return this.methodName(evt); }
|
|
69
|
+
const simpleMatch = handlerStr.match(/^function\s*\(\w*\)\s*\{\s*return\s+this\.(\w+)\(\w*\);\s*\}$/);
|
|
70
|
+
if (simpleMatch) {
|
|
71
|
+
events[eventName] = simpleMatch[1];
|
|
72
|
+
} else if (handlerStr.includes('function') || handlerStr.includes('=>')) {
|
|
73
|
+
events[`$${eventName}`] = handlerStr;
|
|
74
|
+
} else {
|
|
75
|
+
events[eventName] = handlerStr;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
result.events = events;
|
|
79
|
+
}
|
|
80
|
+
if (node.import) {
|
|
81
|
+
result.import = node.import;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// $repeat (for loops)
|
|
85
|
+
if (node.$repeat) {
|
|
86
|
+
result.$repeat = node.$repeat;
|
|
87
|
+
result.repeat = [];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// $shown (if conditions)
|
|
91
|
+
if (node['$shown']) {
|
|
92
|
+
result['$shown'] = node['$shown'];
|
|
93
|
+
result['shown'] = node['shown'] ?? false;
|
|
94
|
+
}
|
|
95
|
+
if (node.children?.length) {
|
|
96
|
+
result.children = node.children.map(child => this.serializeNode(child, styleSheet));
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* 从 class 列表和 styleSheet 解析出内联 style
|
|
103
|
+
* 优先级: class 样式 < inline style(后者覆盖前者)
|
|
104
|
+
*/
|
|
105
|
+
resolveStyles(classStr, inlineStyle, styleSheet) {
|
|
106
|
+
const merged = {};
|
|
107
|
+
if (classStr) {
|
|
108
|
+
const classes = classStr.split(/\s+/).filter(Boolean);
|
|
109
|
+
for (const cls of classes) {
|
|
110
|
+
const key = `.${cls}`;
|
|
111
|
+
if (styleSheet[key]) {
|
|
112
|
+
Object.assign(merged, styleSheet[key]);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (inlineStyle) {
|
|
117
|
+
Object.assign(merged, inlineStyle);
|
|
118
|
+
}
|
|
119
|
+
return Object.keys(merged).length ? merged : undefined;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.default = TemplateSerializer;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ILog } from '@aiot-toolkit/shared-utils';
|
|
2
|
+
import IPrerenderOption from './interface/IPrerenderOption';
|
|
3
|
+
/**
|
|
4
|
+
* 预渲染入口
|
|
5
|
+
*
|
|
6
|
+
* 读取编译后的 JS 产物,在 VM 沙箱中执行模板函数,
|
|
7
|
+
* 将静态 DOM 结构序列化为 .template.json + .css.json
|
|
8
|
+
* 支持子组件递归预渲染和多级缓存
|
|
9
|
+
*/
|
|
10
|
+
export declare function prerender(option: IPrerenderOption, onLog?: (logs: ILog[]) => void): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Clear prerender caches for watch mode.
|
|
13
|
+
* - No args or empty array: full clear (e.g. style file changed)
|
|
14
|
+
* - With page paths: incremental clear for those pages only
|
|
15
|
+
*/
|
|
16
|
+
export declare function watchChange(changedPages?: string[]): void;
|
|
17
|
+
export { default as PrerenderVM } from './PrerenderVM';
|
|
18
|
+
export type { BindingMarker, RepeatMarker, EventMarker, PrerenderNode } from './PrerenderVM';
|
|
19
|
+
export { default as TemplateSerializer } from './TemplateSerializer';
|
|
20
|
+
export type { default as IPrerenderOption } from './interface/IPrerenderOption';
|