I'm trying to write a babel plugin that prepends/appends content to a file - for example; add the lines console.log("start of " + __filename);
and console.log("end of " + __filename);
to each file.
So far, I've managed to write a visitor that does exactly this, however the existing code doesn't get modified by any other plugins before OR after my plugin operates.
For example, I have the following file:
import * as foo from 'foo';
import * as bar from 'bar';
console.dir({ foo, bar });
Using the env
preset alone (ie. without my plugin) and the option targets.node: 'current'
I end up with the output - note that es6 imports have been transformed into commonjs requires:
'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 });
However as soon as I add my own plugin to this; it appears that the env
preset is skipped in favour of my own plugin - however I'd like both plugins to be applied (mine first, preferably).
So far, my plugin code looks like:
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
}
}
and my .babelrc
is simply:
{
"presets": [[
"env", { "targets": { "node": "current" } }
]],
"plugins": [
"./wrapper-babel-plugin"
]
}
And this is producing the output:
console.log("start of " + __filename);
import * as foo from 'foo';
import * as bar from 'bar';
console.dir({ foo, bar });
console.log("end of " + __filename);
Can anyone suggest what I'm missing to have babel chain my plugin with other plugins, to allow me to use multiple plugins in combination?
And this is producing the output:
Given that you are using eval
, and you are calling your transform
function with the wrong number of arguments, that can't possibly be true :)
The correct way to write what you're looking for would be
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());
}
}
};
}
By using unshiftContainer
and pushContainer
Babel can queue up those nodes for processing by other plugins. This also uses template
to generate the ASTs for your two snippets.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.