代码之家  ›  专栏  ›  技术社区  ›  aztack

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

  •  3
  • aztack  · 技术社区  · 7 年前

    我试图用Babel将ImportDeclaration插入到JavaScript代码片段中。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)
    }

    但我有以下错误

    enter image description here

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

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

    1 回复  |  直到 7 年前
        1
  •  12
  •   loganfsmyth    7 年前

    你最好把它写成一个巴别塔插件,例如。

    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());
          },
        },
      };
    }