SOURCE

console 命令行工具 X clear

                    
>
console
/**
 * Created by weiruifeng on 2017/9/3.
 */
(function(F) {
    // 模块缓存器。存储已创建模块
    let moduleCache = {};

    function getUrl(moduleName) {
        // 拼接完整的文件路径字符串,如'lib/ajax' => 'lib/ajax.js'
        return String(moduleName).replace(/\.js$/g, '') + '.js';
    }

    function loadScript(src, id) {
        let _script = document.createElement('script');
        // 文件类型
        _script.type = 'text/JavaScript';
        // 确认编码
        _script.charset = 'UTF-8';
        // 异步加载
        _script.async = true;
        // 文件路径
        _script.src = src;
        // 文件id
        _script.id = id;
        document.getElementsByTagName('head')[0].appendChild(_script);
    }

    function deleteScript(id) {
        const deleteJs = document.getElementById(id);
        console.log(deleteJs);
        if(deleteJs) {
            document.getElementsByTagName('head')[0].removeChild(deleteJs);
        }
    }

    /**
     * 异步加载依赖模块所在文件
     * @param moduleName        模块路径(id)
     * @param callback          模块加载完成回调函数
     */
    function loadModule(moduleName, callback) {
        let _module;
        // 如果依赖模块被要求加载过
        if(moduleCache[moduleName]) {
            _module = moduleCache[moduleName];
            // 如果模块加载完成
            if(_module.status === 'loaded') {
                // 执行模块加载完成后回调函数
                setTimeout(callback(_module.exports), 0);
            } else {
                // 缓存该模块所处文件加载完成回调函数
                _module.onload.push(callback);
            }
            // 模块第一次被依赖引用
        } else {
            // 缓存该模块初始化信息
            moduleCache[moduleName] = {
                // 模块ID
                moduleName: moduleName,
                // 模块对应文件加载状态(默认加载中)
                status: 'loading',
                // 模块接口
                exports: null,
                // 模块对应文件加载完成回调函数缓冲器
                onload: [callback]
            };
            // 加载模块对应文件
            loadScript(getUrl(moduleName), moduleName);
        }
    }

    /**
     * 设置模块并执行模块构造函数
     * @param moduleName        模块ID名称
     * @param params            依赖模块
     * @param callback          模块构造函数
     */
    function setModule(moduleName, params, callback) {
        let fn;
        // 如果模块被调用过
        if(moduleCache[moduleName]) {
            let _module = moduleCache[moduleName];
            // 设置模块已经加载完成
            _module.status = 'loaded';
            // 矫正模块接口
            _module.exports = callback ? callback.apply(_module, params) : null;
            // 执行模块文件加载完成回调函数
            while(fn = _module.onload.shift()) {
                fn(_module.exports);
            }
        } else {
            // 模块不存在(匿名模块),则直接执行构造函数
            callback && callback.apply(null, params);
        }
        // 删除加载的script标签
        deleteScript(moduleName);
    }

    /**
     * 创建或调用模块方法
     * @param url           模块url
     * @param modDeps       依赖模块
     * @param modCallback   模块主函数
     */
    F.module = function(url, modDeps, modCallback) {
        // 将参数转化为数组
        let args = [].slice.call(arguments);
        // 获取模块构造函数(参数数组中最后一个参数成员)
        let callback = args.pop();
        // 获取依赖模块(紧邻回调函数参数,且数据类型为数组)
        let deps = (args.length && args[args.length - 1] instanceof Array) ? args.pop() : [];
        // 该模块url(模块ID)
        url = args.length ? args.pop() : null;
        //  依赖模块序列
        let params = [];
        // 未加载的依赖模块数量统计
        let depsCount = 0;
        // 依赖模块序列中索引值
        let i = 0;
        // 依赖模块序列长度
        let len;

        if(len = deps.length) {
            while(i < len) {
                (function(i) {
                    // 增加未加载依赖模块数量统计
                    depsCount++;
                    // 异步加载依赖模块
                    loadModule(deps[i], function(mod) {
                        // 依赖模块序列中添加依赖模块数量统一减一
                        depsCount--;
                        params[i] = mod;
                        // 如果依赖模块全部加载
                        if(depsCount === 0) {
                            // 在模块缓存器中矫正该模块,并执行构造函数
                            setModule(url, params, callback);
                        }
                    });
                })(i);
                // 遍历下一个模块
                i++;
            }
            // 无依赖模块,直接执行回调函数
        } else {
            // 在模块缓存器中矫正该模块,并执行构造函数
            setModule(url, [], callback);
        }
    }
})((function() {
    // 创建模块管理器对象F,并保存在全局作用域中
    return window.F = {};
})());
<div id="demo">demo</div>
<script>
    const setInter = setInterval(() => {
        if(window.F) {
            F.module(['./lib/event', './lib/dom'], function (event, dom) {
                event.on('demo', 'click', function() {
                    dom.html('demo', 'success');
                });
            });
            clearInterval(setInter);
        }
    }, 10);
</script>