节点VM-require()在第一级正常,在第二级失败

Node VM - require() on first level OK, fails on second level

本文关键字:二级 失败 节点 一级 VM-require      更新时间:2023-09-26

因此,我尝试使用Node的VM来动态加载生成对象的外部脚本。该对象有三个原型(Grandparent->Parent->Child)。

如果所有三个原型都在同一个文件中,一切都会很好。

在两个文件中,一切都很好,分别是child.jsparent-grandtparent.js。我将"module"answers"require"添加到我的VM沙盒中,并提供了一个自定义requireShem,并确保它正确启动child.js正确地请求了parent-grandpparent.js,一切正常。

但是,当使用3个单独的文件时,它不起作用child.js仍然通过requestShim正确地请求parent.js,但在下一个级别上,parent.js忽略提供的填充程序,并直接使用grandpparent.js的内部require()(由于某些原因永远无法定位文件)(由于某种原因,只有当所有文件都在应用程序的根文件夹中时才有效,拒绝处理子目录)

这是我的VM代码。它运行一个外部脚本,并期望在结果中找到新对象。

app.js

var child = getScriptObject("./scripts/child.js")
function getScriptObject(scriptFilename)
    {
    var sandbox = { "module": module, "result": false, 
                    "require":requireShim, "console":console };
    var script = vm.createScript( fs.readFileSync(scriptFilename) );
    script.runInNewContext(sandbox);
    return sandbox.result;
    }
function requireShim (x)
    {
    console.log("requireShim: "+x);
    return require(x);
    }

祖父母.js

function Grandparent() {};
module.exports = Grandparent

parent.js

console.log("Parent requiring Grandparent...");
var Grandparent = require('./scripts/grandparent.js');
function Parent() { Grandparent.call(this); };
Parent.prototype = Object.create(Grandparent.prototype);    
Parent.prototype.constructor = Parent;
module.exports = Parent

child.js

console.log("Child requiring Parent...");
var Parent = require('./scripts/parent.js');
function Child() { Parent.call(this); };
Child.prototype = Object.create(Parent.prototype);  
Child.prototype.constructor = Child;
result = new Child();

具有以下输出:

Child requiring Parent...
requireShim: ./scripts/parent.js
Parent requiring Grandparent...
module.js:322
    throw err;
          ^
Error: Cannot find module './scripts/grandparent.js'
    at Function.Module._resolveFilename (module.js:320:15)
    at Function.Module._load (module.js:262:25)
    at Module.require (module.js:349:17)
    at require (module.js:368:17)
    at Object.<anonymous> (C:'RemHaz2'zone'scripts'parent.js:2:19)
    at Module._compile (module.js:444:26)
    at Object.Module._extensions..js (module.js:462:10)
    at Module.load (module.js:339:32)
    at Function.Module._load (module.js:294:12)
    at Module.require (module.js:349:17)

请注意,Child->Parent工作正常,但Parent->Grandparent忽略了填充程序,由于某种莫名其妙的原因无法处理子目录。

如果parent.jschild.js在同一目录中,则:

var Parent = require('./scripts/parent.js');

应为:

var Parent = require('../scripts/parent.js');

或者:

var Parent = require('./parent.js');

同样适用于:

var Grandparent = require('./scripts/grandparent.js');

而来自app.js"./scripts/child.js"的工作原理是app.jsscripts目录的兄弟目录,即它们共享相同的父目录。