如何编写一个将输出传递给其他插件的 babel js 插件?
How to write a babel js plugin that passes output to other plugins?
我正在尝试编写一个 babel 插件,将 prepends/appends 内容写入文件 - 例如;将 console.log("start of " + __filename);
和 console.log("end of " + __filename);
行添加到每个文件。
到目前为止,我已经设法编写了一个访问者来执行此操作,但是现有代码在我的插件运行之前或之后没有被任何其他插件修改。
例如,我有以下文件:
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);
任何人都可以建议我缺少什么让 babel 将我的插件与其他插件链接起来,以允许我组合使用多个插件吗?
And this is producing the output:
鉴于您正在使用 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 可以将这些节点排队等待其他插件处理。这也使用 template
为您的两个代码段生成 AST。
我正在尝试编写一个 babel 插件,将 prepends/appends 内容写入文件 - 例如;将 console.log("start of " + __filename);
和 console.log("end of " + __filename);
行添加到每个文件。
到目前为止,我已经设法编写了一个访问者来执行此操作,但是现有代码在我的插件运行之前或之后没有被任何其他插件修改。
例如,我有以下文件:
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);
任何人都可以建议我缺少什么让 babel 将我的插件与其他插件链接起来,以允许我组合使用多个插件吗?
And this is producing the output:
鉴于您正在使用 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 可以将这些节点排队等待其他插件处理。这也使用 template
为您的两个代码段生成 AST。