Javascript 如何编写一个BabelJS插件,将输出传递给其他插件?

Javascript 如何编写一个BabelJS插件,将输出传递给其他插件?,javascript,babeljs,babel-plugin,Javascript,Babeljs,Babel Plugin,我正在尝试编写一个babel插件,它可以在一个文件中添加内容,例如;添加行console.log(“开始”+\u文件名)和console.log(“文件名“+”的结尾)到每个文件 到目前为止,我已经成功地编写了一个访问者来完成这项工作,但是在我的插件运行之前或之后,现有的代码不会被任何其他插件修改 例如,我有以下文件: import * as foo from 'foo'; import * as bar from 'bar'; console.dir({ foo, bar }); 单独使用

我正在尝试编写一个babel插件,它可以在一个文件中添加内容,例如;添加行
console.log(“开始”+\u文件名)
console.log(“文件名“+”的结尾)到每个文件

到目前为止,我已经成功地编写了一个访问者来完成这项工作,但是在我的插件运行之前或之后,现有的代码不会被任何其他插件修改

例如,我有以下文件:

import * as foo from 'foo';
import * as bar from 'bar';

console.dir({ foo, bar });
单独使用
env
预设(即不使用我的插件)和选项
targets.node:“current”
我将得到输出-请注意,es6导入已转换为commonjs需要:

'use strict';
var _foo = require('foo');
var foo = _interopRequireWildcard(_foo);
var _bar = require('bar');
var bar = _interopRequireWildcard(_bar);
function _interopRequireWildcard(obj) { /* resolve commonjs or es6 module */ }
console.dir({ foo, bar });
然而,一旦我添加我自己的插件到这个;似乎跳过了
env
预设以支持我自己的插件-但是我希望应用两个插件(最好先应用我的插件)


到目前为止,我的插件代码如下所示:

module.exports = function wrapModule(babel) {

  const prepend = transform(`console.log("start of " + __filename);`)
  const append = transform(`console.log("end of " + __filename);`)
  return {
    visitor: {
      Program(path, {opts}) {
        path.replaceWith(t.program([...prepend, ...path.node.body, ...append]))
        path.stop()
      }
    }
  }

  function transform(content) {
    return babel.transform(content).ast.program.body
  }
}
我的
.babelrc
就是:

{
  "presets": [[
    "env", { "targets": { "node": "current" } }
  ]],
  "plugins": [
    "./wrapper-babel-plugin"
  ]
}
这就产生了输出:

console.log("start of " + __filename);
import * as foo from 'foo';
import * as bar from 'bar';

console.dir({ foo, bar });
console.log("end of " + __filename);
有谁能建议我缺少什么让巴别塔把我的插件和其他插件链接起来,让我可以组合使用多个插件吗

这就产生了输出:

console.log("start of " + __filename);
import * as foo from 'foo';
import * as bar from 'bar';

console.dir({ foo, bar });
console.log("end of " + __filename);
假设您使用的是
eval
,并且调用的
transform
函数的参数数目不正确,那么这不可能是真的:)

写下你要找的东西的正确方法是

export default function wrapModule({ template }) {
  const prepend = template(`console.log("start of " + __filename);`);
  const append = template(`console.log("end of " + __filename);`);

  return {
    visitor: {
      Program(path, {opts}) {
        path.unshiftContainer("body", prepend());
        path.pushContainer("body", append());
      }
    }
  };
}

通过使用
unshiftContainer
pushContainer
Babel可以将这些节点排队等待其他插件处理。这还使用
模板
为您的两个代码片段生成AST。

啊,谢谢!我删掉了这个示例,似乎遗漏了一些内容。unshiftContainer/pushContainer确实是我所缺少的;我已经编辑了问题以更正函数。