如何使用 Babel.js 将 import 语句插入 AST?

How to insert import statement into AST with Babel.js?

我试图将 ImportDeclaration 插入 JavaScript 代码片段中 Babel.js:

const babel = require('babel-core')
const t = babel.types
const traverse = babel.traverse
const template = babel.template
const generate = require('babel-generator').default

const babylon = require('babylon')

const code = [
  "import A from 'a'",
  "import B from 'b'",
  "export default {",
  "  components: {",
  "  },",
  "  methods: {",
  "    init () {",
  "    }",
  "  }",
  "}"
].join("\n")
console.log(code)
const ast = babylon.parse(code, {
  sourceType: 'module'
})
var n = []
traverse(ast, {
  ImportDeclaration: {
    exit(path) {
      n.push(path)
    }
  }
})

const name = 'UserDialog',
  src = './user-dialog.vue'
if (n.length) {
  const importCode = "import " + name + " from '" + src + "'"
  console.log(importCode)
  const importAst = template(importCode, {
    sourceType: 'module'
  })()
  // append to last import statement
  n[n.length - 1].insertAfter(importAst);
  console.log(generate(ast).code)
}

但是我得到了以下错误

执行此操作的正确方法是什么?

仅供参考: 您可以从 git clone https://github.com/aztack/babel-test.git

获取以上代码

你最好把它写成 Babel 插件,例如

const babel = require('babel-core');

const code = [
  "import A from 'a'",
  "import B from 'b'",
  "export default {",
  "  components: {",
  "  },",
  "  methods: {",
  "    init () {",
  "    }",
  "  }",
  "}"
].join("\n");

const result = babel.transform(code, {
  plugins: [myImportInjector]
});

console.log(result.code);


function myImportInjector({ types, template }) {
  const myImport = template(`import UserDialog from "./user-dialog";`, {sourceType: "module"});

  return {
    visitor: {
      Program(path, state) {
        const lastImport = path.get("body").filter(p => p.isImportDeclaration()).pop();

        if (lastImport) lastImport.insertAfter(myImport());
      },
    },
  };
}