2012-06-19 6 views
10

Tengo una aplicación node.js (v0.6.12) que comienza con la evaluación de un archivo Javascript, startup.js. Lleva mucho tiempo evaluar startup.js, y me gustaría 'hornearlo' en una compilación personalizada de Node si es posible.Node.js/v8: Cómo hacer mi propia instantánea para acelerar el inicio

El directorio fuente v8 distribuido con Node, node/deps/v8/src, contiene un SconScript que casi se puede usar para hacer esto. En la línea 302, tenemos

LIBRARY_FILES = ''' 
runtime.js 
v8natives.js 
array.js 
string.js 
uri.js 
math.js 
messages.js 
apinatives.js 
date.js 
regexp.js 
json.js 
liveedit-debugger.js 
mirror-debugger.js 
debug-debugger.js 
'''.split() 

Esos archivos javascript están presentes en el mismo directorio. Algo en el proceso de compilación aparentemente los evalúa, toma una instantánea del estado y la guarda como una cadena de bytes en node/out/Release/obj/release/snapshot.cc (en Mac OS). Este archivo parece estar cocido en Nodo.

Algunas personalizaciones de la instantánea de inicio son posibles mediante la modificación del SconScript. Por ejemplo, puedo cambiar la definición del Date.toString incorporado alterando date.js. Incluso puedo agregar nuevas variables globales agregando startup.js a la lista de archivos de la biblioteca, con el contenido global.test = 1.

Sin embargo, no puedo poner cualquier código de javascript en startup.js. Si contiene Date.toString = 1;, da como resultado un error a pesar de que el código es válido en el nodo repl:

Build failed: -> task failed (err #2): 
    {task: libv8.a SConstruct -> libv8.a} 
make: *** [program] Error 1 

Y es evidente que no se puede hacer uso de código que depende de las bibliotecas nodo añade a V8. global.underscore = require('underscore'); provoca el mismo error.

Idealmente me gustaría tener una herramienta, customSnapshot, donde customSnapshot startup.js evalúa startup.js con Node y luego vuelca una instantánea a un archivo, snapshot.cc, que puedo poner en el directorio de origen del nodo. Luego puedo construir un nodo y decirle que no vuelva a generar la instantánea.

+0

En realidad, este método funcionó bien para mí y usé node.js v0.8.11 que viene con v8 v3.11.10. La diferencia es que utilicé la nueva compilación basada en gyp. [Aquí] (https://github.com/tarruda/node/commit/2f58630e66e2de4cbadae09ac37da55721de7bd3) puede ver los cambios necesarios. Como dijo, no puede invocar un código que depende de los objetos incorporados o de las funciones del nodojs (consola, requiere ...). Puede solucionarlo utilizando la función de inicialización ann: var global = this; global.initialize = function() { global.console.log ('Hola nodo'); }; –

Respuesta

7

Acabo de agregar una opción al comando mksnapshot (que se ejecuta mientras está compilando V8). El nuevo indicador --extra-file = filename.js le permite especificar un archivo que se va a cargar y ejecutar en el proceso y luego colocarlo en la instantánea. Está en la versión troncal de V8, no en la rama 3.11 que se está utilizando para el nodo 0.8, por lo que deberá ejecutar el nodo 0.8 con la versión 3.11 de V8. Por lo que sé en este momento, eso funciona, pero estarás un poco solo.

Por favor, presente errores si prueba esto y no funciona para usted.

+2

Gracias, usuario487683, la nueva opción funciona para mí. Para la posteridad, los cambios se incluyeron en esta revisión: http://code.google.com/p/v8/source/detail?r=11871. Para agregar código adicional al proceso de compilación, cambié la definición de env.Snapshot en la línea 343 de SconScript a 'env ['BUILDERS'] ['Snapshot'] = Builder (acción = '$ SOURCE $ TARGET --logfile' $ LOGFILE "--log-snapshot-positions --extra-code" ruta/a/archivo.js "')'. Parece que el archivo se ejecuta después de los archivos de la biblioteca enumerados en SconScript, por lo que puede modificar los objetos que introducen. Sin embargo, se ejecuta antes que nada en Nodo. –

Cuestiones relacionadas