Babel unshiftcontainer 不创建元素
Babel unshiftcontainer not creating an element
玩转 babel 转换,我写了这个片段来在我的 path
之后插入一个 VariableDeclaration
export default function (babel) {
const { types: t } = babel;
return {
name: "ast-transform", // not required
visitor: {
VariableDeclaration (path) {
if (path.node.kind !== 'var') {
return;
}
const _id = t.Identifier('qwe');
const _init = t.numericLiteral(42);
console.log(_id, _init);
const _node = t.variableDeclaration('var', [
t.variableDeclarator(
t.identifier("uid"),
t.numericLiteral(42)
)
]);
path
.unshiftContainer(
'body',
_node
)
}
}
};
}
得到如下错误,
unknown: Cannot read property 'body' of undefined
编辑:
如果我执行以下操作而不是 unshiftContainer
它会起作用,
const _program = path.findParent(p => p.isProgram());
_program.node.body.unshift(_node);
为什么 unshiftContainer
不起作用?
Link 要点 ast-explorer
为了使用 unshiftContainer("body")
,您必须有一个带有 "body" 的节点。例如,Program
或 FunctionDeclaration
(1, 2, 3)
但是您试图在 VariableDeclaration
上执行此操作,而 VariableDeclaration
没有 body
,正如您在 ast-explorer.
中看到的那样
当您调用 path.get("body")
时,它会 returns {..., node: undefined, ...}
然后,当您调用 unshiftContainer("body")
时,它会尝试获取 "body"
of [=24] =], 即 undefined
: container: this.node[listKey],
.
您的解决方案有效,因为您找到了 Program
对象,它有主体。
所以,如果你想使用 unshiftContainer
:
const _program = path.findParent(p => p.isProgram());
_program.unshiftContainer("body", _node);
此外,您可以这样做:
const parentWithBody = path.findParent(
(p) => p.node !== undefined && p.node.body !== undefined
);
parentWithBody.unshiftContainer("body", _node);
它不仅会检测Program
,还会检测FunctionDeclaration
:
来源:
var x = 10;
var y = 5;
function test() {
var z = 1;
}
输出:
var uid = 42;
var uid = 42;
var x = 10;
var y = 5;
function test() {
var uid = 42;
var z = 1;
}
更新关于无限循环,
确实,当您取消移动容器时,您正在添加新的 VariableDeclaration
,因此它将进入无限循环:
- 参见
var x = 10
-> 添加 var uid = 42
- 参见
var uid = 42
-> 添加 var uid = 42
- 等等...
为了打破这个循环,添加这个条件,检查 node.kind
是否为 var
:
if (path.node.declarations[0].init.value === 42 && path.node.declarations[0].id.name === "uid") {
return;
}
(gist)
玩转 babel 转换,我写了这个片段来在我的 path
VariableDeclaration
export default function (babel) {
const { types: t } = babel;
return {
name: "ast-transform", // not required
visitor: {
VariableDeclaration (path) {
if (path.node.kind !== 'var') {
return;
}
const _id = t.Identifier('qwe');
const _init = t.numericLiteral(42);
console.log(_id, _init);
const _node = t.variableDeclaration('var', [
t.variableDeclarator(
t.identifier("uid"),
t.numericLiteral(42)
)
]);
path
.unshiftContainer(
'body',
_node
)
}
}
};
}
得到如下错误,
unknown: Cannot read property 'body' of undefined
编辑:
如果我执行以下操作而不是 unshiftContainer
它会起作用,
const _program = path.findParent(p => p.isProgram());
_program.node.body.unshift(_node);
为什么 unshiftContainer
不起作用?
Link 要点 ast-explorer
为了使用 unshiftContainer("body")
,您必须有一个带有 "body" 的节点。例如,Program
或 FunctionDeclaration
(1, 2, 3)
但是您试图在 VariableDeclaration
上执行此操作,而 VariableDeclaration
没有 body
,正如您在 ast-explorer.
当您调用 path.get("body")
时,它会 returns {..., node: undefined, ...}
然后,当您调用 unshiftContainer("body")
时,它会尝试获取 "body"
of [=24] =], 即 undefined
: container: this.node[listKey],
.
您的解决方案有效,因为您找到了 Program
对象,它有主体。
所以,如果你想使用 unshiftContainer
:
const _program = path.findParent(p => p.isProgram());
_program.unshiftContainer("body", _node);
此外,您可以这样做:
const parentWithBody = path.findParent(
(p) => p.node !== undefined && p.node.body !== undefined
);
parentWithBody.unshiftContainer("body", _node);
它不仅会检测Program
,还会检测FunctionDeclaration
:
来源:
var x = 10;
var y = 5;
function test() {
var z = 1;
}
输出:
var uid = 42;
var uid = 42;
var x = 10;
var y = 5;
function test() {
var uid = 42;
var z = 1;
}
更新关于无限循环,
确实,当您取消移动容器时,您正在添加新的 VariableDeclaration
,因此它将进入无限循环:
- 参见
var x = 10
-> 添加var uid = 42
- 参见
var uid = 42
-> 添加var uid = 42
- 等等...
为了打破这个循环,添加这个条件,检查 node.kind
是否为 var
:
if (path.node.declarations[0].init.value === 42 && path.node.declarations[0].id.name === "uid") {
return;
}
(gist)