@actview/plugin-babel 2.0.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 -64
- package/dist/index.d.ts +16 -29
- package/dist/index.js +21 -738
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,64 +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
|
-
- `@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/
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## License
|
|
63
|
-
|
|
64
|
-
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) */
|
|
@@ -21,23 +7,24 @@ interface BabelHostResult {
|
|
|
21
7
|
code: string;
|
|
22
8
|
map: unknown;
|
|
23
9
|
}
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
|
|
10
|
+
/** 宿主壳排除规则(createBabelTransform / transformWithBabel 第二/四参) */
|
|
11
|
+
interface BabelTransformOptions {
|
|
12
|
+
/** 白名单:文件命中任一规则才转换(默认不过滤;node_modules 硬排除优先) */
|
|
13
|
+
include?: Array<string | RegExp>;
|
|
14
|
+
/** 黑名单:命中任一规则即跳过(优先级高于 include) */
|
|
15
|
+
exclude?: Array<string | RegExp>;
|
|
16
|
+
}
|
|
17
|
+
/** 是否应跳过转换:node_modules 硬排除 / 未命中 include / 命中 exclude */
|
|
18
|
+
declare function isExcludedTransform(filename: string, options?: BabelTransformOptions): boolean;
|
|
19
|
+
/** 把插件工厂预编译为 ConfigItem(Babel 8 同步版本,可跨多次 transformSync 复用);
|
|
20
|
+
* pluginOptions 非空时按 [plugin, options] 元组创建(Babel 标准插件选项) */
|
|
21
|
+
declare function createBabelItem(plugin: BabelPlugin, pluginOptions?: object): PluginItem;
|
|
22
|
+
/** 统一参数的 transformSync:排除命中或失败返回 null,成功返回 { code, map } */
|
|
23
|
+
declare function transformWithBabel(code: string, filename: string, pluginItem: PluginItem, options?: BabelTransformOptions): BabelHostResult | null;
|
|
28
24
|
/**
|
|
29
25
|
* 静态插件的便捷工厂:模块级调用一次,ConfigItem 只创建一次。
|
|
30
26
|
* 适用于插件对象不随文件变化的场景(如 defineComponentPlugin)。
|
|
31
27
|
*/
|
|
32
|
-
declare function createBabelTransform(plugin: BabelPlugin | BabelPlugin[]): (code: string, filename: string) => BabelHostResult | null;
|
|
33
|
-
|
|
34
|
-
declare function solidPlugin(): {
|
|
35
|
-
visitor: {
|
|
36
|
-
Program: {
|
|
37
|
-
enter(): void;
|
|
38
|
-
exit(path: any): void;
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
};
|
|
28
|
+
declare function createBabelTransform(plugin: BabelPlugin | BabelPlugin[], options?: BabelTransformOptions): (code: string, filename: string) => BabelHostResult | null;
|
|
42
29
|
|
|
43
|
-
export { type BabelHostResult,
|
|
30
|
+
export { type BabelHostResult, type BabelTransformOptions, createBabelItem, createBabelTransform, isExcludedTransform, transformWithBabel };
|
package/dist/index.js
CHANGED
|
@@ -1,446 +1,26 @@
|
|
|
1
|
-
// src/babel-
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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)) {
|
|
1
|
+
// src/babel-host.ts
|
|
2
|
+
import * as babel from "@babel/core";
|
|
3
|
+
var NODE_MODULES_RE = /(^|[\\/])node_modules[\\/]/;
|
|
4
|
+
function matchesRule(rule, filename) {
|
|
5
|
+
return typeof rule === "string" ? filename.includes(rule) : rule.test(filename);
|
|
6
|
+
}
|
|
7
|
+
function isExcludedTransform(filename, options) {
|
|
8
|
+
const norm = filename.replace(/\\/g, "/");
|
|
9
|
+
if (NODE_MODULES_RE.test(norm)) return true;
|
|
10
|
+
if (options?.include?.length && !options.include.some((r) => matchesRule(r, norm))) {
|
|
276
11
|
return true;
|
|
277
12
|
}
|
|
278
|
-
|
|
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
|
-
}
|
|
13
|
+
if (options?.exclude?.some((r) => matchesRule(r, norm))) return true;
|
|
287
14
|
return false;
|
|
288
15
|
}
|
|
289
|
-
function
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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
|
-
// src/babel-host.ts
|
|
439
|
-
import * as babel from "@babel/core";
|
|
440
|
-
function createBabelItem(plugin) {
|
|
441
|
-
return babel.createConfigItemSync(plugin, { type: "plugin" });
|
|
16
|
+
function createBabelItem(plugin, pluginOptions) {
|
|
17
|
+
return babel.createConfigItemSync(
|
|
18
|
+
pluginOptions == null ? plugin : [plugin, pluginOptions],
|
|
19
|
+
{ type: "plugin" }
|
|
20
|
+
);
|
|
442
21
|
}
|
|
443
|
-
function transformWithBabel(code, filename, pluginItem) {
|
|
22
|
+
function transformWithBabel(code, filename, pluginItem, options) {
|
|
23
|
+
if (isExcludedTransform(filename, options)) return null;
|
|
444
24
|
const result = babel.transformSync(code, {
|
|
445
25
|
filename,
|
|
446
26
|
plugins: [pluginItem],
|
|
@@ -453,9 +33,10 @@ function transformWithBabel(code, filename, pluginItem) {
|
|
|
453
33
|
if (!result) return null;
|
|
454
34
|
return { code: result.code || code, map: result.map };
|
|
455
35
|
}
|
|
456
|
-
function createBabelTransform(plugin) {
|
|
36
|
+
function createBabelTransform(plugin, options) {
|
|
457
37
|
const items = (Array.isArray(plugin) ? plugin : [plugin]).map((p) => createBabelItem(p));
|
|
458
38
|
return (code, filename) => {
|
|
39
|
+
if (isExcludedTransform(filename, options)) return null;
|
|
459
40
|
const result = babel.transformSync(code, {
|
|
460
41
|
filename,
|
|
461
42
|
plugins: items,
|
|
@@ -469,307 +50,9 @@ function createBabelTransform(plugin) {
|
|
|
469
50
|
return { code: result.code || code, map: result.map };
|
|
470
51
|
};
|
|
471
52
|
}
|
|
472
|
-
|
|
473
|
-
// src/solid-plugin.ts
|
|
474
|
-
import { types as t2, parseSync } from "@babel/core";
|
|
475
|
-
var solidVarCounter = 0;
|
|
476
|
-
function solidPlugin() {
|
|
477
|
-
let usedSolid = false;
|
|
478
|
-
return {
|
|
479
|
-
visitor: {
|
|
480
|
-
Program: {
|
|
481
|
-
enter() {
|
|
482
|
-
usedSolid = false;
|
|
483
|
-
solidVarCounter = 0;
|
|
484
|
-
},
|
|
485
|
-
exit(path) {
|
|
486
|
-
path.traverse({
|
|
487
|
-
CallExpression(p) {
|
|
488
|
-
handleSolidCall(p, () => {
|
|
489
|
-
usedSolid = true;
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
if (!usedSolid) return;
|
|
494
|
-
const hasImport = path.node.body.some(
|
|
495
|
-
(n) => t2.isImportDeclaration(n) && n.source.value === "@actview/core" && n.specifiers.some((s) => s.imported?.name === "solidGet")
|
|
496
|
-
);
|
|
497
|
-
if (!hasImport) {
|
|
498
|
-
path.node.body.unshift(
|
|
499
|
-
t2.importDeclaration(
|
|
500
|
-
["solidGet", "createEffect", "mapArray"].map(
|
|
501
|
-
(n) => t2.importSpecifier(t2.identifier(n), t2.identifier(n))
|
|
502
|
-
),
|
|
503
|
-
t2.stringLiteral("@actview/core")
|
|
504
|
-
)
|
|
505
|
-
);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
};
|
|
511
|
-
}
|
|
512
|
-
function handleSolidCall(path, markUsed) {
|
|
513
|
-
const node = path.node;
|
|
514
|
-
if (!(t2.isIdentifier(node.callee) && /^_?jsx/.test(node.callee.name))) return;
|
|
515
|
-
if (!(node.arguments[0] && t2.isStringLiteral(node.arguments[0], { value: "solid" }))) return;
|
|
516
|
-
const propsObj = node.arguments[1];
|
|
517
|
-
if (!t2.isObjectExpression(propsObj)) return;
|
|
518
|
-
const childrenProp = propsObj.properties.find(
|
|
519
|
-
(p) => t2.isObjectProperty(p) && t2.isStringLiteral(p.key, { value: "children" })
|
|
520
|
-
);
|
|
521
|
-
if (!childrenProp || !t2.isArrayExpression(childrenProp.value)) return;
|
|
522
|
-
const srcs = [];
|
|
523
|
-
for (const e of childrenProp.value.elements) {
|
|
524
|
-
if (e && t2.isStringLiteral(e)) srcs.push(e.value);
|
|
525
|
-
}
|
|
526
|
-
if (srcs.length === 0 || srcs.every((s) => !s.trim())) return;
|
|
527
|
-
const counter = { n: 0 };
|
|
528
|
-
const stmts = [];
|
|
529
|
-
try {
|
|
530
|
-
for (const src of srcs) {
|
|
531
|
-
const ast = parseSync(src, { parserOpts: { plugins: ["jsx", "typescript"] } });
|
|
532
|
-
if (!ast) return;
|
|
533
|
-
for (const st of ast.program.body) {
|
|
534
|
-
if (t2.isExpressionStatement(st)) {
|
|
535
|
-
compileSolidTop(st.expression, t2.identifier("container"), stmts, counter);
|
|
536
|
-
} else {
|
|
537
|
-
stmts.push(st);
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
} catch (e) {
|
|
542
|
-
console.error("[solid-plugin] compile error:", e?.message);
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
|
-
if (stmts.length === 0) return;
|
|
546
|
-
markUsed();
|
|
547
|
-
const holderId = t2.identifier("_solid$$" + ++solidVarCounter);
|
|
548
|
-
const renderFn = path.getFunctionParent();
|
|
549
|
-
const setupFn = renderFn && renderFn.getFunctionParent();
|
|
550
|
-
const holderDecl = t2.variableDeclaration("const", [
|
|
551
|
-
t2.variableDeclarator(holderId, t2.objectExpression([]))
|
|
552
|
-
]);
|
|
553
|
-
if (setupFn && t2.isFunction(setupFn.node)) {
|
|
554
|
-
setupFn.get("body").unshiftContainer("body", holderDecl);
|
|
555
|
-
} else {
|
|
556
|
-
const prog = path.findParent((p) => p.isProgram());
|
|
557
|
-
prog?.unshiftContainer("body", holderDecl);
|
|
558
|
-
}
|
|
559
|
-
path.replaceWith(
|
|
560
|
-
t2.callExpression(t2.identifier("solidGet"), [
|
|
561
|
-
holderId,
|
|
562
|
-
t2.arrowFunctionExpression(
|
|
563
|
-
[t2.identifier("container")],
|
|
564
|
-
t2.blockStatement(stmts)
|
|
565
|
-
)
|
|
566
|
-
])
|
|
567
|
-
);
|
|
568
|
-
}
|
|
569
|
-
function compileSolidTop(expr, containerVar, stmts, counter) {
|
|
570
|
-
if (t2.isJSXElement(expr)) {
|
|
571
|
-
return compileSolidElement(expr, stmts, counter);
|
|
572
|
-
}
|
|
573
|
-
if (t2.isJSXFragment(expr)) {
|
|
574
|
-
compileSolidChildren(expr.children, containerVar, stmts, counter);
|
|
575
|
-
return null;
|
|
576
|
-
}
|
|
577
|
-
const mapCall = matchMapCall(expr);
|
|
578
|
-
if (mapCall) {
|
|
579
|
-
stmts.push(
|
|
580
|
-
t2.expressionStatement(
|
|
581
|
-
t2.callExpression(t2.identifier("mapArray"), [
|
|
582
|
-
t2.arrowFunctionExpression([], mapCall.listExpr),
|
|
583
|
-
containerVar,
|
|
584
|
-
compileMapArrow(mapCall.arrow, counter)
|
|
585
|
-
])
|
|
586
|
-
)
|
|
587
|
-
);
|
|
588
|
-
return null;
|
|
589
|
-
}
|
|
590
|
-
const textVar = t2.identifier("_t" + ++counter.n);
|
|
591
|
-
stmts.push(
|
|
592
|
-
t2.variableDeclaration("const", [
|
|
593
|
-
t2.variableDeclarator(
|
|
594
|
-
textVar,
|
|
595
|
-
t2.callExpression(t2.memberExpression(t2.identifier("document"), t2.identifier("createTextNode")), [
|
|
596
|
-
t2.stringLiteral("")
|
|
597
|
-
])
|
|
598
|
-
)
|
|
599
|
-
])
|
|
600
|
-
);
|
|
601
|
-
stmts.push(
|
|
602
|
-
t2.expressionStatement(
|
|
603
|
-
t2.callExpression(t2.identifier("createEffect"), [
|
|
604
|
-
t2.arrowFunctionExpression(
|
|
605
|
-
[],
|
|
606
|
-
t2.assignmentExpression(
|
|
607
|
-
"=",
|
|
608
|
-
t2.memberExpression(textVar, t2.identifier("textContent")),
|
|
609
|
-
expr
|
|
610
|
-
)
|
|
611
|
-
)
|
|
612
|
-
])
|
|
613
|
-
)
|
|
614
|
-
);
|
|
615
|
-
stmts.push(appendStmt(containerVar, textVar));
|
|
616
|
-
return null;
|
|
617
|
-
}
|
|
618
|
-
function compileSolidChildren(children, containerVar, stmts, counter) {
|
|
619
|
-
for (const c of children) {
|
|
620
|
-
if (t2.isJSXText(c)) {
|
|
621
|
-
if (c.value.trim() === "") continue;
|
|
622
|
-
const textVar = t2.identifier("_t" + ++counter.n);
|
|
623
|
-
stmts.push(
|
|
624
|
-
t2.variableDeclaration("const", [
|
|
625
|
-
t2.variableDeclarator(
|
|
626
|
-
textVar,
|
|
627
|
-
t2.callExpression(t2.memberExpression(t2.identifier("document"), t2.identifier("createTextNode")), [
|
|
628
|
-
t2.stringLiteral(c.value)
|
|
629
|
-
])
|
|
630
|
-
)
|
|
631
|
-
])
|
|
632
|
-
);
|
|
633
|
-
stmts.push(appendStmt(containerVar, textVar));
|
|
634
|
-
} else if (t2.isJSXExpressionContainer(c)) {
|
|
635
|
-
const expr = c.expression;
|
|
636
|
-
if (t2.isJSXEmptyExpression(expr)) continue;
|
|
637
|
-
const mapCall = matchMapCall(expr);
|
|
638
|
-
if (mapCall) {
|
|
639
|
-
stmts.push(
|
|
640
|
-
t2.expressionStatement(
|
|
641
|
-
t2.callExpression(t2.identifier("mapArray"), [
|
|
642
|
-
t2.arrowFunctionExpression([], mapCall.listExpr),
|
|
643
|
-
containerVar,
|
|
644
|
-
compileMapArrow(mapCall.arrow, counter)
|
|
645
|
-
])
|
|
646
|
-
)
|
|
647
|
-
);
|
|
648
|
-
} else {
|
|
649
|
-
const textVar = t2.identifier("_t" + ++counter.n);
|
|
650
|
-
stmts.push(
|
|
651
|
-
t2.variableDeclaration("const", [
|
|
652
|
-
t2.variableDeclarator(
|
|
653
|
-
textVar,
|
|
654
|
-
t2.callExpression(t2.memberExpression(t2.identifier("document"), t2.identifier("createTextNode")), [
|
|
655
|
-
t2.stringLiteral("")
|
|
656
|
-
])
|
|
657
|
-
)
|
|
658
|
-
])
|
|
659
|
-
);
|
|
660
|
-
stmts.push(
|
|
661
|
-
t2.expressionStatement(
|
|
662
|
-
t2.callExpression(t2.identifier("createEffect"), [
|
|
663
|
-
t2.arrowFunctionExpression(
|
|
664
|
-
[],
|
|
665
|
-
t2.assignmentExpression(
|
|
666
|
-
"=",
|
|
667
|
-
t2.memberExpression(textVar, t2.identifier("textContent")),
|
|
668
|
-
expr
|
|
669
|
-
)
|
|
670
|
-
)
|
|
671
|
-
])
|
|
672
|
-
)
|
|
673
|
-
);
|
|
674
|
-
stmts.push(appendStmt(containerVar, textVar));
|
|
675
|
-
}
|
|
676
|
-
} else if (t2.isJSXElement(c)) {
|
|
677
|
-
const elVar = compileSolidElement(c, stmts, counter);
|
|
678
|
-
stmts.push(appendStmt(containerVar, elVar));
|
|
679
|
-
} else if (t2.isJSXFragment(c)) {
|
|
680
|
-
compileSolidChildren(c.children, containerVar, stmts, counter);
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
function compileSolidElement(el, stmts, counter) {
|
|
685
|
-
const name = el.openingElement.name;
|
|
686
|
-
const tag = t2.isJSXIdentifier(name) ? name.name : name.name;
|
|
687
|
-
const elVar = t2.identifier("_el" + ++counter.n);
|
|
688
|
-
stmts.push(
|
|
689
|
-
t2.variableDeclaration("const", [
|
|
690
|
-
t2.variableDeclarator(
|
|
691
|
-
elVar,
|
|
692
|
-
t2.callExpression(t2.memberExpression(t2.identifier("document"), t2.identifier("createElement")), [
|
|
693
|
-
t2.stringLiteral(tag)
|
|
694
|
-
])
|
|
695
|
-
)
|
|
696
|
-
])
|
|
697
|
-
);
|
|
698
|
-
for (const attr of el.openingElement.attributes) {
|
|
699
|
-
if (!t2.isJSXAttribute(attr)) continue;
|
|
700
|
-
const attrName = attr.name.name;
|
|
701
|
-
if (attrName === "key" || attrName === "ref" || attrName === "v-memo") continue;
|
|
702
|
-
if (/^on[A-Z]/.test(attrName)) {
|
|
703
|
-
const evt = attrName[2].toLowerCase() + attrName.slice(3);
|
|
704
|
-
const handler = attr.value?.expression ?? attr.value ?? t2.identifier("undefined");
|
|
705
|
-
stmts.push(
|
|
706
|
-
t2.expressionStatement(
|
|
707
|
-
t2.callExpression(t2.memberExpression(elVar, t2.identifier("addEventListener")), [
|
|
708
|
-
t2.stringLiteral(evt),
|
|
709
|
-
handler
|
|
710
|
-
])
|
|
711
|
-
)
|
|
712
|
-
);
|
|
713
|
-
continue;
|
|
714
|
-
}
|
|
715
|
-
if (attr.value && t2.isJSXExpressionContainer(attr.value)) {
|
|
716
|
-
stmts.push(
|
|
717
|
-
t2.expressionStatement(
|
|
718
|
-
t2.callExpression(t2.identifier("createEffect"), [
|
|
719
|
-
t2.arrowFunctionExpression(
|
|
720
|
-
[],
|
|
721
|
-
t2.callExpression(t2.memberExpression(elVar, t2.identifier("setAttribute")), [
|
|
722
|
-
t2.stringLiteral(attrName),
|
|
723
|
-
attr.value.expression
|
|
724
|
-
])
|
|
725
|
-
)
|
|
726
|
-
])
|
|
727
|
-
)
|
|
728
|
-
);
|
|
729
|
-
} else {
|
|
730
|
-
const value = attr.value ? t2.isStringLiteral(attr.value) ? attr.value.value : true : true;
|
|
731
|
-
stmts.push(
|
|
732
|
-
t2.expressionStatement(
|
|
733
|
-
t2.callExpression(t2.memberExpression(elVar, t2.identifier("setAttribute")), [
|
|
734
|
-
t2.stringLiteral(attrName),
|
|
735
|
-
value === true ? t2.stringLiteral("true") : t2.stringLiteral(value)
|
|
736
|
-
])
|
|
737
|
-
)
|
|
738
|
-
);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
compileSolidChildren(el.children, elVar, stmts, counter);
|
|
742
|
-
return elVar;
|
|
743
|
-
}
|
|
744
|
-
function appendStmt(containerVar, childVar) {
|
|
745
|
-
return t2.expressionStatement(
|
|
746
|
-
t2.callExpression(t2.memberExpression(containerVar, t2.identifier("appendChild")), [childVar])
|
|
747
|
-
);
|
|
748
|
-
}
|
|
749
|
-
function matchMapCall(expr) {
|
|
750
|
-
if (t2.isCallExpression(expr) && t2.isMemberExpression(expr.callee) && t2.isIdentifier(expr.callee.property, { name: "map" }) && expr.arguments.length === 1 && t2.isArrowFunctionExpression(expr.arguments[0])) {
|
|
751
|
-
return { listExpr: expr.callee.object, arrow: expr.arguments[0] };
|
|
752
|
-
}
|
|
753
|
-
return null;
|
|
754
|
-
}
|
|
755
|
-
function compileMapArrow(arrow, counter) {
|
|
756
|
-
const stmts = [];
|
|
757
|
-
const bodyExpr = arrow.body;
|
|
758
|
-
if (t2.isJSXElement(bodyExpr)) {
|
|
759
|
-
const elVar = compileSolidElement(bodyExpr, stmts, counter);
|
|
760
|
-
stmts.push(t2.returnStatement(elVar));
|
|
761
|
-
return t2.arrowFunctionExpression(arrow.params, t2.blockStatement(stmts));
|
|
762
|
-
}
|
|
763
|
-
if (t2.isJSXFragment(bodyExpr)) {
|
|
764
|
-
return arrow;
|
|
765
|
-
}
|
|
766
|
-
return arrow;
|
|
767
|
-
}
|
|
768
53
|
export {
|
|
769
54
|
createBabelItem,
|
|
770
55
|
createBabelTransform,
|
|
771
|
-
|
|
772
|
-
defineComponentPlugin,
|
|
773
|
-
solidPlugin,
|
|
56
|
+
isExcludedTransform,
|
|
774
57
|
transformWithBabel
|
|
775
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",
|