从内存中的string加载node.js模块

如果我将文件的内容作为内存中的string,而不将它写出到磁盘,我将如何要求()一个文件? 这是一个例子:

// Load the file as a string var strFileContents = fs.readFileSync( "./myUnalteredModule.js", 'utf8' ); // Do some stuff to the files contents strFileContents[532] = '6'; // Load it as a node module (how would I do this?) var loadedModule = require( doMagic(strFileContents) ); 
 function requireFromString(src, filename) { var Module = module.constructor; var m = new Module(); m._compile(src, filename); return m.exports; } console.log(requireFromString('module.exports = { test: 1}')); 

查看module.js中的_compile,_extensions和_load

安德烈已经回答了这个问题,但是我遇到了一个我必须解决的问题,这个问题可能会让其他人感兴趣。

我希望存储的string中的模块能够通过require来加载其他模块,但是模块path被上面的解决scheme破坏了(所以例如没有find针)。 我试图find一个优雅的解决scheme来维护path,通过使用一些现有的function,但我最终以硬布线的path:

 function requireFromString(src, filename) { var m = new module.constructor(); m.paths = module.paths; m._compile(src, filename); return m.exports; } var codeString = 'var needle = require(\'needle\');\n' + '[...]\n' + 'exports.myFunc = myFunc;'; var virtMod = requireFromString(codeString); console.log('Available public functions: '+Object.keys(virtMod)); 

之后,我可以加载string化模块中的所有现有模块。 任何意见或更好的解决scheme高度赞赏

require-from-string包完成这项工作。

用法:

 var requireFromString = require('require-from-string'); requireFromString('module.exports = 1'); //=> 1 

基于Andrey Sidorov&Dominic的解决scheme,我不能要求一个string化的模块,然后我build议这个版本的事实令我感到难过。

码:

 void function() { 'use strict'; const EXTENSIONS = ['.js', '.json', '.node']; var Module, path, cache, resolveFilename, demethodize, hasOwnProperty, dirname, parse, resolve, stringify, virtual; Module = require('module'); path = require('path'); cache = Module._cache; resolveFilename = Module._resolveFilename; dirname = path.dirname; parse = path.parse; resolve = path.resolve; demethodize = Function.bind.bind(Function.call); hasOwnProperty = demethodize(Object.prototype.hasOwnProperty); Module._resolveFilename = function(request, parent) { var filename; // Pre-resolution filename = resolve(parse(parent.filename).dir, request); // Adding extension, if needed if (EXTENSIONS.indexOf(parse(filename).ext) === -1) { filename += '.js'; } // If the module exists or is virtual, return the filename if (virtual || hasOwnProperty(cache, filename)) { return filename; } // Preserving the native behavior return resolveFilename.apply(Module, arguments); }; Module._register = function(request, parent, src) { var filename, module; // Enabling virtual resolution virtual = true; filename = Module._resolveFilename(request, parent); // Disabling virtual resolution virtual = false; // Conflicts management if (hasOwnProperty(cache, filename)) { error = new Error('Existing module "' + request + '"'); error.code = 'MODULE_EXISTS'; throw error; } // Module loading cache[filename] = module = new Module(filename, parent); module.filename = filename; module.paths = Module._nodeModulePaths(dirname(filename)); module._compile(stringify(src), filename); module.loaded = true; return module; }; stringify = function(src) { // If src is a function, turning to IIFE src return typeof src === 'function' ? 'void ' + src.toString() + '();' : src; }; }(); void function() { var Module, parentModule, child; Module = require('module'); // Creating a parent module from string parentModule = Module._register('parent', process.mainModule, ` module.exports = { name: module.filename, getChild: function() { return require('child'); } }; `); // Creating a child module from function Module._register('child', parentModule, function() { module.exports = { name: module.filename, getParent: function() { return module.parent.exports; } }; }); child = require('child'); console.log(child === child.getParent().getChild()); }(); 

用法:

 void function() { var Module, parentModule, child; Module = require('module'); // Creating a parent module from string parentModule = Module._register('parent', process.mainModule, ` module.exports = { name: module.filename, getChild: function() { return require('child'); } }; `); // Creating a child module from function Module._register('child', parentModule, function() { module.exports = { name: module.filename, getParent: function() { return module.parent.exports; } }; }); child = require('child'); console.log(child === child.getParent().getChild()); }(); 

*你可以看到,它包含一个函数formater,它提供了一种从函数创build一些模块的方法。

我认为更好的方法来处理这个问题将是一个参数,你可以在之后设置…

如文件内部:myUnalteredModule.js

 exports.setChanges = function( args )... 

那么你可以这样做:

  var loadedModule = require( 'myUnalteredModule' ); loadedModule