I have a node.js (v0.6.12) application that starts by evaluating a Javascript file, startup.js. It takes a long time to evaluate startup.js, and I'd like to 'bake it in' to a custom build of Node if possible.

The v8 source directory distributed with Node, node/deps/v8/src, contains a SconScript that can almost be used to do this. On line 302, we have

Those javascript files are present in the same directory. Something in the build process apparently evaluates them, takes a snapshot of state, and saves it as a byte string in node/out/Release/obj/release/snapshot.cc (on Mac OS). This file seems to be baked into Node.

Some customization of the startup snapshot is possible by altering the SconScript. For example, I can change the definition of the builtin Date.toString by altering date.js. I can even add new global variables by adding startup.js to the list of library files, with contents global.test = 1.

However, I can't put just any javascript code in startup.js. If it contains Date.toString = 1;, an error results even though the code is valid at the node repl:

And it obviously can't make use of code that depends on libraries Node adds to v8. global.underscore = require('underscore'); causes the same error.

I'd ideally like a tool, customSnapshot, where customSnapshot startup.js evaluates startup.js with Node and then dumps a snapshot to a file, snapshot.cc, which I can put into the Node source directory. I can then build node and tell it not to rebuild the snapshot.

Actually this method worked fine for me and I used node.js v0.8.11 which comes with v8 v3.11.10. The difference is that I used the new gyp-based build. Here you can see the required changes. As you said, you cannot invoke code that depends on the builtin objects or nodejs functions(console, require...). You can work around that by using ann initialization function: var global = this; global.initialize = function() { global.console.log('Hello node'); };
–
Thiago de ArrudaSep 28 '12 at 10:37

1 Answer
1

I just added an option to the mksnapshot command (which runs while you are building V8). The new --extra-file=filename.js flag lets you specify a file that is to be loaded and run in the process and then put in the snapshot. It's on the trunk version of V8, not the 3.11 branch that is being used for node 0.8 so you will have to run node 0.8 with V8 version 3.11. As far as I know at the moment that works, but you will be somewhat on your own.

Thanks, user487683, the new option works for me. For posterity, your changes were in this revision: code.google.com/p/v8/source/detail?r=11871 . To add extra code to the build process, I changed the definition of env.Snapshot on line 343 of the SconScript to env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE" --log-snapshot-positions --extra-code "path/to/file.js"'). It looks like the file gets executed after the library files listed in the SconScript, so it can modify objects they introduce. However it gets executed before anything in Node.
–
Anand PatilJun 27 '12 at 23:19