Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

298
Views
¿La mejor manera de crear un contexto de JavaScript Node.js "nuevo y vacío" dentro del mismo proceso?

Pregunta para expertos en Node.js y v8.

Estoy desarrollando una nueva versión de la herramienta de prueba Siesta .

De forma predeterminada, Siesta ejecuta todas las pruebas en el proceso Node.js recién creado. Sin embargo, me gustaría evitar la sobrecarga de generar un nuevo proceso y, en su lugar, brindar la capacidad de ejecutar la prueba en el contexto de JavaScript vacío.

Dicho contexto se puede crear con el módulo vm incorporado. Sin embargo, el contexto creado de esta manera es un contexto de JavaScript vacío, no un contexto de Node.js vacío. Por ejemplo, no tiene un process de variable global:

 > require('vm').runInNewContext('process') evalmachine.<anonymous>:1 process ^ Uncaught ReferenceError: process is not defined at evalmachine.<anonymous>:1:1 at Script.runInContext (vm.js:143:18) at Script.runInNewContext (vm.js:148:17) at Object.runInNewContext (vm.js:303:38) at REPL30:1:15 at Script.runInThisContext (vm.js:133:18) at REPLServer.defaultEval (repl.js:484:29) at bound (domain.js:413:15) at REPLServer.runBound [as eval] (domain.js:424:12) at REPLServer.onLine (repl.js:817:10) >

Entonces, la pregunta es: ¿cuál es la mejor manera de crear un contexto Node.js nuevo y vacío dentro del mismo proceso? Espero que dicho contexto tenga todos los globales regulares, como process , require , etc. Además, espero que dicho contexto tenga un caché de módulos separado e inicialmente vacío, de modo que incluso si algún módulo se carga en el contexto principal, se cargará de nuevo en el nuevo contexto.

Por supuesto, podría mapear los globales del contexto principal al nuevo contexto, pero eso significaría que esos globales se comparten entre contextos, y mi objetivo es el aislamiento del contexto. Además, la memoria caché de los módulos también se compartirá.

Creo que la diferencia entre JavaScript y el contexto de Node.js es que este último se inicializa con un determinado script. ¿Es posible obtener las fuentes de ese script de alguna manera y ejecutarlo en el nuevo contexto?

¡Gracias!

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Una opción que tiene es usar la API fork() 'child_process' , que hace girar un nuevo proceso de Nodo con su propia memoria e instancia V8. Sin embargo, esto podría ser igual o muy similar (al menos en teoría) a lo que está haciendo en este momento.

Tenga en cuenta que los procesos secundarios de Node.js generados son independientes del principal, con la excepción del canal de comunicación IPC que se establece entre los dos. Cada proceso tiene su propia memoria, con sus propias instancias V8. Debido a las asignaciones de recursos adicionales requeridas, no se recomienda generar una gran cantidad de procesos secundarios de Node.js.

Tenga en cuenta que esta bifurcación no es una clonación de todo el proceso en ejecución:

A diferencia de la llamada al sistema POSIX fork(2), child_process.fork() no clona el proceso actual.

Otra opción que parece prometedora es usar la API Node async_hooks para emular ejecuciones en contextos separados. Consulte node-execution-context , puede funcionar para sus requisitos.

over 4 years ago · Santiago Trujillo Report

0

Esto es lo que sucede cuando NodeJS carga un nuevo módulo :

 (function(exports, require, module, __filename, __dirname) { // Module code actually lives in here });

Usan lo que llaman un contenedor de módulos

Entonces tendrías que hacer algo similar usando VM

 require('vm').runInNewContext('the code you are running', { module: // your empty module or a wrapper exports: // a reference to the module.exports require: // your empty require or a wapper __filename: // your __filename __dirname: // your __dirname process })

Tuve éxito en la creación de nuevas funciones require vacías válidas después de depurar las partes internas de la clase/función del módulo

Si crea estos 2 archivos siguientes y ejecuta el archivo isolated.js, verá que, de hecho, se está recargando cada vez y, al mismo tiempo, el caché original permanece intacto (aunque creo que las ejecuciones asíncronas podrían tener resultados inesperados)

 // isolated.js const Module = require('module') const vm = require('vm') const path = require('path') // this is just to show it wont load it again const print = require('./print') print('main file') const getNewContext = () => { const mod = new Module() const filename = path.join(__dirname, `test-filename-${Math.random().toString().substr(-6)}.js`) const req = Module.createRequire(filename) req.cache = Object.create(null) return { module: mod, // your empty module or a wrapper exports: mod.exports, // a reference to the module.exports require: req, // your empty require or a wapper // require: mod.require, // your empty require or a wapper __filename: filename, __dirname: path.dirname(filename), console, process } } // print('runningInNewContext') const jsCode = ` // What? const log = console.log.bind(null, Date.now()) log({from:'print', cache: require.cache}) const print = require('./print.js') log(print.toString()) print('evaluated code') log({from:'print', cache: require.cache}) ` function customRunInNewContext (jsCode, context) { const { _cache } = Module Module._cache = Object.create(null) vm.runInNewContext(jsCode, context) Module._cache = _cache } customRunInNewContext(jsCode, getNewContext()) customRunInNewContext(jsCode, getNewContext())
 // print.js const log = console.log.bind(null, 'PRINT loaded at', new Date().toISOString(), module.parent.filename) process.stdout.write('\n ====> loading print module\n\n') module.exports = function print (...args) { log(...args) }

cuando corres

 node ./isolated.js

Debería ver el mensaje ====> loading print module varias veces

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!