我正在编写一个Babel插件,它应该将每个导入包装到执行某些转换的函数调用中。我们的想法是改变这段代码:
import { member } from "module-name";
import { member as alias } from "module-name";
进入这个:
import { member as _member } from "module-name";
const member = someTransform(_member);
import { member as _alias } from "module-name";
const alias = someTransform(_alias);
因此,对于别名导入(请参阅AST documentation),我想更改别名的名称;应将基本导入转换为别名导入,以便我可以更改其标识符。添加作业是微不足道的,所以我会在这个问题的其余部分忽略它。
根据AST文档,基本和别名导入的模型相同。唯一的区别是,对于基本导入,imported
和local
字段包含相同的ID,而它们的别名导入则不同。
所以我想我只需要更改所有local
的{{1}} ID。这应该会自动将基本导入转换为别名导入;对于别名导入,它应该更改别名。
这是我的代码(try it out in the AST explorer)。
ImportSpecifier
问题是生成的代码是这样的:
function transformImportDeclaration(path) {
const importSpecifierPaths = path.get('specifiers');
for (const importSpecifierPath of importSpecifierPaths) {
const node = importSpecifierPath.node;
const id = node.local;
node.local = path.scope.generateUidIdentifier(id.name);
}
}
export default function (babel) {
const t = babel.types;
return {
visitor: {
Program(programPath) {
const declarations = programPath.get('body').filter(path => t.isImportDeclaration(path));
declarations.forEach(transformImportDeclaration);
},
},
};
}
因此,只有具有别名导入的第二行才能正确转换。但是基本导入的第一行没有转换为别名导入。相反,它保持基本导入,现在指向错误的导出。我不明白为什么会这样,因为AST的import { _member } from "module-name";
import { member as _alias } from "module-name";
ID仍包含原始ID。
答案 0 :(得分:0)
这似乎是巴别塔中的一个错误。我在那里创建了a bug report。
作为一种解决方法,a commenter suggested用修改后的副本替换导入说明符。他还添加了a working demo on AST explorer。
相关代码如下:
importSpecifierPath.replaceWith(
t.importSpecifier(
path.scope.generateUidIdentifier(node.imported.name),
t.clone(node.imported)
)
);