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

时间:2017-12-27 14:03:28

标签: javascript babeljs abstract-syntax-tree

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

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)
}

但我收到以下错误

enter image description here

这样做的正确方法是什么?

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

获取以上代码

1 个答案:

答案 0 :(得分:4)

你最好把它写成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());
      },
    },
  };
}