在沙箱中执行代码,模块位于相同的上下文中

时间:2014-05-29 12:02:27

标签: javascript node.js

我自动运行ECMA-402 test suite针对我写的Intl polyfill,我遇到了一些问题。目前,测试是针对库的完全构建版本运行的,这意味着每次在测试运行之前进行更改时都必须重新编译。我试图通过将代码拆分为单独的模块并使用require来运行测试来改进它。

当我尝试使用vm模块运行测试时,主要问题就出现了。如果我将polyfill添加到测试的沙箱中,则在检查本机行为时某些测试会失败 - polyfill的对象不会继承测试上下文Object.prototype , 例如。将require传递给测试将不起作用,因为模块仍然在父上下文中编译和执行。

我脑子里最简单的解决方案是生成一个新的节点进程并将代码写入进程的stdin,但生成的node进程并不执行代码写到它,只是永远等待。这是我试过的代码:

function runTest(testPath, cb) {
    var test,
        err = '',
        content = 'var IntlPolyfill = require("' + LIB_PATH + '");\n';

    content += LIBS.fs.readFileSync(LIBS.path.resolve(TEST_DIR, testPath)).toString();
    content += 'runner();';

    test = LIBS.spawn(process.execPath, process.execArgv);
    test.stdin.write(content, 'utf8');

    // cb runs the next test
    test.on('exit', cb);
}

有没有人知道为什么Node.js不执行写入其stdin流的代码,或者是否有另一种方法可以让模块在同一个上下文中编译作为测试?

2 个答案:

答案 0 :(得分:2)

您必须关闭子进程的stdin才能使用数据并退出。完成传递代码后执行此操作。

test.stdin.end();

答案 1 :(得分:1)

最后,我选择使用-e命令行开关将代码直接传递给新节点实例。它只对代码稍作修改:

function runTest(testPath, cb) {
    var test,
        err = '',
        content = 'var IntlPolyfill = require("' + LIB_PATH + '");\n';

    content += LIBS.fs.readFileSync(LIBS.path.resolve(TEST_DIR, testPath)).toString();
    content += 'runner();';

    test = LIBS.spawn(process.execPath, process.execArgv.concat('-e', content));

    // cb runs the next test
    test.on('exit', cb);
}