Cargar el módulo node.js desde la cadena en la memoria

¿Cómo necesitaría () un archivo si tuviera el contenido del archivo como una cadena en la memoria, sin escribirlo en el disco? Aquí hay un ejemplo:

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

mira _compile, _extensions y _load en module.js

La pregunta ya fue respondida por Andrey, pero me encontré con una deficiencia que tuve que resolver y que podría ser de interés para los demás.

Quería que el módulo de la secuencia memorizada pudiera cargar otros módulos a través de require , pero la ruta del módulo se rompió con la solución anterior (por ejemplo, no se encontró la aguja). Traté de encontrar una solución elegante para mantener las rutas, usando alguna función existente pero terminé con el cableado de las rutas:

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

Después de eso, pude cargar todos los módulos existentes desde el módulo codificado. Cualquier comentario o mejor solución muy apreciada!

El paquete require-from-string hace el trabajo.

Uso:

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

En base a las soluciones de Andrey Sidorov y Dominic, me entristeció el hecho de no poder solicitar un módulo codificado, entonces sugiero esta versión *.

Código:

 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()); }(); 

Uso:

 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()); }(); 

* como puede ver, contiene un formateador de funciones que proporciona una forma de crear algunos módulos a partir de funciones.

Creo que la mejor manera de abordar esto sería tener un parámetro que puedas establecer después …

como dentro del archivo: myUnalteredModule.js

 exports.setChanges = function( args )... 

Entonces podrías hacer:

  var loadedModule = require( 'myUnalteredModule' ); loadedModule