| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780 | /** * ESL (Enterprise Standard Loader) * Copyright 2013 Baidu Inc. All rights reserved. * * @file Browser端标准加载器,符合AMD规范 * @author errorrik(errorrik@gmail.com) *         Firede(firede@firede.us) */var define;var require;(function ( global ) {    // "mod"开头的变量或函数为内部模块管理函数    // 为提高压缩率,不使用function或object包装    /**     * 模块容器     *     * @inner     * @type {Object}     */    var modModules = {};    var MODULE_STATE_PRE_DEFINED = 1;    var MODULE_STATE_PRE_ANALYZED = 2;    var MODULE_STATE_ANALYZED = 3;    var MODULE_STATE_READY = 4;    var MODULE_STATE_DEFINED = 5;    /**     * 全局require函数     *     * @inner     * @type {Function}     */    var actualGlobalRequire = createLocalRequire( '' );    /**     * 超时提醒定时器     *     * @inner     * @type {number}     */    var waitTimeout;    /**     * 加载模块     *     * @param {string|Array} requireId 模块id或模块id数组,     * @param {Function=} callback 加载完成的回调函数     * @return {*}     */    function require( requireId, callback ) {        assertNotContainRelativeId( requireId );        // 超时提醒        var timeout = requireConf.waitSeconds;        if ( isArray( requireId ) && timeout ) {            if ( waitTimeout ) {                clearTimeout( waitTimeout );            }            waitTimeout = setTimeout( waitTimeoutNotice, timeout * 1000 );        }        return actualGlobalRequire( requireId, callback );    }    /**     * 将模块标识转换成相对的url     *     * @param {string} id 模块标识     * @return {string}     */    require.toUrl = toUrl;    /**     * 超时提醒函数     *     * @inner     */    function waitTimeoutNotice() {        var hangModules = [];        var missModules = [];        var missModulesMap = {};        var hasError;        for ( var id in modModules ) {            if ( !modIsDefined( id ) ) {                hangModules.push( id );                hasError = 1;            }            each(                modModules[ id ].realDeps || [],                function ( depId ) {                    if ( !modModules[ depId ] && !missModulesMap[ depId ] ) {                        hasError = 1;                        missModules.push( depId );                        missModulesMap[ depId ] = 1;                    }                }            );        }        if ( hasError ) {            throw new Error( '[MODULE_TIMEOUT]Hang( '                + ( hangModules.join( ', ' ) || 'none' )                + ' ) Miss( '                + ( missModules.join( ', ' ) || 'none' )                + ' )'            );        }    }    /**     * 尝试完成模块定义的定时器     *     * @inner     * @type {number}     */    var tryDefineTimeout;    /**     * 定义模块     *     * @param {string=} id 模块标识     * @param {Array=} dependencies 依赖模块列表     * @param {Function=} factory 创建模块的工厂方法     */    function define() {        var argsLen = arguments.length;        if ( !argsLen ) {            return;        }        var id;        var dependencies;        var factory = arguments[ --argsLen ];        while ( argsLen-- ) {            var arg = arguments[ argsLen ];            if ( isString( arg ) ) {                id = arg;            }            else if ( isArray( arg ) ) {                dependencies = arg;            }        }        // 出现window不是疏忽        // esl设计是做为browser端的loader        // 闭包的global更多意义在于:        //     define和require方法可以被挂到用户自定义对象中        var opera = window.opera;        // IE下通过current script的data-require-id获取当前id        if (            !id            && document.attachEvent            && (!(opera && opera.toString() === '[object Opera]'))        ) {            var currentScript = getCurrentScript();            id = currentScript && currentScript.getAttribute('data-require-id');        }        // 处理依赖声明        // 默认为['require', 'exports', 'module']        dependencies = dependencies || ['require', 'exports', 'module'];        if ( id ) {            modPreDefine( id, dependencies, factory );            // 在不远的未来尝试完成define            // define可能是在页面中某个地方调用,不一定是在独立的文件被require装载            if ( tryDefineTimeout ) {                clearTimeout( tryDefineTimeout );            }            tryDefineTimeout = setTimeout( modPreAnalyse, 10 );        }        else {            // 纪录到共享变量中,在load或readystatechange中处理            wait4PreDefines.push( {                deps    : dependencies,                factory : factory            } );        }    }    define.amd = {};    /**     * 获取相应状态的模块列表     *     * @inner     * @param {number} state 状态码     * @return {Array}     */    function modGetByState( state ) {        var modules = [];        for ( var key in modModules ) {            var module = modModules[ key ];            if ( module.state == state ) {                modules.push( module );            }        }        return modules;    }    /**     * 模块配置获取函数     *     * @inner     * @return {Object} 模块配置对象     */    function moduleConfigGetter() {        var conf = requireConf.config[ this.id ];        if ( conf && typeof conf === 'object' ) {            return conf;        }        return {};    }    /**     * 预定义模块     *     * @inner     * @param {string} id 模块标识     * @param {Array.<string>} dependencies 显式声明的依赖模块列表     * @param {*} factory 模块定义函数或模块对象     */    function modPreDefine( id, dependencies, factory ) {        if ( modExists( id ) ) {            return;        }        var module = {            id       : id,            deps     : dependencies,            factory  : factory,            exports  : {},            config   : moduleConfigGetter,            state    : MODULE_STATE_PRE_DEFINED,            hardDeps : {}        };        // 将模块预存入defining集合中        modModules[ id ] = module;    }    /**     * 预分析模块     *     * 首先,完成对factory中声明依赖的分析提取     * 然后,尝试加载"资源加载所需模块"     *     * 需要先加载模块的原因是:如果模块不存在,无法进行resourceId normalize化     * modAnalyse完成后续的依赖分析处理,并进行依赖模块的加载     *     * @inner     * @param {Object} modules 模块对象     */    function modPreAnalyse() {        var pluginModuleIds = [];        var pluginModuleIdsMap = {};        var modules = modGetByState( MODULE_STATE_PRE_DEFINED );        each(            modules,            function ( module ) {                // 处理实际需要加载的依赖                var realDepends = module.deps.slice( 0 );                module.realDeps = realDepends;                // 分析function body中的require                // 如果包含显式依赖声明,为性能考虑,可以不分析factoryBody                // AMD规范的说明是`SHOULD NOT`,所以这里还是分析了                var factory = module.factory;                var requireRule = /require\(\s*(['"'])([^'"]+)\1\s*\)/g;                var commentRule = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;                if ( isFunction( factory ) ) {                    factory.toString()                        .replace( commentRule, '' )                        .replace( requireRule, function ( $0, $1, $2 ) {                            realDepends.push( $2 );                        });                }                // 分析resource加载的plugin module id                each(                    realDepends,                    function ( dependId ) {                        var idInfo = parseId( dependId );                        if ( idInfo.resource ) {                            var plugId = normalize( idInfo.module, module.id );                            if ( !pluginModuleIdsMap[ plugId ] ) {                                pluginModuleIds.push( plugId );                                pluginModuleIdsMap[ plugId ] = 1;                            }                        }                    }                );                module.state = MODULE_STATE_PRE_ANALYZED;            }        );        nativeRequire( pluginModuleIds, function () {            modAnalyse( modules );        } );    }    /**     * 分析模块     * 对所有依赖id进行normalize化,完成分析,并尝试加载其依赖的模块     *     * @inner     * @param {Array} modules 模块对象列表     */    function modAnalyse( modules ) {        var requireModules = [];        each(            modules,            function ( module ) {                if ( module.state !== MODULE_STATE_PRE_ANALYZED ) {                    return;                }                var id = module.id;                // 对参数中声明的依赖进行normalize                var depends = module.deps;                var hardDepends = module.hardDeps;                var hardDependsCount = isFunction( module.factory )                    ? module.factory.length                    : 0;                each(                    depends,                    function ( dependId, index ) {                        dependId = normalize( dependId, id );                        depends[ index ] = dependId;                        if ( index < hardDependsCount ) {                            hardDepends[ dependId ] = 1;                        }                    }                );                // 依赖模块id normalize化,并去除必要的依赖。去除的依赖模块有:                // 1. 内部模块:require/exports/module                // 2. 重复模块:dependencies参数和内部require可能重复                // 3. 空模块:dependencies中使用者可能写空                var realDepends = module.realDeps;                var len = realDepends.length;                var existsDepend = {};                while ( len-- ) {                    // 此处和上部分循环存在重复normalize,因为deps和realDeps是重复的                    // 为保持逻辑分界清晰,就不做优化了先                    var dependId = normalize( realDepends[ len ], id );                    if ( !dependId                         || dependId in existsDepend                         || dependId in BUILDIN_MODULE                    ) {                        realDepends.splice( len, 1 );                    }                    else {                        existsDepend[ dependId ] = 1;                        realDepends[ len ] = dependId;                        // 将实际依赖压入加载序列中,后续统一进行require                        requireModules.push( dependId );                    }                }                module.realDepsIndex = existsDepend;                module.state = MODULE_STATE_ANALYZED;                modWaitDependenciesLoaded( module );                modInvokeFactoryDependOn( id );            }        );        nativeRequire( requireModules );    }    /**     * 等待模块依赖加载完成     * 加载完成后尝试调用factory完成模块定义     *     * @inner     * @param {Object} module 模块对象     */    function modWaitDependenciesLoaded( module ) {        var id = module.id;        module.invokeFactory = invokeFactory;        invokeFactory();        // 用于避免死依赖链的死循环尝试        var checkingLevel = 0;        /**         * 判断依赖加载完成         *         * @inner         * @return {boolean}         */        function checkInvokeReadyState() {            checkingLevel++;            var isReady = 1;            var tryDeps = [];            each(                module.realDeps,                function ( depId ) {                    if ( !modIsAnalyzed( depId ) ) {                        isReady = 0;                    }                    else if ( !modIsDefined( depId ) ) {                        switch ( modHasCircularDependency( id, depId ) ) {                            case CIRCULAR_DEP_UNREADY:                            case CIRCULAR_DEP_NO:                                isReady = 0;                                break;                            case CIRCULAR_DEP_YES:                                if ( module.hardDeps[ depId ] ) {                                    tryDeps.push( depId );                                }                                break;                        }                    }                    return !!isReady;                }            );            // 只有当其他非循环依赖都装载了,才去尝试触发硬依赖模块的初始化            isReady && each(                tryDeps,                function ( depId ) {                    modTryInvokeFactory( depId );                }            );            isReady = isReady && tryDeps.length === 0;            isReady && (module.state = MODULE_STATE_READY);            checkingLevel--;            return isReady;        }        /**         * 初始化模块         *         * @inner         */        function invokeFactory() {            if ( module.state == MODULE_STATE_DEFINED                || checkingLevel > 1                || !checkInvokeReadyState()            ) {                return;            }            // 调用factory函数初始化module            try {                var factory = module.factory;                var exports = isFunction( factory )                    ? factory.apply(                        global,                        modGetModulesExports(                            module.deps,                            {                                require : createLocalRequire( id ),                                exports : module.exports,                                module  : module                            }                        )                    )                    : factory;                if ( typeof exports != 'undefined' ) {                    module.exports = exports;                }                module.state = MODULE_STATE_DEFINED;                module.invokeFactory = null;            }            catch ( ex ) {                if ( /^\[MODULE_MISS\]"([^"]+)/.test( ex.message ) ) {                    // 出错说明在factory的运行中,该require的模块是需要的                    // 所以把它加入硬依赖中                    module.hardDeps[ RegExp.$1 ] = 1;                    return;                }                throw ex;            }            modInvokeFactoryDependOn( id );            modFireDefined( id );        }    }    /**     * 根据模块id数组,获取其的exports数组     * 用于模块初始化的factory参数或require的callback参数生成     *     * @inner     * @param {Array} modules 模块id数组     * @param {Object} buildinModules 内建模块对象     * @return {Array}     */    function modGetModulesExports( modules, buildinModules ) {        var args = [];        each(            modules,            function ( moduleId, index ) {                args[ index ] =                    buildinModules[ moduleId ]                    || modGetModuleExports( moduleId );            }        );        return args;    }    var CIRCULAR_DEP_UNREADY = 0;    var CIRCULAR_DEP_NO = 1;    var CIRCULAR_DEP_YES = 2;    /**     * 判断source是否处于target的依赖链中     *     * @inner     * @return {number}     */    function modHasCircularDependency( source, target, meet ) {        if ( !modIsAnalyzed( target ) ) {            return CIRCULAR_DEP_UNREADY;        }        meet = meet || {};        meet[ target ] = 1;        if ( target == source ) {            return CIRCULAR_DEP_YES;        }        var module = modGetModule( target );        var depends = module && module.realDeps;        if ( depends ) {            var len = depends.length;            while ( len-- ) {                var dependId = depends[ len ];                if ( meet[ dependId ] ) {                    continue;                }                var state = modHasCircularDependency( source, dependId, meet );                switch ( state ) {                    case CIRCULAR_DEP_UNREADY:                    case CIRCULAR_DEP_YES:                        return state;                }            }        }        return CIRCULAR_DEP_NO;    }    /**     * 让依赖自己的模块尝试初始化     *     * @inner     * @param {string} id 模块id     */    function modInvokeFactoryDependOn( id ) {        for ( var key in modModules ) {            var realDeps = modModules[ key ].realDepsIndex || {};            realDeps[ id ] && modTryInvokeFactory( key );        }    }    /**     * 尝试执行模块factory函数,进行模块初始化     *     * @inner     * @param {string} id 模块id     */    function modTryInvokeFactory( id ) {        var module = modModules[ id ];        if ( module && module.invokeFactory ) {            module.invokeFactory();        }    }    /**     * 模块定义完成的事件监听器     *     * @inner     * @type {Array}     */    var modDefinedListener = [];    /**     * 模块定义完成事件监听器的移除索引     *     * @inner     * @type {Array}     */    var modRemoveListenerIndex = [];    /**     * 模块定义完成事件fire层级     *     * @inner     * @type {number}     */    var modFireLevel = 0;    /**     * 派发模块定义完成事件     *     * @inner     * @param {string} id 模块标识     */    function modFireDefined( id ) {        modFireLevel++;        each(            modDefinedListener,            function ( listener ) {                listener && listener( id );            }        );        modFireLevel--;        modSweepDefinedListener();    }    /**     * 清理模块定义完成事件监听器     * modRemoveDefinedListener时只做标记     * 在modFireDefined执行清除动作     *     * @inner     * @param {Function} listener 模块定义监听器     */    function modSweepDefinedListener() {        if ( modFireLevel < 1 ) {            modRemoveListenerIndex.sort(                function ( a, b ) { return b - a; }            );            each(                modRemoveListenerIndex,                function ( index ) {                    modDefinedListener.splice( index, 1 );                }            );            modRemoveListenerIndex = [];        }    }    /**     * 移除模块定义监听器     *     * @inner     * @param {Function} listener 模块定义监听器     */    function modRemoveDefinedListener( listener ) {        each(            modDefinedListener,            function ( item, index ) {                if ( listener == item ) {                    modRemoveListenerIndex.push( index );                }            }        );    }    /**     * 添加模块定义监听器     *     * @inner     * @param {Function} listener 模块定义监听器     */    function modAddDefinedListener( listener ) {        modDefinedListener.push( listener );    }    /**     * 判断模块是否存在     *     * @inner     * @param {string} id 模块标识     * @return {boolean}     */    function modExists( id ) {        return id in modModules;    }    /**     * 判断模块是否已定义完成     *     * @inner     * @param {string} id 模块标识     * @return {boolean}     */    function modIsDefined( id ) {        return modExists( id )            && modModules[ id ].state == MODULE_STATE_DEFINED;    }    /**     * 判断模块是否已分析完成     *     * @inner     * @param {string} id 模块标识     * @return {boolean}     */    function modIsAnalyzed( id ) {        return modExists( id )            && modModules[ id ].state >= MODULE_STATE_ANALYZED;    }    /**     * 获取模块的exports     *     * @inner     * @param {string} id 模块标识     * @return {*}     */    function modGetModuleExports( id ) {        if ( modIsDefined( id ) ) {            return modModules[ id ].exports;        }        return null;    }    /**     * 获取模块     *     * @inner     * @param {string} id 模块标识     * @return {Object}     */    function modGetModule( id ) {        return modModules[ id ];    }    /**     * 添加资源     *     * @inner     * @param {string} resourceId 资源标识     * @param {*} value 资源对象     */    function modAddResource( resourceId, value ) {        modModules[ resourceId ] = {            exports: value || true,            state: MODULE_STATE_DEFINED        };        modInvokeFactoryDependOn( resourceId );        modFireDefined( resourceId );    }    /**     * 内建module名称集合     *     * @inner     * @type {Object}     */    var BUILDIN_MODULE = {        require : require,        exports : 1,        module  : 1    };    /**     * 未预定义的模块集合     * 主要存储匿名方式define的模块     *     * @inner     * @type {Array}     */    var wait4PreDefines = [];    /**     * 完成模块预定义     *     * @inner     */    function completePreDefine( currentId ) {        var preDefines = wait4PreDefines.slice( 0 );        wait4PreDefines.length = 0;        wait4PreDefines = [];        // 预定义模块:        // 此时处理的模块都是匿名define的模块        each(            preDefines,            function ( module ) {                var id = module.id || currentId;                modPreDefine( id, module.deps, module.factory );            }        );        modPreAnalyse();    }    /**     * 获取模块     *     * @param {string|Array} ids 模块名称或模块名称列表     * @param {Function=} callback 获取模块完成时的回调函数     * @return {Object}     */    function nativeRequire( ids, callback, baseId ) {        callback = callback || new Function();        baseId = baseId || '';        // 根据 https://github.com/amdjs/amdjs-api/wiki/require        // It MUST throw an error if the module has not        // already been loaded and evaluated.        if ( isString( ids ) ) {            if ( !modIsDefined( ids ) ) {                throw new Error( '[MODULE_MISS]"' + ids + '" is not exists!' );            }            return modGetModuleExports( ids );        }        if ( !isArray( ids ) ) {            return;        }        if ( ids.length === 0 ) {            callback();            return;        }        var isCallbackCalled = 0;        modAddDefinedListener( tryFinishRequire );        each(            ids,            function ( id ) {                if ( id in BUILDIN_MODULE ) {                    return;                }                ( id.indexOf( '!' ) > 0                    ? loadResource                    : loadModule                )( id, baseId );            }        );        tryFinishRequire();        /**         * 尝试完成require,调用callback         * 在模块与其依赖模块都加载完时调用         *         * @inner         */        function tryFinishRequire() {            if ( isCallbackCalled ) {                return;            }            var visitedModule = {};            /**             * 判断是否所有模块都已经加载完成,包括其依赖的模块             *             * @inner             * @param {Array} modules 直接模块标识列表             * @return {boolean}             */            function isAllInited( modules ) {                var allInited = 1;                each(                    modules,                    function ( id ) {                        if ( visitedModule[ id ] ) {                            return;                        }                        visitedModule[ id ] = 1;                        if ( BUILDIN_MODULE[ id ] ) {                            return;                        }                        if (                            !modIsDefined( id )                            || !isAllInited( modGetModule( id ).realDeps )                        ) {                            allInited = 0;                            return false;                        }                    }                );                return allInited;            }            // 检测并调用callback            if ( isAllInited( ids ) ) {                isCallbackCalled = 1;                modRemoveDefinedListener( tryFinishRequire );                callback.apply(                    global,                    modGetModulesExports( ids, BUILDIN_MODULE )                );            }        }    }    /**     * 正在加载的模块列表     *     * @inner     * @type {Object}     */    var loadingModules = {};    /**     * 加载模块     *     * @inner     * @param {string} moduleId 模块标识     */    function loadModule( moduleId ) {        if ( loadingModules[ moduleId ] ) {            return;        }        if ( modExists( moduleId ) ) {            modAnalyse( [ modGetModule( 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 ) ;        script.async = true;        if ( script.readyState ) {            script.onreadystatechange = loadedListener;        }        else {            script.onload = loadedListener;        }        appendScript( script );        /**         * script标签加载完成的事件处理函数         *         * @inner         */        function loadedListener() {            var readyState = script.readyState;            if (                typeof readyState == 'undefined'                || /^(loaded|complete)$/.test( readyState )            ) {                script.onload = script.onreadystatechange = null;                script = null;                completePreDefine( moduleId );                delete loadingModules[ moduleId ];            }        }    }    /**     * 加载资源     *     * @inner     * @param {string} pluginAndResource 插件与资源标识     * @param {string} baseId 当前环境的模块标识     */    function loadResource( pluginAndResource, baseId ) {        var idInfo = parseId( pluginAndResource );        var pluginId = idInfo.module;        var resourceId = idInfo.resource;        /**         * plugin加载完成的回调函数         *         * @inner         * @param {*} value resource的值         */        function pluginOnload( value ) {            modAddResource( pluginAndResource, value );        }        /**         * 该方法允许plugin使用加载的资源声明模块         *         * @param {string} name 模块id         * @param {string} body 模块声明字符串         */        pluginOnload.fromText = function ( id, text ) {            new Function( text )();            completePreDefine( id );        };        /**         * 加载资源         *         * @inner         * @param {Object} plugin 用于加载资源的插件模块         */        function load( plugin ) {            if ( !modIsDefined( pluginAndResource ) ) {                plugin.load(                    resourceId,                    createLocalRequire( baseId ),                    pluginOnload,                    moduleConfigGetter.call( { id: pluginAndResource } )                );            }        }        if ( !modIsDefined( pluginId ) ) {            nativeRequire( [ pluginId ], load );        }        else {            load( modGetModuleExports( pluginId ) );        }    }    /**     * require配置     *     * @inner     * @type {Object}     */    var requireConf = {        baseUrl     : './',        paths       : {},        config      : {},        map         : {},        packages    : [],        waitSeconds : 0,        urlArgs     : {}    };    /**     * 混合当前配置项与用户传入的配置项     *     * @inner     * @param {string} name 配置项名称     * @param {Any} value 用户传入配置项的值     */    function mixConfig( name, value ) {        var originValue = requireConf[ name ];        var type = typeof originValue;        if ( type == 'string' || type == 'number' ) {            requireConf[ name ] = value;        }        else if ( isArray( originValue ) ) {            each( value, function ( item ) {                originValue.push( item );            } );        }        else {            for ( var key in value ) {                originValue[ key ] = value[ key ];            }        }    }    /**     * 配置require     *     * @param {Object} conf 配置对象     */    require.config = function ( conf ) {        // 简单的多处配置还是需要支持        // 所以实现更改为二级mix        for ( var key in requireConf ) {            if ( conf.hasOwnProperty( key ) ) {                var confItem = conf[ key ];                if ( key == 'urlArgs' && isString( confItem ) ) {                    defaultUrlArgs = confItem;                }                else {                    mixConfig( key, confItem );                }            }        }        createConfIndex();    };    // 初始化时需要创建配置索引    createConfIndex();    /**     * 创建配置信息内部索引     *     * @inner     */    function createConfIndex() {        requireConf.baseUrl = requireConf.baseUrl.replace( /\/$/, '' ) + '/';        createPathsIndex();        createMappingIdIndex();        createPackagesIndex();        createUrlArgsIndex();    }    /**     * packages内部索引     *     * @inner     * @type {Array}     */    var packagesIndex;    /**     * 创建packages内部索引     *     * @inner     */    function createPackagesIndex() {        packagesIndex = [];        each(            requireConf.packages,            function ( packageConf ) {                var pkg = packageConf;                if ( isString( packageConf ) ) {                    pkg = {                        name: packageConf.split('/')[ 0 ],                        location: packageConf,                        main: 'main'                    };                }                pkg.location = pkg.location || pkg.name;                pkg.main = (pkg.main || 'main').replace(/\.js$/i, '');                packagesIndex.push( pkg );            }        );        packagesIndex.sort( createDescSorter( 'name' ) );    }    /**     * paths内部索引     *     * @inner     * @type {Array}     */    var pathsIndex;    /**     * 创建paths内部索引     *     * @inner     */    function createPathsIndex() {        pathsIndex = kv2List( requireConf.paths );        pathsIndex.sort( createDescSorter() );    }    /**     * 默认的urlArgs     *     * @inner     * @type {string}     */    var defaultUrlArgs;    /**     * urlArgs内部索引     *     * @inner     * @type {Array}     */    var urlArgsIndex;    /**     * 创建urlArgs内部索引     *     * @inner     */    function createUrlArgsIndex() {        urlArgsIndex = kv2List( requireConf.urlArgs );        urlArgsIndex.sort( createDescSorter() );    }    /**     * mapping内部索引     *     * @inner     * @type {Array}     */    var mappingIdIndex;    /**     * 创建mapping内部索引     *     * @inner     */    function createMappingIdIndex() {        mappingIdIndex = [];        mappingIdIndex = kv2List( requireConf.map );        mappingIdIndex.sort( createDescSorter() );        each(            mappingIdIndex,            function ( item ) {                var key = item.k;                item.v = kv2List( item.v );                item.v.sort( createDescSorter() );                item.reg = key == '*'                    ? /^/                    : createPrefixRegexp( key );            }        );    }    /**     * 将`模块标识+'.extension'`形式的字符串转换成相对的url     *     * @inner     * @param {string} source 源字符串     * @return {string}     */    function toUrl( source ) {        // 分离 模块标识 和 .extension        var extReg = /(\.[a-z0-9]+)$/i;        var queryReg = /(\?[^#]*)$/i;        var extname = '.js';        var id = source;        var query = '';        if ( queryReg.test( source ) ) {            query = RegExp.$1;            source = source.replace( queryReg, '' );        }        if ( extReg.test( source ) ) {            extname = RegExp.$1;            id = source.replace( extReg, '' );        }        // 模块标识合法性检测        if ( !MODULE_ID_REG.test( id ) ) {            return source;        }        var url = id;        // paths处理和匹配        var isPathMap;        each( pathsIndex, function ( item ) {            var key = item.k;            if ( createPrefixRegexp( key ).test( id ) ) {                url = url.replace( key, item.v );                isPathMap = 1;                return false;            }        } );        // packages处理和匹配        if ( !isPathMap ) {            each(                packagesIndex,                function ( packageConf ) {                    var name = packageConf.name;                    if ( createPrefixRegexp( name ).test( id ) ) {                        url = url.replace( name, packageConf.location );                        return false;                    }                }            );        }        // 相对路径时,附加baseUrl        if ( !/^([a-z]{2,10}:\/)?\//i.test( url ) ) {            url = requireConf.baseUrl + url;        }        // 附加 .extension 和 query        url += extname + query;        var isUrlArgsAppended;        /**         * 为url附加urlArgs         *         * @inner         * @param {string} args urlArgs串         */        function appendUrlArgs( args ) {            if ( !isUrlArgsAppended ) {                url += ( url.indexOf( '?' ) > 0 ? '&' : '?' ) + args;                isUrlArgsAppended = 1;            }        }        // urlArgs处理和匹配        each( urlArgsIndex, function ( item ) {            if ( createPrefixRegexp( item.k ).test( id ) ) {                appendUrlArgs( item.v );                return false;            }        } );        defaultUrlArgs && appendUrlArgs( defaultUrlArgs );        return url;    }    /**     * 创建local require函数     *     * @inner     * @param {number} baseId 当前module id     * @return {Function}     */    function createLocalRequire( baseId ) {        var requiredCache = {};        function req( requireId, callback ) {            if ( isString( requireId ) ) {                var requiredModule;                if ( !( requiredModule = requiredCache[ requireId ] ) ) {                    requiredModule = nativeRequire(                        normalize( requireId, baseId ),                        callback,                        baseId                    );                    requiredCache[ requireId ] = requiredModule;                }                return requiredModule;            }            else if ( isArray( requireId ) ) {                // 分析是否有resource使用的plugin没加载                var unloadedPluginModules = [];                each(                    requireId,                    function ( id ) {                        var idInfo = parseId( id );                        var pluginId = normalize( idInfo.module, baseId );                        if ( idInfo.resource && !modIsDefined( pluginId ) ) {                            unloadedPluginModules.push( pluginId );                        }                    }                );                // 加载模块                nativeRequire(                    unloadedPluginModules,                    function () {                        var ids = [];                        each(                            requireId,                            function ( id ) {                                ids.push( normalize( id, baseId ) );                            }                        );                        nativeRequire( ids, callback, baseId );                    },                    baseId                );            }        }        /**         * 将[module ID] + '.extension'格式的字符串转换成url         *         * @inner         * @param {string} source 符合描述格式的源字符串         * @return {string}         */        req.toUrl = function ( id ) {            return toUrl( normalize( id, baseId ) );        };        return req;    }    /**     * id normalize化     *     * @inner     * @param {string} id 需要normalize的模块标识     * @param {string} baseId 当前环境的模块标识     * @return {string}     */    function normalize( id, baseId ) {        if ( !id ) {            return '';        }        var idInfo = parseId( id );        if ( !idInfo ) {            return id;        }        var resourceId = idInfo.resource;        var moduleId = relative2absolute( idInfo.module, baseId );        each(            packagesIndex,            function ( packageConf ) {                var name = packageConf.name;                var main = name + '/' + packageConf.main;                if ( name == moduleId                ) {                    moduleId = moduleId.replace( name, main );                    return false;                }            }        );        moduleId = mappingId( moduleId, baseId );        if ( resourceId ) {            var module = modGetModuleExports( moduleId );            resourceId = module && module.normalize                ? module.normalize(                    resourceId,                    function ( resId ) {                        return normalize( resId, baseId );                    }                  )                : normalize( resourceId, baseId );            return moduleId + '!' + resourceId;        }        return moduleId;    }    /**     * 相对id转换成绝对id     *     * @inner     * @param {string} id 要转换的id     * @param {string} baseId 当前所在环境id     * @return {string}     */    function relative2absolute( id, baseId ) {        if ( /^\.{1,2}/.test( id ) ) {            var basePath = baseId.split( '/' );            var namePath = id.split( '/' );            var baseLen = basePath.length - 1;            var nameLen = namePath.length;            var cutBaseTerms = 0;            var cutNameTerms = 0;            pathLoop: for ( var i = 0; i < nameLen; i++ ) {                var term = namePath[ i ];                switch ( term ) {                    case '..':                        if ( cutBaseTerms < baseLen ) {                            cutBaseTerms++;                            cutNameTerms++;                        }                        else {                            break pathLoop;                        }                        break;                    case '.':                        cutNameTerms++;                        break;                    default:                        break pathLoop;                }            }            basePath.length = baseLen - cutBaseTerms;            namePath = namePath.slice( cutNameTerms );            basePath.push.apply( basePath, namePath );            return basePath.join( '/' );        }        return id;    }    /**     * 确定require的模块id不包含相对id。用于global require,提前预防难以跟踪的错误出现     *     * @inner     * @param {string|Array} requireId require的模块id     */    function assertNotContainRelativeId( requireId ) {        var invalidIds = [];        /**         * 监测模块id是否relative id         *         * @inner         * @param {string} id 模块id         */        function monitor( id ) {            if ( /^\.{1,2}/.test( id ) ) {                invalidIds.push( id );            }        }        if ( isString( requireId ) ) {            monitor( requireId );        }        else {            each(                requireId,                function ( id ) {                    monitor( id );                }            );        }        // 包含相对id时,直接抛出错误        if ( invalidIds.length > 0 ) {            throw new Error(                '[REQUIRE_FATAL]Relative ID is not allowed in global require: '                + invalidIds.join( ', ' )            );        }    }    /**     * 模块id正则     *     * @const     * @inner     * @type {RegExp}     */    var MODULE_ID_REG = /^[-_a-z0-9\.]+(\/[-_a-z0-9\.]+)*$/i;    /**     * 解析id,返回带有module和resource属性的Object     *     * @inner     * @param {string} id 标识     * @return {Object}     */    function parseId( id ) {        var segs = id.split( '!' );        if ( MODULE_ID_REG.test( segs[ 0 ] ) ) {            return {                module   : segs[ 0 ],                resource : segs[ 1 ] || ''            };        }        return null;    }    /**     * 基于map配置项的id映射     *     * @inner     * @param {string} id 模块id     * @param {string} baseId 当前环境的模块id     * @return {string}     */    function mappingId( id, baseId ) {        each(            mappingIdIndex,            function ( item ) {                if ( item.reg.test( baseId ) ) {                    each( item.v, function ( mapData ) {                        var key = mapData.k;                        var rule = createPrefixRegexp( key );                        if ( rule.test( id ) ) {                            id = id.replace( key, mapData.v );                            return false;                        }                    } );                    return false;                }            }        );        return id;    }    /**     * 将对象数据转换成数组,数组每项是带有k和v的Object     *     * @inner     * @param {Object} source 对象数据     * @return {Array.<Object>}     */    function kv2List( source ) {        var list = [];        for ( var key in source ) {            if ( source.hasOwnProperty( key ) ) {                list.push( {                    k: key,                    v: source[ key ]                } );            }        }        return list;    }    // 感谢requirejs,通过currentlyAddingScript兼容老旧ie    //    // For some cache cases in IE 6-8, the script executes before the end    // of the appendChild execution, so to tie an anonymous define    // call to the module name (which is stored on the node), hold on    // to a reference to this node, but clear after the DOM insertion.    var currentlyAddingScript;    var interactiveScript;    /**     * 获取当前script标签     * 用于ie下define未指定module id时获取id     *     * @inner     * @return {HTMLDocument}     */    function getCurrentScript() {        if ( currentlyAddingScript ) {            return currentlyAddingScript;        }        else if (            interactiveScript            && interactiveScript.readyState == 'interactive'        ) {            return interactiveScript;        }        else {            var scripts = document.getElementsByTagName( 'script' );            var scriptLen = scripts.length;            while ( scriptLen-- ) {                var script = scripts[ scriptLen ];                if ( script.readyState == 'interactive' ) {                    interactiveScript = script;                    return script;                }            }        }    }    /**     * 向页面中插入script标签     *     * @inner     * @param {HTMLScriptElement} script script标签     */    function appendScript( script ) {        currentlyAddingScript = script;        var doc = document;        (doc.getElementsByTagName('head')[0] || doc.body).appendChild( script );        currentlyAddingScript = null;    }    /**     * 创建id前缀匹配的正则对象     *     * @inner     * @param {string} prefix id前缀     * @return {RegExp}     */    function createPrefixRegexp( prefix ) {        return new RegExp( '^' + prefix + '(/|$)' );    }    /**     * 判断对象是否数组类型     *     * @inner     * @param {*} obj 要判断的对象     * @return {boolean}     */    function isArray( obj ) {        return obj instanceof Array;    }    /**     * 判断对象是否函数类型     *     * @inner     * @param {*} obj 要判断的对象     * @return {boolean}     */    function isFunction( obj ) {        return typeof obj == 'function';    }    /**     * 判断是否字符串     *     * @inner     * @param {*} obj 要判断的对象     * @return {boolean}     */    function isString( obj ) {        return typeof obj == 'string';    }    /**     * 循环遍历数组集合     *     * @inner     * @param {Array} source 数组源     * @param {function(Array,Number):boolean} iterator 遍历函数     */    function each( source, iterator ) {        if ( isArray( source ) ) {            for ( var i = 0, len = source.length; i < len; i++ ) {                if ( iterator( source[ i ], i ) === false ) {                    break;                }            }        }    }    /**     * 创建数组字符数逆序排序函数     *     * @inner     * @param {string} property 数组项对象名     * @return {Function}     */    function createDescSorter( property ) {        property = property || 'k';        return function ( a, b ) {            var aValue = a[ property ];            var bValue = b[ property ];            if ( bValue == '*' ) {                return -1;            }            if ( aValue == '*' ) {                return 1;            }            return bValue.length - aValue.length;        };    }    // 暴露全局对象    global.define = define;    global.require = require;})( this );
 |