admin管理员组

文章数量:1353228

I was trying to insert a ImportDeclaration into a snippets of JavaScript code with 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 {",
  "  ponents: {",
  "  },",
  "  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)
}

I was trying to insert a ImportDeclaration into a snippets of JavaScript code with 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 {",
  "  ponents: {",
  "  },",
  "  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)
}

But I got the following error

What's the proper way to do this?

FYI: You can get above code from git clone https://github./aztack/babel-test.git

Share Improve this question edited Dec 27, 2017 at 14:19 aztack asked Dec 27, 2017 at 14:03 aztackaztack 4,6147 gold badges35 silver badges57 bronze badges 1
  • I also tried to path.insertAfter(importAst) in exit method. But It will cause the traverse go into an infinite loop, since I just inserted a ImportDeclaration... – aztack Commented Dec 27, 2017 at 14:06
Add a ment  | 

1 Answer 1

Reset to default 13

You'd be best off writing this as a Babel plugin, e.g.

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

const code = [
  "import A from 'a'",
  "import B from 'b'",
  "export default {",
  "  ponents: {",
  "  },",
  "  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());
      },
    },
  };
}

本文标签: javascriptHow to insert import statement into AST with BabeljsStack Overflow