neuronjs
Version:
Neuron is A Full Feature CommonJS Module Manager, Dependency Graph Handler and Loader for Browsers
98 lines (82 loc) • 2.92 kB
JavaScript
// module define
// ---------------------------------------------------------------------------------------------------
// Method to define a module.
// **NOTICE** that `define` has no fault tolerance and type checking since neuron 2.0,
// because `define` method is no longer designed for human developers to use directly.
// `define` should be generated by some develop environment such as [cortex](http://github.com/cortexjs/cortex)
// @private
// @param {string} id (optional) module identifier
// @param {Array.<string>} dependencies ATTENSION! `dependencies` must be array of standard
// module id and there will be NO fault tolerance for argument `dependencies`. Be carefull!
// @param {function(...[*])} factory (require, exports, module)
// @param {Object=} options
// @return {undefined}
function define(id, dependencies, factory, options) {
options || (options = {});
var parsed = parse_id(id);
if (parsed.p) {
// Legacy
// in old times, main entry:
// - define(id_without_ext)
// - define(pkg) <- even older
// now, main entry: define(id_with_ext)
// parsed.p = legacy_transform_id(parsed.p, options);
format_parsed(parsed);
}
var pkg = parsed.k;
var modMain;
if (options.main) {
modMain = mods[pkg];
}
// `mod['a@1.1.0']` must be USED before `mod['a@1.1.0/index.js']`,
// because nobody knows which module is the main entry of 'a@1.1.0'
// But `mod['a@1.1.0/index.js']` might be DEFINED first.
var mod = mods[parsed.id] = modMain || mods[parsed.id] || get_mod(parsed);
if (options.main) {
mods[pkg] = mod;
// Set the real id and path
mix(mod, parsed);
}
mix(mod, options);
// A single module might be defined more than once.
// use this trick to prevent module redefining, avoiding the subsequent side effect.
// mod.factory -> already defined
// X mod.exports -> the module initialization is done
if (!mod.factory) {
mod.factory = factory;
mod.deps = dependencies;
// ['a@0.0.1'] -> {'a' -> 'a@0.0.1'}
generate_module_version_map(dependencies, mod.m);
run_callbacks(mod, 'l');
}
}
// @private
// create version info of the dependencies of current module into current sandbox
// @param {Array.<string>} modules no type detecting
// @param {Object} host
// ['a@~0.1.0', 'b@~2.3.9']
// ->
// {
// a: '~0.1.0',
// b: '~2.3.9'
// }
function generate_module_version_map(modules, host) {
modules.forEach(function(mod) {
var name = mod.split('@')[0];
host[name] = mod;
});
}
// Run the callbacks
function run_callbacks (object, key) {
var callbacks = object[key];
var callback;
// Mark the module is ready
// `delete module.c` is not safe
// #135
// Android 2.2 might treat `null` as [object Global] and equal it to true,
// So, never confuse `null` and `false`
object[key] = FALSE;
while(callback = callbacks.pop()){
callback();
}
}