@actview/plugin-babel 2.1.0 → 2.2.0
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/README.md +64 -86
- package/dist/index.d.ts +4 -26
- package/dist/index.js +5 -738
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,86 +1,64 @@
|
|
|
1
|
-
# @actview/plugin-babel
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
##
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// vite.config.ts
|
|
66
|
-
resolve: {
|
|
67
|
-
alias: { 'my-lib': 'node_modules/my-lib/src' }, // 路径不再含 node_modules 段 → 正常转换
|
|
68
|
-
},
|
|
69
|
-
optimizeDeps: { exclude: ['my-lib'] }, // 不预构建,保持源码形态
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## 依赖关系
|
|
73
|
-
|
|
74
|
-
- `@babel/core`(^8)
|
|
75
|
-
- 被依赖方:`@actview/plugin-vite`、`@actview/plugin-scoped`(复用宿主壳)
|
|
76
|
-
|
|
77
|
-
## 开发
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
pnpm build # tsup 打包 dist
|
|
81
|
-
pnpm test # vitest(test/plugin.test.ts:组件转换/插槽/props/早退等 30 用例)
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## License
|
|
85
|
-
|
|
86
|
-
MIT
|
|
1
|
+
# @actview/plugin-babel
|
|
2
|
+
|
|
3
|
+
**共享 Babel 宿主壳** —— 统一 `transformSync` 调用参数与排除规则,供 `@actview/plugin-vite` 与 `@actview/plugin-scoped` 复用。
|
|
4
|
+
|
|
5
|
+
(v1 的 `defineComponentPlugin` / `solidPlugin` 已随 ActView v2 移除——v2 的 JSX 编译由 `@actview/plugin-jsx` 承担。)
|
|
6
|
+
|
|
7
|
+
## 核心功能
|
|
8
|
+
|
|
9
|
+
- **统一参数**:`parserOpts(jsx+typescript)` / `retainLines` / `sourceMaps` / `babelrc:false` / `configFile:false`
|
|
10
|
+
- **排除规则**:node_modules 硬排除(include 不可覆盖)/ include 白名单 / exclude 黑名单
|
|
11
|
+
- **性能**:`createBabelTransform` 模块级创建一次 ConfigItem(Babel 8 同步),跨多次 `transformSync` 复用
|
|
12
|
+
|
|
13
|
+
## 安装
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add -D @actview/plugin-babel
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## API
|
|
20
|
+
|
|
21
|
+
| 导出 | 说明 |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `createBabelTransform(plugin, options?)` | 宿主壳工厂:模块级创建一次 ConfigItem,返回 `(code, filename) => { code, map } \| null` |
|
|
24
|
+
| `createBabelItem(plugin)` | 把插件工厂预编译为 ConfigItem(Babel 8 同步) |
|
|
25
|
+
| `transformWithBabel(code, filename, pluginItem, options?)` | 统一参数的 `transformSync` |
|
|
26
|
+
| `isExcludedTransform(filename, options?)` | 排除判定:node_modules 硬排除 / 未命中 include / 命中 exclude |
|
|
27
|
+
| 类型:`BabelPlugin` / `BabelHostResult` / `BabelTransformOptions` | 宿主壳类型 |
|
|
28
|
+
|
|
29
|
+
## 排除规则(node_modules 硬排除)
|
|
30
|
+
|
|
31
|
+
宿主壳**硬排除 node_modules 下的文件**(返回 `null` 不转换):依赖是第三方代码,属依赖管线(esbuild 预构建),不是源码管线。`BabelTransformOptions`:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
{
|
|
35
|
+
include?: Array<string | RegExp>, // 白名单:命中任一才转换(默认不过滤;node_modules 硬排除优先)
|
|
36
|
+
exclude?: Array<string | RegExp>, // 黑名单:命中任一即跳过(优先于 include)
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**源码分发库包(node_modules 下)需要现场编译时**,在宿主构建配置里做**路径转换**,让文件解析路径脱离 node_modules 段:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
// vite.config.ts
|
|
44
|
+
resolve: {
|
|
45
|
+
alias: { 'my-lib': 'node_modules/my-lib/src' }, // 路径不再含 node_modules 段 → 正常转换
|
|
46
|
+
},
|
|
47
|
+
optimizeDeps: { exclude: ['my-lib'] },
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 依赖关系
|
|
51
|
+
|
|
52
|
+
- `@babel/core`(^8)
|
|
53
|
+
- 被依赖方:`@actview/plugin-vite`、`@actview/plugin-scoped`(复用宿主壳)
|
|
54
|
+
|
|
55
|
+
## 开发
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pnpm build # tsup 打包 dist
|
|
59
|
+
pnpm test # vitest(test/babel-host.test.ts:排除规则/宿主壳行为)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## License
|
|
63
|
+
|
|
64
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,5 @@
|
|
|
1
1
|
import { PluginObject, PluginItem } from '@babel/core';
|
|
2
2
|
|
|
3
|
-
declare function defineComponentPlugin(): {
|
|
4
|
-
visitor: {
|
|
5
|
-
Program: {
|
|
6
|
-
enter(): void;
|
|
7
|
-
exit(path: any): void;
|
|
8
|
-
};
|
|
9
|
-
FunctionDeclaration(path: any): void;
|
|
10
|
-
VariableDeclarator(path: any): void;
|
|
11
|
-
JSXElement(path: any): void;
|
|
12
|
-
JSXFragment(path: any): void;
|
|
13
|
-
ExportDefaultDeclaration(path: any): void;
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
|
|
17
3
|
/** Babel 插件工厂形态(() => { visitor }),createConfigItemSync 的标准输入 */
|
|
18
4
|
type BabelPlugin = () => PluginObject;
|
|
19
5
|
/** transformSync 统一产物(result.map 类型为 BabelSourceMap | null | undefined) */
|
|
@@ -30,8 +16,9 @@ interface BabelTransformOptions {
|
|
|
30
16
|
}
|
|
31
17
|
/** 是否应跳过转换:node_modules 硬排除 / 未命中 include / 命中 exclude */
|
|
32
18
|
declare function isExcludedTransform(filename: string, options?: BabelTransformOptions): boolean;
|
|
33
|
-
/** 把插件工厂预编译为 ConfigItem(Babel 8 同步版本,可跨多次 transformSync
|
|
34
|
-
|
|
19
|
+
/** 把插件工厂预编译为 ConfigItem(Babel 8 同步版本,可跨多次 transformSync 复用);
|
|
20
|
+
* pluginOptions 非空时按 [plugin, options] 元组创建(Babel 标准插件选项) */
|
|
21
|
+
declare function createBabelItem(plugin: BabelPlugin, pluginOptions?: object): PluginItem;
|
|
35
22
|
/** 统一参数的 transformSync:排除命中或失败返回 null,成功返回 { code, map } */
|
|
36
23
|
declare function transformWithBabel(code: string, filename: string, pluginItem: PluginItem, options?: BabelTransformOptions): BabelHostResult | null;
|
|
37
24
|
/**
|
|
@@ -40,13 +27,4 @@ declare function transformWithBabel(code: string, filename: string, pluginItem:
|
|
|
40
27
|
*/
|
|
41
28
|
declare function createBabelTransform(plugin: BabelPlugin | BabelPlugin[], options?: BabelTransformOptions): (code: string, filename: string) => BabelHostResult | null;
|
|
42
29
|
|
|
43
|
-
|
|
44
|
-
visitor: {
|
|
45
|
-
Program: {
|
|
46
|
-
enter(): void;
|
|
47
|
-
exit(path: any): void;
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export { type BabelHostResult, type BabelTransformOptions, createBabelItem, createBabelTransform, defineComponentPlugin as default, defineComponentPlugin, isExcludedTransform, solidPlugin, transformWithBabel };
|
|
30
|
+
export { type BabelHostResult, type BabelTransformOptions, createBabelItem, createBabelTransform, isExcludedTransform, transformWithBabel };
|
package/dist/index.js
CHANGED
|
@@ -1,440 +1,3 @@
|
|
|
1
|
-
// src/babel-plugin.ts
|
|
2
|
-
import { types as t } from "@babel/core";
|
|
3
|
-
import generate from "@babel/generator";
|
|
4
|
-
function extractNamedSlots(el) {
|
|
5
|
-
const nameNode = el.openingElement.name;
|
|
6
|
-
if (t.isJSXIdentifier(nameNode)) {
|
|
7
|
-
if (!/^[A-Z]/.test(nameNode.name)) return;
|
|
8
|
-
} else if (!t.isJSXMemberExpression(nameNode)) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
const children = el.children;
|
|
12
|
-
const slotProps = [];
|
|
13
|
-
const remaining = [];
|
|
14
|
-
for (const child of children) {
|
|
15
|
-
if (t.isJSXElement(child) && t.isJSXIdentifier(child.openingElement.name, { name: "template" })) {
|
|
16
|
-
const attrs = child.openingElement.attributes;
|
|
17
|
-
const slotAttr = attrs.find(
|
|
18
|
-
(a) => t.isJSXAttribute(a) && t.isJSXIdentifier(a.name, { name: "slot" })
|
|
19
|
-
);
|
|
20
|
-
if (slotAttr && t.isStringLiteral(slotAttr.value)) {
|
|
21
|
-
const scopeParams = attrs.filter(
|
|
22
|
-
(a) => t.isJSXAttribute(a) && !t.isJSXIdentifier(a.name, { name: "slot" }) && !a.value
|
|
23
|
-
).map((a) => t.identifier(a.name.name));
|
|
24
|
-
const slotBody = t.jsxFragment(
|
|
25
|
-
t.jsxOpeningFragment(),
|
|
26
|
-
t.jsxClosingFragment(),
|
|
27
|
-
child.children
|
|
28
|
-
);
|
|
29
|
-
slotProps.push(
|
|
30
|
-
t.objectProperty(
|
|
31
|
-
t.stringLiteral(slotAttr.value.value),
|
|
32
|
-
t.arrowFunctionExpression(scopeParams, slotBody)
|
|
33
|
-
)
|
|
34
|
-
);
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
remaining.push(child);
|
|
39
|
-
}
|
|
40
|
-
if (!slotProps.length) return;
|
|
41
|
-
el.children = remaining;
|
|
42
|
-
el.openingElement.attributes.push(
|
|
43
|
-
t.jsxAttribute(
|
|
44
|
-
t.jsxIdentifier("slots"),
|
|
45
|
-
t.jsxExpressionContainer(t.objectExpression(slotProps))
|
|
46
|
-
)
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
function walkJSX(node) {
|
|
50
|
-
if (t.isJSXElement(node)) {
|
|
51
|
-
extractNamedSlots(node);
|
|
52
|
-
node.children.forEach(walkJSX);
|
|
53
|
-
} else if (t.isJSXFragment(node)) {
|
|
54
|
-
node.children.forEach(walkJSX);
|
|
55
|
-
} else if (t.isJSXExpressionContainer(node)) {
|
|
56
|
-
walkExpression(node.expression);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
function walkExpression(expr) {
|
|
60
|
-
if (!expr) return;
|
|
61
|
-
if (t.isJSXElement(expr) || t.isJSXFragment(expr)) {
|
|
62
|
-
walkJSX(expr);
|
|
63
|
-
} else if (t.isJSXExpressionContainer(expr)) {
|
|
64
|
-
walkExpression(expr.expression);
|
|
65
|
-
} else if (t.isLogicalExpression(expr) || t.isBinaryExpression(expr)) {
|
|
66
|
-
walkExpression(expr.left);
|
|
67
|
-
walkExpression(expr.right);
|
|
68
|
-
} else if (t.isConditionalExpression(expr)) {
|
|
69
|
-
walkExpression(expr.consequent);
|
|
70
|
-
walkExpression(expr.alternate);
|
|
71
|
-
} else if (t.isArrowFunctionExpression(expr) || t.isFunctionExpression(expr)) {
|
|
72
|
-
walkExpression(expr.body);
|
|
73
|
-
} else if (t.isCallExpression(expr)) {
|
|
74
|
-
expr.arguments.forEach(walkExpression);
|
|
75
|
-
} else if (t.isArrayExpression(expr)) {
|
|
76
|
-
expr.elements.forEach(walkExpression);
|
|
77
|
-
} else if (t.isObjectExpression(expr)) {
|
|
78
|
-
expr.properties.forEach((p) => walkExpression(p.value));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
function defineComponentPlugin() {
|
|
82
|
-
let hasTransformed = false;
|
|
83
|
-
const jstate = { usedJsx: false, usedFragment: false };
|
|
84
|
-
return {
|
|
85
|
-
visitor: {
|
|
86
|
-
Program: {
|
|
87
|
-
enter() {
|
|
88
|
-
hasTransformed = false;
|
|
89
|
-
jstate.usedJsx = false;
|
|
90
|
-
jstate.usedFragment = false;
|
|
91
|
-
},
|
|
92
|
-
exit(path) {
|
|
93
|
-
if (jstate.usedJsx) {
|
|
94
|
-
const jsxSpecs = [];
|
|
95
|
-
if (jstate.usedJsx) {
|
|
96
|
-
jsxSpecs.push(t.importSpecifier(t.identifier("_jsx"), t.identifier("jsx")));
|
|
97
|
-
}
|
|
98
|
-
if (jstate.usedFragment) {
|
|
99
|
-
jsxSpecs.push(
|
|
100
|
-
t.importSpecifier(t.identifier("_Fragment"), t.identifier("Fragment"))
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
const hasJsxImport = path.node.body.some(
|
|
104
|
-
(n) => t.isImportDeclaration(n) && n.source.value === "@actview/jsx/jsx-runtime"
|
|
105
|
-
);
|
|
106
|
-
if (!hasJsxImport) {
|
|
107
|
-
path.node.body.unshift(
|
|
108
|
-
t.importDeclaration(jsxSpecs, t.stringLiteral("@actview/jsx/jsx-runtime"))
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
if (!hasTransformed) return;
|
|
113
|
-
const alreadyImported = path.node.body.some(
|
|
114
|
-
(n) => t.isImportDeclaration(n) && n.specifiers.some(
|
|
115
|
-
(s) => s.imported?.name === "defineComponent"
|
|
116
|
-
)
|
|
117
|
-
);
|
|
118
|
-
if (!alreadyImported) {
|
|
119
|
-
path.node.body.unshift(
|
|
120
|
-
t.importDeclaration(
|
|
121
|
-
[t.importSpecifier(t.identifier("defineComponent"), t.identifier("defineComponent"))],
|
|
122
|
-
t.stringLiteral("@actview/core")
|
|
123
|
-
)
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
FunctionDeclaration(path) {
|
|
129
|
-
const node = path.node;
|
|
130
|
-
if (!node.id) return;
|
|
131
|
-
const name = node.id.name;
|
|
132
|
-
if (!/^[A-Z]/.test(name)) return;
|
|
133
|
-
assertNoSetupStyleEarlyReturns(path, name);
|
|
134
|
-
const fn = t.functionExpression(null, node.params, node.body, false, false);
|
|
135
|
-
if (node.typeParameters) fn.typeParameters = node.typeParameters;
|
|
136
|
-
const wrapped = wrapComponentFn(fn, name, path);
|
|
137
|
-
if (!wrapped) return;
|
|
138
|
-
const call = wrapped;
|
|
139
|
-
hasTransformed = true;
|
|
140
|
-
wrapEarlyReturns(path);
|
|
141
|
-
path.replaceWith(
|
|
142
|
-
t.variableDeclaration("const", [
|
|
143
|
-
t.variableDeclarator(node.id, call)
|
|
144
|
-
])
|
|
145
|
-
);
|
|
146
|
-
},
|
|
147
|
-
// 缺陷 2 修复:函数表达式 / 箭头函数组件
|
|
148
|
-
// const X = function (props) {...}
|
|
149
|
-
// const X = (props) => <JSX> / (props) => { ...; return function(){...} }
|
|
150
|
-
VariableDeclarator(path) {
|
|
151
|
-
const node = path.node;
|
|
152
|
-
const id = node.id;
|
|
153
|
-
if (!t.isIdentifier(id) || !/^[A-Z]/.test(id.name)) return;
|
|
154
|
-
const init = node.init;
|
|
155
|
-
const isFn = t.isFunctionExpression(init) || t.isArrowFunctionExpression(init);
|
|
156
|
-
if (!isFn) return;
|
|
157
|
-
const initPath = path.get("init");
|
|
158
|
-
assertNoSetupStyleEarlyReturns(initPath, id.name);
|
|
159
|
-
const wrapped = wrapComponentFn(init, id.name, initPath);
|
|
160
|
-
if (!wrapped) return;
|
|
161
|
-
const call = wrapped;
|
|
162
|
-
hasTransformed = true;
|
|
163
|
-
wrapEarlyReturns(initPath);
|
|
164
|
-
node.init = call;
|
|
165
|
-
},
|
|
166
|
-
// 顺带支持:export default (props) => <JSX>(默认导出箭头/函数/匿名函数组件)
|
|
167
|
-
// JSX 编译:组件转换(含 <solid> 提取)之后剩余 JSX → _jsx 调用
|
|
168
|
-
JSXElement(path) {
|
|
169
|
-
const name = path.node.openingElement.name;
|
|
170
|
-
if (t.isJSXIdentifier(name) && name.name === "solid") {
|
|
171
|
-
path.replaceWith(buildSolidMark(path.node, jstate));
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
path.replaceWith(compileJsxElement(path.node, jstate));
|
|
175
|
-
},
|
|
176
|
-
JSXFragment(path) {
|
|
177
|
-
path.replaceWith(compileJsxFragment(path.node, jstate));
|
|
178
|
-
},
|
|
179
|
-
ExportDefaultDeclaration(path) {
|
|
180
|
-
const decl = path.node.declaration;
|
|
181
|
-
const isFn = t.isFunctionExpression(decl) || t.isArrowFunctionExpression(decl) || // export default function() {...}(匿名函数声明)
|
|
182
|
-
t.isFunctionDeclaration(decl);
|
|
183
|
-
if (!isFn) return;
|
|
184
|
-
const fn = t.isFunctionDeclaration(decl) ? t.functionExpression(null, decl.params, decl.body, false, false) : decl;
|
|
185
|
-
if (t.isFunctionDeclaration(decl) && decl.typeParameters) {
|
|
186
|
-
;
|
|
187
|
-
fn.typeParameters = decl.typeParameters;
|
|
188
|
-
}
|
|
189
|
-
const declPath = path.get("declaration");
|
|
190
|
-
assertNoSetupStyleEarlyReturns(declPath);
|
|
191
|
-
const wrapped = wrapComponentFn(fn, void 0, path);
|
|
192
|
-
if (!wrapped) return;
|
|
193
|
-
const call = wrapped;
|
|
194
|
-
hasTransformed = true;
|
|
195
|
-
wrapEarlyReturns(declPath);
|
|
196
|
-
path.node.declaration = call;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
function wrapComponentFn(fn, name, fnPath) {
|
|
202
|
-
const body = fn.body;
|
|
203
|
-
const isExprBody = !t.isBlockStatement(body);
|
|
204
|
-
let last = null;
|
|
205
|
-
let ret;
|
|
206
|
-
if (isExprBody) {
|
|
207
|
-
ret = body;
|
|
208
|
-
} else {
|
|
209
|
-
const stmts = body.body;
|
|
210
|
-
if (stmts.length === 0) return null;
|
|
211
|
-
last = stmts[stmts.length - 1];
|
|
212
|
-
if (!t.isReturnStatement(last)) return null;
|
|
213
|
-
ret = last.argument;
|
|
214
|
-
if (ret == null) return null;
|
|
215
|
-
}
|
|
216
|
-
const isJsx = t.isJSXElement(ret) || t.isJSXFragment(ret);
|
|
217
|
-
const isJsxCall = t.isCallExpression(ret) && t.isIdentifier(ret.callee) && /^_?jsx/.test(ret.callee.name);
|
|
218
|
-
const isNullRet = t.isNullLiteral(ret);
|
|
219
|
-
const isCondRet = isRenderExpr(ret);
|
|
220
|
-
if (!isJsx && !isJsxCall && !isNullRet && !isCondRet) {
|
|
221
|
-
const returnsFn = t.isArrowFunctionExpression(ret) || t.isFunctionExpression(ret);
|
|
222
|
-
if (returnsFn && (name !== void 0 || containsRenderNode(ret))) {
|
|
223
|
-
throw buildSetupStyleError(fnPath, name);
|
|
224
|
-
}
|
|
225
|
-
return null;
|
|
226
|
-
}
|
|
227
|
-
if (isJsx) walkJSX(ret);
|
|
228
|
-
if (isExprBody) {
|
|
229
|
-
fn.body = t.blockStatement([
|
|
230
|
-
t.returnStatement(t.arrowFunctionExpression([], ret))
|
|
231
|
-
]);
|
|
232
|
-
} else if (isJsx || isJsxCall || isCondRet) {
|
|
233
|
-
last.argument = t.arrowFunctionExpression([], ret);
|
|
234
|
-
} else if (isNullRet) {
|
|
235
|
-
last.argument = t.arrowFunctionExpression([], t.nullLiteral());
|
|
236
|
-
}
|
|
237
|
-
const args = [fn];
|
|
238
|
-
if (name) args.push(t.stringLiteral(name));
|
|
239
|
-
return t.callExpression(t.identifier("defineComponent"), args);
|
|
240
|
-
}
|
|
241
|
-
function assertNoSetupStyleEarlyReturns(fnPath, name) {
|
|
242
|
-
const body = fnPath.node.body;
|
|
243
|
-
if (!t.isBlockStatement(body)) return;
|
|
244
|
-
const stmts = body.body;
|
|
245
|
-
const trailing = stmts.length ? stmts[stmts.length - 1] : null;
|
|
246
|
-
fnPath.traverse({
|
|
247
|
-
ReturnStatement(retPath) {
|
|
248
|
-
if (retPath.getFunctionParent() !== fnPath) return;
|
|
249
|
-
if (trailing && retPath.node === trailing) return;
|
|
250
|
-
const arg = retPath.node.argument;
|
|
251
|
-
if (t.isArrowFunctionExpression(arg) || t.isFunctionExpression(arg)) {
|
|
252
|
-
throw buildSetupStyleError(retPath, name);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
function buildSetupStyleError(fnPath, name) {
|
|
258
|
-
const label = name ? `\u7EC4\u4EF6 ${name}` : "\u7EC4\u4EF6\u51FD\u6570";
|
|
259
|
-
const msg = `[actview] \u5DF2\u5E9F\u5F03\u7684 setup \u98CE\u683C\uFF1A${label}\u4F53\u5185 return \u4E86\u6E32\u67D3\u51FD\u6570\uFF08() => JSX / function () { JSX }\uFF09\u3002
|
|
260
|
-
ActView \u53EA\u652F\u6301\u7B80\u5199\u7EC4\u4EF6\u2014\u2014\u76F4\u63A5 return JSX\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u5305\u88C5 render \u51FD\u6570\uFF1A
|
|
261
|
-
|
|
262
|
-
\u2717 function App() { return () => <div /> }
|
|
263
|
-
\u2713 function App() { return <div /> }
|
|
264
|
-
`;
|
|
265
|
-
try {
|
|
266
|
-
return fnPath.buildCodeFrameError(msg);
|
|
267
|
-
} catch {
|
|
268
|
-
return new Error(msg);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
function containsRenderNode(node, seen = /* @__PURE__ */ new Set()) {
|
|
272
|
-
if (!node || typeof node !== "object" || seen.has(node)) return false;
|
|
273
|
-
seen.add(node);
|
|
274
|
-
if (t.isJSXElement(node) || t.isJSXFragment(node)) return true;
|
|
275
|
-
if (t.isCallExpression(node) && t.isIdentifier(node.callee) && /^_?jsx/.test(node.callee.name)) {
|
|
276
|
-
return true;
|
|
277
|
-
}
|
|
278
|
-
for (const k in node) {
|
|
279
|
-
if (k === "leadingComments" || k === "trailingComments") continue;
|
|
280
|
-
const v = node[k];
|
|
281
|
-
if (Array.isArray(v)) {
|
|
282
|
-
if (v.some((c) => containsRenderNode(c, seen))) return true;
|
|
283
|
-
} else if (v !== null && typeof v === "object") {
|
|
284
|
-
if (containsRenderNode(v, seen)) return true;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
function wrapEarlyReturns(fnPath) {
|
|
290
|
-
fnPath.traverse({
|
|
291
|
-
ReturnStatement(innerPath) {
|
|
292
|
-
if (innerPath.getFunctionParent() !== fnPath) return;
|
|
293
|
-
const arg = innerPath.node.argument;
|
|
294
|
-
if (arg == null) return;
|
|
295
|
-
const isStmtJsx = t.isJSXElement(arg) || t.isJSXFragment(arg);
|
|
296
|
-
const isStmtJsxCall = t.isCallExpression(arg) && t.isIdentifier(arg.callee) && /^_?jsx/.test(arg.callee.name);
|
|
297
|
-
const isStmtNull = t.isNullLiteral(arg);
|
|
298
|
-
const isStmtCond = isRenderExpr(arg);
|
|
299
|
-
if (isStmtJsx || isStmtJsxCall || isStmtNull || isStmtCond) {
|
|
300
|
-
innerPath.node.argument = t.arrowFunctionExpression([], arg);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
function isRenderExpr(expr) {
|
|
306
|
-
if (!expr) return false;
|
|
307
|
-
if (t.isJSXElement(expr) || t.isJSXFragment(expr)) return true;
|
|
308
|
-
if (t.isCallExpression(expr) && t.isIdentifier(expr.callee) && /^_?jsx/.test(expr.callee.name)) {
|
|
309
|
-
return true;
|
|
310
|
-
}
|
|
311
|
-
if (t.isConditionalExpression(expr)) {
|
|
312
|
-
return isRenderExpr(expr.consequent) || isRenderExpr(expr.alternate);
|
|
313
|
-
}
|
|
314
|
-
if (t.isLogicalExpression(expr)) {
|
|
315
|
-
return isRenderExpr(expr.right) || isRenderExpr(expr.left);
|
|
316
|
-
}
|
|
317
|
-
return false;
|
|
318
|
-
}
|
|
319
|
-
function compileJsxElement(el, state) {
|
|
320
|
-
const name = el.openingElement.name;
|
|
321
|
-
let typeExpr;
|
|
322
|
-
if (t.isJSXIdentifier(name)) {
|
|
323
|
-
typeExpr = /^[a-z]/.test(name.name) ? t.stringLiteral(name.name) : t.identifier(name.name);
|
|
324
|
-
} else if (t.isJSXMemberExpression(name)) {
|
|
325
|
-
typeExpr = jsxMemberToMember(name);
|
|
326
|
-
} else {
|
|
327
|
-
typeExpr = t.stringLiteral(name.name);
|
|
328
|
-
}
|
|
329
|
-
let keyExpr = null;
|
|
330
|
-
const propEntries = [];
|
|
331
|
-
for (const attr of el.openingElement.attributes) {
|
|
332
|
-
if (t.isJSXSpreadAttribute(attr)) {
|
|
333
|
-
propEntries.push(t.spreadElement(attr.argument));
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
const aname = attr.name.name;
|
|
337
|
-
let value;
|
|
338
|
-
if (attr.value == null) {
|
|
339
|
-
value = t.booleanLiteral(true);
|
|
340
|
-
} else if (t.isStringLiteral(attr.value)) {
|
|
341
|
-
value = attr.value;
|
|
342
|
-
} else {
|
|
343
|
-
value = attr.value.expression;
|
|
344
|
-
}
|
|
345
|
-
if (aname === "key") {
|
|
346
|
-
keyExpr = t.isStringLiteral(value) ? value : value;
|
|
347
|
-
continue;
|
|
348
|
-
}
|
|
349
|
-
propEntries.push(t.objectProperty(t.stringLiteral(aname), value));
|
|
350
|
-
}
|
|
351
|
-
const children = compileJsxChildren(el.children, state);
|
|
352
|
-
if (children.length === 1) {
|
|
353
|
-
propEntries.push(t.objectProperty(t.stringLiteral("children"), children[0]));
|
|
354
|
-
} else if (children.length > 1) {
|
|
355
|
-
propEntries.push(
|
|
356
|
-
t.objectProperty(t.stringLiteral("children"), t.arrayExpression(children))
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
state.usedJsx = true;
|
|
360
|
-
const args = [typeExpr, t.objectExpression(propEntries)];
|
|
361
|
-
args.push(keyExpr ?? t.identifier("undefined"));
|
|
362
|
-
return t.callExpression(t.identifier("_jsx"), args);
|
|
363
|
-
}
|
|
364
|
-
function compileJsxFragment(frag, state) {
|
|
365
|
-
const children = compileJsxChildren(frag.children, state);
|
|
366
|
-
state.usedJsx = true;
|
|
367
|
-
state.usedFragment = true;
|
|
368
|
-
const propEntries = [];
|
|
369
|
-
if (children.length === 1) {
|
|
370
|
-
propEntries.push(t.objectProperty(t.stringLiteral("children"), children[0]));
|
|
371
|
-
} else if (children.length > 1) {
|
|
372
|
-
propEntries.push(
|
|
373
|
-
t.objectProperty(t.stringLiteral("children"), t.arrayExpression(children))
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
return t.callExpression(t.identifier("_jsx"), [
|
|
377
|
-
t.identifier("_Fragment"),
|
|
378
|
-
t.objectExpression(propEntries),
|
|
379
|
-
t.identifier("undefined")
|
|
380
|
-
]);
|
|
381
|
-
}
|
|
382
|
-
function compileJsxChildren(children, state) {
|
|
383
|
-
const out = [];
|
|
384
|
-
for (const c of children) {
|
|
385
|
-
if (t.isJSXText(c)) {
|
|
386
|
-
if (c.value.trim() === "") continue;
|
|
387
|
-
out.push(t.stringLiteral(processJsxText(c.value)));
|
|
388
|
-
} else if (t.isJSXExpressionContainer(c)) {
|
|
389
|
-
if (t.isJSXEmptyExpression(c.expression)) continue;
|
|
390
|
-
out.push(c.expression);
|
|
391
|
-
} else if (t.isJSXElement(c)) {
|
|
392
|
-
const cname = c.openingElement.name;
|
|
393
|
-
if (t.isJSXIdentifier(cname) && cname.name === "solid") {
|
|
394
|
-
out.push(buildSolidMark(c, state));
|
|
395
|
-
} else {
|
|
396
|
-
out.push(compileJsxElement(c, state));
|
|
397
|
-
}
|
|
398
|
-
} else if (t.isJSXFragment(c)) {
|
|
399
|
-
out.push(compileJsxFragment(c, state));
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
return out;
|
|
403
|
-
}
|
|
404
|
-
function jsxMemberToMember(name) {
|
|
405
|
-
const obj = t.isJSXMemberExpression(name.object) ? jsxMemberToMember(name.object) : t.identifier(name.object.name);
|
|
406
|
-
return t.memberExpression(obj, t.identifier(name.property.name));
|
|
407
|
-
}
|
|
408
|
-
function processJsxText(value) {
|
|
409
|
-
if (!value.includes("\n")) return value;
|
|
410
|
-
return value.replace(/^[ \t]*\n[ \t]*/, "").replace(/[ \t]*\n[ \t]*$/, "").replace(/[ \t]*\n[ \t]*/g, " ");
|
|
411
|
-
}
|
|
412
|
-
function buildSolidMark(el, state) {
|
|
413
|
-
state.usedJsx = true;
|
|
414
|
-
const parts = [];
|
|
415
|
-
for (const c of el.children) {
|
|
416
|
-
if (t.isJSXText(c)) {
|
|
417
|
-
if (c.value.trim() === "") continue;
|
|
418
|
-
parts.push(c.value);
|
|
419
|
-
} else if (t.isJSXExpressionContainer(c)) {
|
|
420
|
-
if (t.isJSXEmptyExpression(c.expression)) continue;
|
|
421
|
-
parts.push(generate(c.expression).code);
|
|
422
|
-
} else {
|
|
423
|
-
parts.push(generate(c).code);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
return t.callExpression(t.identifier("_jsx"), [
|
|
427
|
-
t.stringLiteral("solid"),
|
|
428
|
-
t.objectExpression([
|
|
429
|
-
t.objectProperty(
|
|
430
|
-
t.stringLiteral("children"),
|
|
431
|
-
t.arrayExpression(parts.map((p) => t.stringLiteral(p)))
|
|
432
|
-
)
|
|
433
|
-
]),
|
|
434
|
-
t.identifier("undefined")
|
|
435
|
-
]);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
1
|
// src/babel-host.ts
|
|
439
2
|
import * as babel from "@babel/core";
|
|
440
3
|
var NODE_MODULES_RE = /(^|[\\/])node_modules[\\/]/;
|
|
@@ -450,8 +13,11 @@ function isExcludedTransform(filename, options) {
|
|
|
450
13
|
if (options?.exclude?.some((r) => matchesRule(r, norm))) return true;
|
|
451
14
|
return false;
|
|
452
15
|
}
|
|
453
|
-
function createBabelItem(plugin) {
|
|
454
|
-
return babel.createConfigItemSync(
|
|
16
|
+
function createBabelItem(plugin, pluginOptions) {
|
|
17
|
+
return babel.createConfigItemSync(
|
|
18
|
+
pluginOptions == null ? plugin : [plugin, pluginOptions],
|
|
19
|
+
{ type: "plugin" }
|
|
20
|
+
);
|
|
455
21
|
}
|
|
456
22
|
function transformWithBabel(code, filename, pluginItem, options) {
|
|
457
23
|
if (isExcludedTransform(filename, options)) return null;
|
|
@@ -484,308 +50,9 @@ function createBabelTransform(plugin, options) {
|
|
|
484
50
|
return { code: result.code || code, map: result.map };
|
|
485
51
|
};
|
|
486
52
|
}
|
|
487
|
-
|
|
488
|
-
// src/solid-plugin.ts
|
|
489
|
-
import { types as t2, parseSync } from "@babel/core";
|
|
490
|
-
var solidVarCounter = 0;
|
|
491
|
-
function solidPlugin() {
|
|
492
|
-
let usedSolid = false;
|
|
493
|
-
return {
|
|
494
|
-
visitor: {
|
|
495
|
-
Program: {
|
|
496
|
-
enter() {
|
|
497
|
-
usedSolid = false;
|
|
498
|
-
solidVarCounter = 0;
|
|
499
|
-
},
|
|
500
|
-
exit(path) {
|
|
501
|
-
path.traverse({
|
|
502
|
-
CallExpression(p) {
|
|
503
|
-
handleSolidCall(p, () => {
|
|
504
|
-
usedSolid = true;
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
});
|
|
508
|
-
if (!usedSolid) return;
|
|
509
|
-
const hasImport = path.node.body.some(
|
|
510
|
-
(n) => t2.isImportDeclaration(n) && n.source.value === "@actview/core" && n.specifiers.some((s) => s.imported?.name === "solidGet")
|
|
511
|
-
);
|
|
512
|
-
if (!hasImport) {
|
|
513
|
-
path.node.body.unshift(
|
|
514
|
-
t2.importDeclaration(
|
|
515
|
-
["solidGet", "createEffect", "mapArray"].map(
|
|
516
|
-
(n) => t2.importSpecifier(t2.identifier(n), t2.identifier(n))
|
|
517
|
-
),
|
|
518
|
-
t2.stringLiteral("@actview/core")
|
|
519
|
-
)
|
|
520
|
-
);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
};
|
|
526
|
-
}
|
|
527
|
-
function handleSolidCall(path, markUsed) {
|
|
528
|
-
const node = path.node;
|
|
529
|
-
if (!(t2.isIdentifier(node.callee) && /^_?jsx/.test(node.callee.name))) return;
|
|
530
|
-
if (!(node.arguments[0] && t2.isStringLiteral(node.arguments[0], { value: "solid" }))) return;
|
|
531
|
-
const propsObj = node.arguments[1];
|
|
532
|
-
if (!t2.isObjectExpression(propsObj)) return;
|
|
533
|
-
const childrenProp = propsObj.properties.find(
|
|
534
|
-
(p) => t2.isObjectProperty(p) && t2.isStringLiteral(p.key, { value: "children" })
|
|
535
|
-
);
|
|
536
|
-
if (!childrenProp || !t2.isArrayExpression(childrenProp.value)) return;
|
|
537
|
-
const srcs = [];
|
|
538
|
-
for (const e of childrenProp.value.elements) {
|
|
539
|
-
if (e && t2.isStringLiteral(e)) srcs.push(e.value);
|
|
540
|
-
}
|
|
541
|
-
if (srcs.length === 0 || srcs.every((s) => !s.trim())) return;
|
|
542
|
-
const counter = { n: 0 };
|
|
543
|
-
const stmts = [];
|
|
544
|
-
try {
|
|
545
|
-
for (const src of srcs) {
|
|
546
|
-
const ast = parseSync(src, { parserOpts: { plugins: ["jsx", "typescript"] } });
|
|
547
|
-
if (!ast) return;
|
|
548
|
-
for (const st of ast.program.body) {
|
|
549
|
-
if (t2.isExpressionStatement(st)) {
|
|
550
|
-
compileSolidTop(st.expression, t2.identifier("container"), stmts, counter);
|
|
551
|
-
} else {
|
|
552
|
-
stmts.push(st);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
} catch (e) {
|
|
557
|
-
console.error("[solid-plugin] compile error:", e?.message);
|
|
558
|
-
return;
|
|
559
|
-
}
|
|
560
|
-
if (stmts.length === 0) return;
|
|
561
|
-
markUsed();
|
|
562
|
-
const holderId = t2.identifier("_solid$$" + ++solidVarCounter);
|
|
563
|
-
const renderFn = path.getFunctionParent();
|
|
564
|
-
const setupFn = renderFn && renderFn.getFunctionParent();
|
|
565
|
-
const holderDecl = t2.variableDeclaration("const", [
|
|
566
|
-
t2.variableDeclarator(holderId, t2.objectExpression([]))
|
|
567
|
-
]);
|
|
568
|
-
if (setupFn && t2.isFunction(setupFn.node)) {
|
|
569
|
-
setupFn.get("body").unshiftContainer("body", holderDecl);
|
|
570
|
-
} else {
|
|
571
|
-
const prog = path.findParent((p) => p.isProgram());
|
|
572
|
-
prog?.unshiftContainer("body", holderDecl);
|
|
573
|
-
}
|
|
574
|
-
path.replaceWith(
|
|
575
|
-
t2.callExpression(t2.identifier("solidGet"), [
|
|
576
|
-
holderId,
|
|
577
|
-
t2.arrowFunctionExpression(
|
|
578
|
-
[t2.identifier("container")],
|
|
579
|
-
t2.blockStatement(stmts)
|
|
580
|
-
)
|
|
581
|
-
])
|
|
582
|
-
);
|
|
583
|
-
}
|
|
584
|
-
function compileSolidTop(expr, containerVar, stmts, counter) {
|
|
585
|
-
if (t2.isJSXElement(expr)) {
|
|
586
|
-
return compileSolidElement(expr, stmts, counter);
|
|
587
|
-
}
|
|
588
|
-
if (t2.isJSXFragment(expr)) {
|
|
589
|
-
compileSolidChildren(expr.children, containerVar, stmts, counter);
|
|
590
|
-
return null;
|
|
591
|
-
}
|
|
592
|
-
const mapCall = matchMapCall(expr);
|
|
593
|
-
if (mapCall) {
|
|
594
|
-
stmts.push(
|
|
595
|
-
t2.expressionStatement(
|
|
596
|
-
t2.callExpression(t2.identifier("mapArray"), [
|
|
597
|
-
t2.arrowFunctionExpression([], mapCall.listExpr),
|
|
598
|
-
containerVar,
|
|
599
|
-
compileMapArrow(mapCall.arrow, counter)
|
|
600
|
-
])
|
|
601
|
-
)
|
|
602
|
-
);
|
|
603
|
-
return null;
|
|
604
|
-
}
|
|
605
|
-
const textVar = t2.identifier("_t" + ++counter.n);
|
|
606
|
-
stmts.push(
|
|
607
|
-
t2.variableDeclaration("const", [
|
|
608
|
-
t2.variableDeclarator(
|
|
609
|
-
textVar,
|
|
610
|
-
t2.callExpression(t2.memberExpression(t2.identifier("document"), t2.identifier("createTextNode")), [
|
|
611
|
-
t2.stringLiteral("")
|
|
612
|
-
])
|
|
613
|
-
)
|
|
614
|
-
])
|
|
615
|
-
);
|
|
616
|
-
stmts.push(
|
|
617
|
-
t2.expressionStatement(
|
|
618
|
-
t2.callExpression(t2.identifier("createEffect"), [
|
|
619
|
-
t2.arrowFunctionExpression(
|
|
620
|
-
[],
|
|
621
|
-
t2.assignmentExpression(
|
|
622
|
-
"=",
|
|
623
|
-
t2.memberExpression(textVar, t2.identifier("textContent")),
|
|
624
|
-
expr
|
|
625
|
-
)
|
|
626
|
-
)
|
|
627
|
-
])
|
|
628
|
-
)
|
|
629
|
-
);
|
|
630
|
-
stmts.push(appendStmt(containerVar, textVar));
|
|
631
|
-
return null;
|
|
632
|
-
}
|
|
633
|
-
function compileSolidChildren(children, containerVar, stmts, counter) {
|
|
634
|
-
for (const c of children) {
|
|
635
|
-
if (t2.isJSXText(c)) {
|
|
636
|
-
if (c.value.trim() === "") continue;
|
|
637
|
-
const textVar = t2.identifier("_t" + ++counter.n);
|
|
638
|
-
stmts.push(
|
|
639
|
-
t2.variableDeclaration("const", [
|
|
640
|
-
t2.variableDeclarator(
|
|
641
|
-
textVar,
|
|
642
|
-
t2.callExpression(t2.memberExpression(t2.identifier("document"), t2.identifier("createTextNode")), [
|
|
643
|
-
t2.stringLiteral(c.value)
|
|
644
|
-
])
|
|
645
|
-
)
|
|
646
|
-
])
|
|
647
|
-
);
|
|
648
|
-
stmts.push(appendStmt(containerVar, textVar));
|
|
649
|
-
} else if (t2.isJSXExpressionContainer(c)) {
|
|
650
|
-
const expr = c.expression;
|
|
651
|
-
if (t2.isJSXEmptyExpression(expr)) continue;
|
|
652
|
-
const mapCall = matchMapCall(expr);
|
|
653
|
-
if (mapCall) {
|
|
654
|
-
stmts.push(
|
|
655
|
-
t2.expressionStatement(
|
|
656
|
-
t2.callExpression(t2.identifier("mapArray"), [
|
|
657
|
-
t2.arrowFunctionExpression([], mapCall.listExpr),
|
|
658
|
-
containerVar,
|
|
659
|
-
compileMapArrow(mapCall.arrow, counter)
|
|
660
|
-
])
|
|
661
|
-
)
|
|
662
|
-
);
|
|
663
|
-
} else {
|
|
664
|
-
const textVar = t2.identifier("_t" + ++counter.n);
|
|
665
|
-
stmts.push(
|
|
666
|
-
t2.variableDeclaration("const", [
|
|
667
|
-
t2.variableDeclarator(
|
|
668
|
-
textVar,
|
|
669
|
-
t2.callExpression(t2.memberExpression(t2.identifier("document"), t2.identifier("createTextNode")), [
|
|
670
|
-
t2.stringLiteral("")
|
|
671
|
-
])
|
|
672
|
-
)
|
|
673
|
-
])
|
|
674
|
-
);
|
|
675
|
-
stmts.push(
|
|
676
|
-
t2.expressionStatement(
|
|
677
|
-
t2.callExpression(t2.identifier("createEffect"), [
|
|
678
|
-
t2.arrowFunctionExpression(
|
|
679
|
-
[],
|
|
680
|
-
t2.assignmentExpression(
|
|
681
|
-
"=",
|
|
682
|
-
t2.memberExpression(textVar, t2.identifier("textContent")),
|
|
683
|
-
expr
|
|
684
|
-
)
|
|
685
|
-
)
|
|
686
|
-
])
|
|
687
|
-
)
|
|
688
|
-
);
|
|
689
|
-
stmts.push(appendStmt(containerVar, textVar));
|
|
690
|
-
}
|
|
691
|
-
} else if (t2.isJSXElement(c)) {
|
|
692
|
-
const elVar = compileSolidElement(c, stmts, counter);
|
|
693
|
-
stmts.push(appendStmt(containerVar, elVar));
|
|
694
|
-
} else if (t2.isJSXFragment(c)) {
|
|
695
|
-
compileSolidChildren(c.children, containerVar, stmts, counter);
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
function compileSolidElement(el, stmts, counter) {
|
|
700
|
-
const name = el.openingElement.name;
|
|
701
|
-
const tag = t2.isJSXIdentifier(name) ? name.name : name.name;
|
|
702
|
-
const elVar = t2.identifier("_el" + ++counter.n);
|
|
703
|
-
stmts.push(
|
|
704
|
-
t2.variableDeclaration("const", [
|
|
705
|
-
t2.variableDeclarator(
|
|
706
|
-
elVar,
|
|
707
|
-
t2.callExpression(t2.memberExpression(t2.identifier("document"), t2.identifier("createElement")), [
|
|
708
|
-
t2.stringLiteral(tag)
|
|
709
|
-
])
|
|
710
|
-
)
|
|
711
|
-
])
|
|
712
|
-
);
|
|
713
|
-
for (const attr of el.openingElement.attributes) {
|
|
714
|
-
if (!t2.isJSXAttribute(attr)) continue;
|
|
715
|
-
const attrName = attr.name.name;
|
|
716
|
-
if (attrName === "key" || attrName === "ref" || attrName === "v-memo") continue;
|
|
717
|
-
if (/^on[A-Z]/.test(attrName)) {
|
|
718
|
-
const evt = attrName[2].toLowerCase() + attrName.slice(3);
|
|
719
|
-
const handler = attr.value?.expression ?? attr.value ?? t2.identifier("undefined");
|
|
720
|
-
stmts.push(
|
|
721
|
-
t2.expressionStatement(
|
|
722
|
-
t2.callExpression(t2.memberExpression(elVar, t2.identifier("addEventListener")), [
|
|
723
|
-
t2.stringLiteral(evt),
|
|
724
|
-
handler
|
|
725
|
-
])
|
|
726
|
-
)
|
|
727
|
-
);
|
|
728
|
-
continue;
|
|
729
|
-
}
|
|
730
|
-
if (attr.value && t2.isJSXExpressionContainer(attr.value)) {
|
|
731
|
-
stmts.push(
|
|
732
|
-
t2.expressionStatement(
|
|
733
|
-
t2.callExpression(t2.identifier("createEffect"), [
|
|
734
|
-
t2.arrowFunctionExpression(
|
|
735
|
-
[],
|
|
736
|
-
t2.callExpression(t2.memberExpression(elVar, t2.identifier("setAttribute")), [
|
|
737
|
-
t2.stringLiteral(attrName),
|
|
738
|
-
attr.value.expression
|
|
739
|
-
])
|
|
740
|
-
)
|
|
741
|
-
])
|
|
742
|
-
)
|
|
743
|
-
);
|
|
744
|
-
} else {
|
|
745
|
-
const value = attr.value ? t2.isStringLiteral(attr.value) ? attr.value.value : true : true;
|
|
746
|
-
stmts.push(
|
|
747
|
-
t2.expressionStatement(
|
|
748
|
-
t2.callExpression(t2.memberExpression(elVar, t2.identifier("setAttribute")), [
|
|
749
|
-
t2.stringLiteral(attrName),
|
|
750
|
-
value === true ? t2.stringLiteral("true") : t2.stringLiteral(value)
|
|
751
|
-
])
|
|
752
|
-
)
|
|
753
|
-
);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
compileSolidChildren(el.children, elVar, stmts, counter);
|
|
757
|
-
return elVar;
|
|
758
|
-
}
|
|
759
|
-
function appendStmt(containerVar, childVar) {
|
|
760
|
-
return t2.expressionStatement(
|
|
761
|
-
t2.callExpression(t2.memberExpression(containerVar, t2.identifier("appendChild")), [childVar])
|
|
762
|
-
);
|
|
763
|
-
}
|
|
764
|
-
function matchMapCall(expr) {
|
|
765
|
-
if (t2.isCallExpression(expr) && t2.isMemberExpression(expr.callee) && t2.isIdentifier(expr.callee.property, { name: "map" }) && expr.arguments.length === 1 && t2.isArrowFunctionExpression(expr.arguments[0])) {
|
|
766
|
-
return { listExpr: expr.callee.object, arrow: expr.arguments[0] };
|
|
767
|
-
}
|
|
768
|
-
return null;
|
|
769
|
-
}
|
|
770
|
-
function compileMapArrow(arrow, counter) {
|
|
771
|
-
const stmts = [];
|
|
772
|
-
const bodyExpr = arrow.body;
|
|
773
|
-
if (t2.isJSXElement(bodyExpr)) {
|
|
774
|
-
const elVar = compileSolidElement(bodyExpr, stmts, counter);
|
|
775
|
-
stmts.push(t2.returnStatement(elVar));
|
|
776
|
-
return t2.arrowFunctionExpression(arrow.params, t2.blockStatement(stmts));
|
|
777
|
-
}
|
|
778
|
-
if (t2.isJSXFragment(bodyExpr)) {
|
|
779
|
-
return arrow;
|
|
780
|
-
}
|
|
781
|
-
return arrow;
|
|
782
|
-
}
|
|
783
53
|
export {
|
|
784
54
|
createBabelItem,
|
|
785
55
|
createBabelTransform,
|
|
786
|
-
defineComponentPlugin as default,
|
|
787
|
-
defineComponentPlugin,
|
|
788
56
|
isExcludedTransform,
|
|
789
|
-
solidPlugin,
|
|
790
57
|
transformWithBabel
|
|
791
58
|
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actview/plugin-babel",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Babel
|
|
5
|
+
"description": "共享 Babel 宿主壳(排除规则/transformSync 参数统一,供 @actview/plugin-vite 与 @actview/plugin-scoped 复用)",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
8
8
|
"types": "./dist/index.d.ts",
|