预分析模块

首先，完成对factory中声明依赖的分析提取
然后，尝试加载"资源加载所需模块"

需要先加载模块的原因是：如果模块不存在，无法进行resourceId normalize化
modAnalyse完成后续的依赖分析处理，并进行依赖模块的加载

@inner
@param {Object} modules 模块对象
490645
function modAnalyse() {
        var requireModules = [];
        var requireModulesIndex = {};

        /**
         * 添加需要请求的模块
         *
         * @inner
         * @param {string} id 模块id
         */
        function addRequireModule( id ) {
            if ( modModules[ id ] || requireModulesIndex[ id ] ) {
                return;
            }

            requireModules.push( id );
            requireModulesIndex[ id ] = 1;
        }

        each( modModuleList, function ( module ) {
            if ( module.state > MODULE_PRE_DEFINED ) {
                return;
            }

            var deps = module.deps;
            var hardDependsCount = 0;
            var factory = module.factory;

            // 分析function body中的require
            // 如果包含显式依赖声明，根据AMD规定和性能考虑，可以不分析factoryBody
            if ( typeof factory === 'function' ) {
                hardDependsCount = Math.min( factory.length, deps.length );

                // If the dependencies argument is present, the module loader
                // SHOULD NOT scan for dependencies within the factory function.
                !module.depsDec && factory.toString()
                    .replace( /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, '' )
                    .replace( /require\(\s*(['"'])([^'"]+)\1\s*\)/g,
                        function ( $0, $1, depId ) {
                            deps.push( depId );
                        }
                    );
            }

            each( deps, function ( depId, index ) {
                var idInfo = parseId( depId );
                var absId = normalize( idInfo.module, module.id );
                var moduleInfo, resInfo;

                if ( absId && !BUILDIN_MODULE[ absId ] ) {
                    // 如果依赖是一个资源，将其信息添加到module.depRs
                    //
                    // module.depRs中的项有可能是重复的。
                    // 在这个阶段，加载resource的module可能还未defined，
                    // 导致此时resource id无法被normalize。
                    //
                    // 比如对a/b/c而言，下面几个resource可能指的是同一个资源：
                    // - js!../name.js
                    // - js!a/name.js
                    // - ../../js!../name.js
                    //
                    // 所以加载资源的module ready时，需要遍历module.depRs进行处理
                    if ( idInfo.resource ) {
                        resInfo = {
                            id       : depId,
                            module   : absId,
                            resource : idInfo.resource
                        };
                        autoDefineModules[ absId ] = 1;
                        module.depPMs.push( absId );
                        module.depRs.push( resInfo );
                    }

                    // 对依赖模块的id normalize能保证正确性，在此处进行去重
                    moduleInfo = module.depMkv[ absId ];
                    if ( !moduleInfo ) {
                        moduleInfo = {
                            id      : idInfo.module,
                            absId   : absId,
                            hard    : index < hardDependsCount
                        };
                        module.depMs.push( moduleInfo );
                        module.depMkv[ absId ] = moduleInfo;
                        addRequireModule( absId );
                    }
                }
                else {
                    moduleInfo = { absId: absId };
                }

                // 如果当前正在分析的依赖项是define中声明的，
                // 则记录到module.factoryDeps中
                // 在factory invoke前将用于生成invoke arguments
                if ( index < hardDependsCount ) {
                    module.factoryDeps.push( resInfo || moduleInfo );
                }
            } );

            module.state = MODULE_ANALYZED;
            modInitFactoryInvoker( module.id );
        });

        modAutoInvoke();
        nativeRequire( requireModules );
    }
762367
function(moduleIds) {
		for (var i = moduleIds.length; i--;) {
			var moduleId = moduleIds[i],
				module = getModule(moduleId);

			if (module == null) {
				module = _modules[moduleId] = {};
				_fetchFunc(moduleId);
			}
		}
	}
757858
function modPreDefine(id, dependencies, factory) {
        // 将模块存入容器
        //
        // 模块内部信息包括
        // -----------------------------------
        // id: module id
        // depsDec: 模块定义时声明的依赖
        // deps: 模块依赖，默认为['require', 'exports', 'module']
        // factory: 初始化函数或对象
        // factoryDeps: 初始化函数的参数依赖
        // exports: 模块的实际暴露对象（AMD定义）
        // config: 用于获取模块配置信息的函数（AMD定义）
        // state: 模块当前状态
        // require: local require函数
        // depMs: 实际依赖的模块集合，数组形式
        // depMkv: 实际依赖的模块集合，表形式，便于查找
        // depRs: 实际依赖的资源集合
        // ------------------------------------
        if (!modModules[id]) {
            modModules[id] = {
                id         : id,
                depsDec    : dependencies,
                deps       : dependencies || ['require', 'exports', 'module'],
                factoryDeps: [],
                factory    : factory,
                exports    : {},
                config     : moduleConfigGetter,
                state      : MODULE_PRE_DEFINED,
                require    : createLocalRequire(id),
                depMs      : [],
                depMkv     : {},
                depRs      : [],
                hang       : 0
            };
        }
    }
406661
function workFn() {
            if (currentSpec.$injector) {
                throw Error('Injector already created, can not register a module!');
            } else {
                var modules = currentSpec.$modules || (currentSpec.$modules = []);
                angular.forEach(moduleFns, function(module) {
                    if (angular.isObject(module) && !angular.isArray(module)) {
                        modules.push(function($provide) {
                            angular.forEach(module, function(value, key) {
                                $provide.value(key, value);
                            });
                        });
                    } else {
                        modules.push(module);
                    }
                });
            }
        }
42346
function (runtime, mod) {
            if (mod.status != LOADED) {
                return;
            }

            var fn = mod.fn;

            if (typeof fn === 'function') {
                // 需要解开 index，相对路径
                // 但是需要保留 alias，防止值不对应
                mod.value = fn.apply(mod, Utils.getModules(runtime, mod.getRequiresWithAlias()));
            } else {
                mod.value = fn;
            }

            mod.status = ATTACHED;
        }
959588
function (runtime, name, fn, config) {
            name = indexMapStr(name);

            var mods = runtime.Env.mods,
                mod = mods[name];

            if (mod && mod.fn) {
                S.log(name + ' is defined more than once', 'warn');
                return;
            }

            // 没有 use，静态载入的 add 可能执行
            Utils.createModuleInfo(runtime, name);

            mod = mods[name];

            // 注意：通过 S.add(name[, fn[, config]]) 注册的代码，无论是页面中的代码，
            // 还是 js 文件里的代码，add 执行时，都意味着该模块已经 LOADED
            S.mix(mod, {
                name: name,
                status: LOADED,
                fn: fn
            });

            S.mix(mod, config);
        }
679005
public Governator addModules(Module ... modules) {
        if (modules != null) {
            this.modules.addAll(Arrays.asList(modules));
        }
        return this;
    }
1081984
function modInitFactoryInvoker( id ) {
        var module = modModules[ id ];
        var invoking;

        module.invokeFactory = invokeFactory;
        each( module.depPMs, function ( pluginModuleId ) {
            modAddDefinedListener( pluginModuleId, function () {
                each( module.depRs, function ( res ) {
                    if ( !res.absId && res.module === pluginModuleId ) {
                        res.absId = normalize( res.id, id );
                        nativeRequire( [ res.absId ], modAutoInvoke );
                    }
                } );
            } );
        } );

        /**
         * 初始化模块
         *
         * @inner
         */
        function invokeFactory() {
            if ( invoking || module.state !== MODULE_PREPARED ) {
                return;
            }

            invoking = 1;

            // 拼接factory invoke所需的arguments
            var factoryReady = 1;
            var factoryDeps = [];
            each(
                module.factoryDeps,
                function ( dep ) {
                    var depId = dep.absId;

                    if ( !BUILDIN_MODULE[ depId ] ) {
                        modTryInvokeFactory( depId );
                        if ( !modIs( depId, MODULE_DEFINED ) ) {
                            factoryReady = 0;
                            return false;
                        }
                    }

                    factoryDeps.push( depId );
                }
            );

            if ( factoryReady ) {
                try {
                    var args = modGetModulesExports(
                        factoryDeps,
                        {
                            require : module.require,
                            exports : module.exports,
                            module  : module
                        }
                    );

                    // 调用factory函数初始化module
                    var factory = module.factory;
                    var exports = typeof factory === 'function'
                        ? factory.apply( global, args )
                        : factory;

                    if ( exports != null ) {
                        module.exports = exports;
                    }

                    module.invokeFactory = null;
                }
                catch ( ex ) {
                    invoking = 0;
                    if ( /^\[MODULE_MISS\]"([^"]+)/.test( ex.message ) ) {
                        // 出错，则说明在factory的运行中，该require的模块是需要的
                        // 所以把它加入强依赖中
                        var hardCirclurDep = module.depMkv[ RegExp.$1 ];
                        hardCirclurDep && (hardCirclurDep.hard = 1);
                        return;
                    }

                    throw ex;
                }

                // 完成define
                // 不放在try里，避免后续的运行错误被这里吞掉
                modDefined( id );
            }
        }
    }
868124
function modTryInvokeFactory( id ) {
        var module = modModules[ id ];

        if ( module && module.invokeFactory ) {
            module.invokeFactory();
        }
    }
648524
function(module) {
		var name = module.$modname;
		if (!this.$hasModule(name)) {
			this._modules.push(module);
			if (gui.Type.isFunction(module.oncontextinitialize)) {
				module.oncontextinitialize(window);
			}
			if (gui.Type.isFunction(module.onrun)) {
				module.onrun();
			}
		} else {
			throw new Error(name + ' loaded twice?');
		}
		return module;
	}
737355
@GetMapping("/modules")
  @ResponseBody
  public ModulesConfigResponse getModules(@RequestParam("entity") String entityTypeId) {
    EntityType entityType = dataService.getEntityType(entityTypeId);
    List<Module> modules = dataExplorerService.getModules(entityType);

    ModulesConfigResponse modulesConfigResponse = new ModulesConfigResponse();
    modules.forEach(
        module -> {
          String id;
          String label;
          String icon;

          switch (module) {
            case DATA:
              id = MOD_DATA;
              label = "Data";
              icon = "grid-icon.png";
              break;
            case AGGREGATION:
              id = "aggregates";
              label =
                  messageSource.getMessage(
                      "dataexplorer_aggregates_title", new Object[] {}, getLocale());
              icon = "aggregate-icon.png";
              break;
            case REPORT:
              id = MOD_ENTITIESREPORT;
              label = dataExplorerSettings.getEntityReport(entityTypeId);
              icon = "report-icon.png";
              break;
            default:
              throw new UnexpectedEnumException(module);
          }

          modulesConfigResponse.add(new ModuleConfig(id, label, icon));
        }
481680
function (modNames, cache, ret) {
            var i,
                m,
                mod,
                modStatus,
                self = this,
                waitingModules = self.waitingModules,
                runtime = self.runtime;

            ret = ret || {};
            // 提高性能，不用每个模块都再次全部依赖计算
            // 做个缓存，每个模块对应的待动态加载模块
            cache = cache || {};

            for (i = 0; i < modNames.length; i++) {
                m = modNames[i];
                if (cache[m]) {
                    continue;
                }
                cache[m] = 1;
                mod = Utils.createModuleInfo(runtime, m);
                modStatus = mod.status;
                if (modStatus === ERROR || modStatus === ATTACHED) {
                    continue;
                }
                if (modStatus != LOADED) {
                    if (!waitingModules.contains(m)) {
                        if (modStatus != LOADING) {
                            mod.status = LOADING;
                            ret[m] = 1;
                        }
                        mod.wait(function (mod) {
                            waitingModules.remove(mod.getName());
                            // notify current loader instance
                            waitingModules.notifyAll();
                        });
                        waitingModules.add(m);
                    }
                }
                self.calculate(mod.getNormalizedRequires(), cache, ret);
            }

            return ret;
        }
851241
function runModules(str, modules) {
    var replacements = [],
        module;

    if (Array.isArray(modules) === false) {
        modules = [modules];
    }

    modules.forEach(function forEachModule(module) {
        if (!module) {
            throw new Error("Unknown module '" + module + "'");
        }

        runModule(module, str, replacements);
    });

    return replacements;
}
1328491
public void initializeMultipleModules( List<? extends IModule> modules ) {
    if (_initialized) {
      throw new IllegalStateException("Illegal attempt to initialize Gosu");
    }
    getGosuInitialization().initializeMultipleModules( _execEnv, modules );
    _initialized = true;
  }
306960
function getModuleDefinitions(modules) {
      return modules.split(',').map(function(md) {
        var split = md.split(':'), name, path, type;
        name = split[0];
        path = './' + name.toLowerCase();
        if (name === 'Locales') {
          type = 'locales';
        } else if (moduleIsPolyfill(name)) {
          type = 'polyfill';
        } else {
          type = 'module';
        }
        return {
          name: name,
          path: path,
          type: type,
          namespace: split[1]
        };
      });
    }
1236574
@Override
    public T addAsModules(final File... resources) throws IllegalArgumentException {
        // Precondition checks
        Validate.notNull(resources, "resources must be specified");

        // Add each
        for (final File resource : resources) {
            this.addAsModule(resource);
        }

        // Return
        return this.covarientReturn();
    }
784485
function loadModule( moduleId ) {
        if ( loadingModules[ moduleId ] || modModules[ moduleId ] ) {
            return;
        }

        loadingModules[ moduleId ] = 1;

        // 创建script标签
        //
        // 这里不挂接onerror的错误处理
        // 因为高级浏览器在devtool的console面板会报错
        // 再throw一个Error多此一举了
        var script = document.createElement( 'script' );
        script.setAttribute( 'data-require-id', moduleId );
        script.src = toUrl( moduleId + '.js' ) ;
        script.async = true;
        if ( script.readyState ) {
            script.onreadystatechange = loadedListener;
        }
        else {
            script.onload = loadedListener;
        }
        appendScript( script );

        /**
         * script标签加载完成的事件处理函数
         *
         * @ignore
         */
        function loadedListener() {
            var readyState = script.readyState;
            if (
                typeof readyState === 'undefined'
                || /^(loaded|complete)$/.test( readyState )
            ) {
                script.onload = script.onreadystatechange = null;
                script = null;

                completePreDefine( moduleId );
            }
        }
    }