同步加载

  1. 先使用require.register注册文件路径和对应方法之间的映射关系保存在require.modules中
  2. 再使用require方法,通过传入的路径去require.modules中取出对应的方法
  3. 使用require获取方法的同时,会触发依赖模块中的require方法,这样就实现了模块的加载

index.html

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
 
<body>
    <!-- <script src="./commonJS_async.js"></script> -->
    <script src="./commonJS.js"></script>
    <script src="./modules/hello.js"></script>
    <script src="./modules/name.js"></script>
    <script>
        var hello = require("hello.js");
        console.log(hello);
        console.log(require.modules);
        // require.ensure('./modules/ajax.js', function (obj) {
        //     console.log(obj);
        // })
    </script>
</body>
</html>

commonJS.js

function require(path) {
    let mod = require.modules[path];
    mod.exports = {};
    mod.call(window, require, mod, mod.exports);
    return mod.exports;
}
 
require.modules = {};
 
require.register = function (path, fn) {
    // 异步加载
    require.modules[path] = fn;
}

hello.js、name.js

//hello.js
require.register('hello.js', function (require, module, exports) {
    let name = require('name.js')
    exports.hello_name = 'hello ' + name;
    exports.hello_world = 'hello world';
})
//name.js
require.register('name.js', function (require, module, exports) {
    module.exports = 'shimingw'
})

异步加载

  1. 异步加载的逻辑匜不复杂,在同步加载的基础上增加require.ensure方法,预先在modules对象上挂在onload方法
  2. 修改require.register方法,增加异步模块注册逻辑,在异步模块注册完成后触发onload,以达到模块异步加载的需求

commonJS_async.js

function require(path) {
    let mod = require.modules[path].method;
    mod.exports = {};
    mod.call(window, require, mod, mod.exports);
    return mod.exports;
}
 
require.modules = {};
 
require.register = function (path, fn) {
    // 异步加载
    if (require.modules[path] && require.modules[path].status === 'loading') {
        // 异步加载成功
        require.modules[path].status = 'loaded'
        require.modules[path].method = fn;
        require.modules[path].onload(require(path));
    } else {
        require.modules[path] = {
            moduleName: path, // 模块Id
            status: 'loaded',
            onload: null,
            method: fn
        };
    }
}
 
require.ensure = function (path, cb) {
    require.modules[path] = {
        moduleName: path, // 模块Id
        status: 'loading',
        onload: cb,
        method: null
    };
    var head = document.querySelector('head')
    var script = document.createElement('script');
    script.async = true;
    script.src = path;
    setTimeout(() => {
        head.appendChild(script);
    },5000 );
}

 

posted on 2020-12-27 15:43  Jack·zhou  阅读(143)  评论(0编辑  收藏  举报