2017-12-27 208 views
0

我试图插入一个导入声明成JavaScript代码段与Babel.js:如何用Babel.js将导入语句插入到AST中?

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

有什么正确的方法来做到这一点?

FYI: 你可以得到上面的代码从git clone https://github.com/aztack/babel-test.git

+0

我也尝试''path.insertAfter(importAst)'in'exit'方法。但它会导致'遍历'进入一个无限循环,因为我刚插入一个'ImportDeclaration' ... – aztack

回答

0

你最好还是写信以此为巴贝尔的插件,例如

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

明白了!谢谢! – aztack