8

我的目标是通过 babel 伪造一些 requirejs 代码。我发现如果我if (typeof define !== "function") { var define = require("amdefine")(module); }在 nodejs 中运行时将以下内容添加到每个文件的顶部,事情似乎就可以解决。

这是我编写的一些代码,我认为它们可以工作或几乎可以工作:

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');

components/button文件只是我试图测试某些文件可以加载。

其他说明:我使用的是 babel 5,目前无法升级。我现在也不能.babelrc很容易地使用。

4

2 回答 2

7

BABEL_DISABLE_CACHE=1提示 1:如果您正在对插件进行大量测试,则需要环境变量。如果您有一个像您一样运行的脚本,npm run unit您可能希望BABEL_DISABLE_CACHE=1 npm run unit在测试插件时像这样运行。

提示2:babel.parse会给你一个完整的程序出一些来源。你能做的最简单的事情是babel.parse(header).program.body[0].

以下最终工作:

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],
});
于 2016-05-11T03:34:00.453 回答
3

在这个阶段,可以使用更清洁的解决方案@babel/traverse@babel/types.

假设您想在每个文件的顶部附加注释,您可以使用如下代码:

// Import the required modules
import * as t from "@babel/types";
import traverse from "@babel/traverse";

// Get your ast (for this, you can use @babel/parser)

// Traverse your ast
traverse(ast, {
  // When the current node is the Program node (so the main node)
  Program(path) {
    // Insert at the beginning a string "Hello World" --> not valid JS code
    path.unshiftContainer('body', t.stringLiteral("Hello World"));
  }
});
于 2019-11-13T20:47:25.123 回答