string - instalar - node versions
Cargar el módulo node.js desde la cadena en la memoria (5)
¿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) );
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
El github.com/floatdrop/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.
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!
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