Node.js has a modular architecture with the V8 engine providing JavaScript execution and libuv handling asynchronous operations. Core modules can be implemented in either C++ or JavaScript. When a module is required, Node.js checks its cache and compiles the source before returning the exports object. This allows seamless usage of both native and JavaScript modules.
6. V8
• V8 provides C++ API
o Access Javascript object in C++
o Access C++ objects in Javascript
7. Terms
• Handler: An object reference managed by
the v8 garbage collector
• HandlerScopes: A stack-allocated class that
governs a number of local handles
• Context: A sandboxed execution context
with its own set of built-in objects and
functions
• Templaates: A template is a blueprint for
JavaScript functions and objects in a
context.
9. Core modules
• C++ modules (src/node_extensions.cc)
o fs
o http_parser
o os
o Zlib
o …
• Js modules (lib/)
o fs.js
o http.js
o net.js
o os.js
o modules.js
o …
10. How to use core modules ?
…
var util = require('util');
var pathModule = require('path');
var binding = process.binding('fs');
var constants = process.binding('constants');
var fs = exports;
…
Lib/fs.js
11. How modules inited ?
node::Start(argc, argv)
// Use original argv, as we're just copying values out of it.
Handle<Object> process_l = SetupProcessObject(argc, argv);
v8_typed_array::AttachBindings(context->Global());
// Create all the objects, load modules, do everything.
// so your next reading stop should be node::Load()!
Load(process_l);
// All our arguments are loaded. We've evaluated all of the scripts. We
// might even have created TCP servers. Now we enter the main eventloop. If
// there are no watchers on the loop (except for the ones that were
// uv_unref'd) then this function exits. As long as there are active
// watchers, it blocks.
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
12. C++ modules
• What process.binding (a.k.a Node::Binding)
do
o Check binding_cache if module is in cache
already
o If not cached, call node_extensions::get_builtin_module to
bind the c++ module and call the module’s
register_func()
• How C++ modules implemented
o node_file.cc
13. Js modules
• When when requiring a js module in native modules,
NativeModule.require() in node.js is called
o If require(“native_module”), return NativeModule
o If cached return getCached().exports
o else return new
NativeModule(id).compile().exports
• NativeModule(id).compile() reads
source and compiles source into js
object in js heap
14. Why NativeModule.require()
• src/node.js is invoked by node::Load() in src/node.cc, and
responsible for loading lib/*.js and bootstrapping the nodejs
core.
NativeModule.wrap = function(script) {
return NativeModule.wrapper[0] + script + NativeModule.wrapper[1];
};
NativeModule.wrapper = [
'(function (exports, require, module, __filename, __dirname) { ',
'n});'
];
NativeModule.prototype.compile = function() {
var source = NativeModule.getSource(this.id);
source = NativeModule.wrap(source);
var fn = runInThisContext(source, this.filename, true);
fn(this.exports, NativeModule.require, this, this.filename);
this.loaded = true;
};
15. How to use core modules(revisit)
• Loading C++ module
process.binding(“fs”) -> get_builtin_module(“fs”) ->
NODE_MODULE(node_fs, node::InitFs)
• Loading js module
Require(“path”) -> NativeModule.require(“path”) ->
process.binding("natives")["path"] ->
DefineJavaScript() -> natives[] -> node_natives.h
16. More !!
• How to write a C++ module
o http://nodejs.org/api/addons.html
• How about user-defined js module
o lib/modules.js
o http://nodejs.org/api/modules.html