@actview/plugin-babel 1.0.6 → 2.0.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/dist/index.js +64 -7
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -130,9 +130,10 @@ function defineComponentPlugin() {
|
|
|
130
130
|
if (!node.id) return;
|
|
131
131
|
const name = node.id.name;
|
|
132
132
|
if (!/^[A-Z]/.test(name)) return;
|
|
133
|
+
assertNoSetupStyleEarlyReturns(path, name);
|
|
133
134
|
const fn = t.functionExpression(null, node.params, node.body, false, false);
|
|
134
135
|
if (node.typeParameters) fn.typeParameters = node.typeParameters;
|
|
135
|
-
const wrapped = wrapComponentFn(fn, name);
|
|
136
|
+
const wrapped = wrapComponentFn(fn, name, path);
|
|
136
137
|
if (!wrapped) return;
|
|
137
138
|
const call = wrapped;
|
|
138
139
|
hasTransformed = true;
|
|
@@ -153,11 +154,12 @@ function defineComponentPlugin() {
|
|
|
153
154
|
const init = node.init;
|
|
154
155
|
const isFn = t.isFunctionExpression(init) || t.isArrowFunctionExpression(init);
|
|
155
156
|
if (!isFn) return;
|
|
156
|
-
const
|
|
157
|
+
const initPath = path.get("init");
|
|
158
|
+
assertNoSetupStyleEarlyReturns(initPath, id.name);
|
|
159
|
+
const wrapped = wrapComponentFn(init, id.name, initPath);
|
|
157
160
|
if (!wrapped) return;
|
|
158
161
|
const call = wrapped;
|
|
159
162
|
hasTransformed = true;
|
|
160
|
-
const initPath = path.get("init");
|
|
161
163
|
wrapEarlyReturns(initPath);
|
|
162
164
|
node.init = call;
|
|
163
165
|
},
|
|
@@ -184,18 +186,19 @@ function defineComponentPlugin() {
|
|
|
184
186
|
;
|
|
185
187
|
fn.typeParameters = decl.typeParameters;
|
|
186
188
|
}
|
|
187
|
-
const
|
|
189
|
+
const declPath = path.get("declaration");
|
|
190
|
+
assertNoSetupStyleEarlyReturns(declPath);
|
|
191
|
+
const wrapped = wrapComponentFn(fn, void 0, path);
|
|
188
192
|
if (!wrapped) return;
|
|
189
193
|
const call = wrapped;
|
|
190
194
|
hasTransformed = true;
|
|
191
|
-
const declPath = path.get("declaration");
|
|
192
195
|
wrapEarlyReturns(declPath);
|
|
193
196
|
path.node.declaration = call;
|
|
194
197
|
}
|
|
195
198
|
}
|
|
196
199
|
};
|
|
197
200
|
}
|
|
198
|
-
function wrapComponentFn(fn, name) {
|
|
201
|
+
function wrapComponentFn(fn, name, fnPath) {
|
|
199
202
|
const body = fn.body;
|
|
200
203
|
const isExprBody = !t.isBlockStatement(body);
|
|
201
204
|
let last = null;
|
|
@@ -214,7 +217,13 @@ function wrapComponentFn(fn, name) {
|
|
|
214
217
|
const isJsxCall = t.isCallExpression(ret) && t.isIdentifier(ret.callee) && /^_?jsx/.test(ret.callee.name);
|
|
215
218
|
const isNullRet = t.isNullLiteral(ret);
|
|
216
219
|
const isCondRet = isRenderExpr(ret);
|
|
217
|
-
if (!isJsx && !isJsxCall && !isNullRet && !isCondRet)
|
|
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
|
+
}
|
|
218
227
|
if (isJsx) walkJSX(ret);
|
|
219
228
|
if (isExprBody) {
|
|
220
229
|
fn.body = t.blockStatement([
|
|
@@ -229,6 +238,54 @@ function wrapComponentFn(fn, name) {
|
|
|
229
238
|
if (name) args.push(t.stringLiteral(name));
|
|
230
239
|
return t.callExpression(t.identifier("defineComponent"), args);
|
|
231
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
|
+
}
|
|
232
289
|
function wrapEarlyReturns(fnPath) {
|
|
233
290
|
fnPath.traverse({
|
|
234
291
|
ReturnStatement(innerPath) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actview/plugin-babel",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Babel 插件:JSX 组件自动 defineComponent 转换(ActView 编译核心,独立于 Vite 宿主)",
|
|
6
6
|
"exports": {
|
|
@@ -9,7 +9,11 @@
|
|
|
9
9
|
"import": "./dist/index.js"
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
|
-
"
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@babel/core": "^8.0.0",
|
|
14
|
+
"@babel/generator": "^8.0.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
13
17
|
"@babel/core": "^8.0.1",
|
|
14
18
|
"@babel/generator": "^8.0.0"
|
|
15
19
|
},
|