如何将基本导入转换为别名导入?

时间:2017-05-02 14:08:24

标签: javascript plugins babeljs

我正在编写一个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文档,基本和别名导入的模型相同。唯一的区别是,对于基本导入,importedlocal字段包含相同的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。

1 个答案:

答案 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)
  )
);