Search code examples
javascriptbabeljstranspiler

Using babel, how can I append some code to the top of every file?


My goal is to fake out getting some requirejs code working via babel. I've found that if I add the following: if (typeof define !== "function") { var define = require("amdefine")(module); } to the top of every file while running in nodejs things seem to work out.

Here is some code I wrote, which I thought would work or nearly work:

function injectDefine(babel) {
    var header = 'if (typeof define !== "function") { var define = require("amdefine")(module); }';

    return new babel.Plugin('amdefine', {
        visitor: {
            Program: {
                enter: function(path, file) {
                    path.unshiftContainer(
                        'body',
                        babel.types.expressionStatement(
                            babel.types.stringLiteral(header)
                        )
                    );
                },
            },
        },
    });
}

require('babel-core/register')({
    stage: 0,
    plugins: [{transformer: injectDefine}],
});

require('../components/button');

The components/button file is just me trying to test that some file can load.

Other notes: I'm using babel 5, and I can't upgrade right now. I also can't use a .babelrc very easily right now.


Solution

  • Tip 1: the environment variable BABEL_DISABLE_CACHE=1 is needed if you are doing heavy testing of plugins. If you had a script that you ran like npm run unit you may instead want to run like BABEL_DISABLE_CACHE=1 npm run unit while testing your plugin.

    Tip 2: babel.parse will give you a full program out of some source. The easiest thing you could do is babel.parse(header).program.body[0].

    The following ended up working:

    function injectDefine(babel) {
    
        var header = 'if (typeof define !== "function") { var define = require("amdefine")(module); }';
    
        return new babel.Plugin('amdefine', {
            visitor: {
                Program: {
                    enter: function(node, parent) {
                        node.body.unshift(
                            babel.parse(header).program.body[0]
                        );
                    },
                },
            },
        });
    }
    
    require('babel-core/register')({
        cache: false,
        stage: 0,
        plugins: [injectDefine],
    });