1.Analyse require method:
if(global.define){ if(has("dojo-log-api")){ signal(error,makeError("defineAlreadyDefined",0)); } return; }else{ global.define = def; global.require = req; if(has("host-node")){ require= req; } }
req = function( config,//(object,optional) hash of configuration properties dependencies,//(array of commonjs.moduleId,optional) list of modules to be loaded before applying callback callback //(function,optional) lamda expression to apply to module values implied by dependencies ){ return contextRequire(config,dependencies,callback,req); },
contextRequire = function(a1,a2,a3,referenceModule,contextRequire){ var module,syntheticMid; if(isString(a1)){ // signature is (moduleId) module = getModule(a1,true); if(module && module.executed){ return module.result; } throw makeError("undefinedModule",a1); } if(!isArray(a1)){ // a1 is a configuration config(a1,referenceModule); // juggle args; (a2,a3) may be (dependencies,callback) a1 = a2; a2 = a3; } if(isArray(a1)){ // signature is (requestList [,callback]) if(!a1.length){ a2 && a2(); }else{ syntheticMid = "require*" + uid(); // resolve the request list with respect to the reference module for(var mid,deps = [],i = 0; i < a1.length;){ mid = a1[i++]; deps.push(getModule(mid,referenceModule)); } // construct a synthetic module to control execution of the requestList,and,optionally,callback module = mix(makeModuleInfo("",syntheticMid,""),{ injected: arrived,deps: deps,def: a2 || noop,require: referenceModule ? referenceModule.require : req,gc: 1 //garbage collect }); modules[module.mid] = module; // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies injectDependencies(module); // try to immediately execute // if already traversing a factory tree,then strict causes circular dependency to abort the execution; maybe // it's possible to execute this require later after the current traversal completes and avoid the circular dependency. // ...but *always* insist on immediate in synch mode var strict = checkCompleteGuard && legacyMode!=sync; guardCheckComplete(function(){ execModule(module,strict); }); if(!module.executed){ // some deps weren't on board or circular dependency detected and strict; therefore,push into the execQ execQ.push(module); } checkComplete(); } } return contextRequire; },
getModule = function(mid,immediate){ // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule var match,plugin,prid,result; match = mid.match(/^(.+?)\!(.*)$/); if(match){ // name was <plugin-module>!<plugin-resource-id> plugin = getModule(match[1],immediate); if(has("dojo-sync-loader") && legacyMode == sync && !plugin.executed){ injectModule(plugin); if(plugin.injected===arrived && !plugin.executed){ guardCheckComplete(function(){ execModule(plugin); }); } if(plugin.executed){ promoteModuleToPlugin(plugin); }else{ // we are in xdomain mode for some reason execQ.unshift(plugin); } } if(plugin.executed === executed && !plugin.load){ // executed the module not knowing it was a plugin promoteModuleToPlugin(plugin); } // if the plugin has not been loaded,then can't resolve the prid and must assume this plugin is dynamic until we find out otherwise if(plugin.load){ prid = resolvePluginResourceId(plugin,match[2],referenceModule); mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid); }else{ prid = match[2]; mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin"; } result = {plugin:plugin,mid:mid,req:createRequire(referenceModule),prid:prid}; }else{ result = getModuleInfo(mid,referenceModule); } return modules[result.mid] || (!immediate && (modules[result.mid] = result)); },原文链接:https://www.f2er.com/dojo/291491.html