CommonJs 加载 CommonJs

CommonJs 加载 CommonJs 不需要任何处理;

加载图解

打包文件分析

(() => {
  // 该入口文件引入的模块,会议键值对的形式放在 modules 里面
  // 不管你是用什么样的路径来加载的,最终模块 ID (key值)统一会变成相对根目录的相对路径
  //  - index.js ./src/index.js
  //  - a.js  ./src/a.js
  var modules = {
    "./src/a.js": ((module, module_exports, require) => {
      module.exports = {
        a: 1,
        b: 2,
        c: 3
      };
    })
  };

  // 缓存模块
  var cache = {};
  function require(moduleId) {
    // 如果存在缓存,直接从缓存中获取
    if (cache[moduleId]) {
      return cache[moduleId].exports;
    }

    // 没有缓存,则需要放入缓存中
    var module = cache[moduleId] = {
      exports: {} // 默认值为空,引入模块后会赋值到这里
    };
    // 加载模块,执行该模块代码
    modules[moduleId](module, module.exports, require);

    return module.exports;
  }

  // 入口文件加载后,执行以下代码
  (() => {
    let title = require("./src/a.js");
    console.log(title);
  })();
})();

CommonJs 加载 ESModules

CommonJs 加载 ESModulesESModules 需要转成 CommonJs 规范;

加载图解

打包文件分析

(() => {
    var modules = {
        // esModule 模块 => Commonjs 模块:
        //  - export default 会变成 exports.default
        //  - export name 会变成 exports.name
        './src/a.js': (module, exports, require) => {
            // 不管是 commonjs 还是 esModule 最后都编译成 common.js
            // 如果原来是 es module 的话,就把 exports 传给 r 方法处理一下,exports.__esModule = true,以后就可以通过这个属性来判断原来是不是一个 esModule
            require.r(exports);
            require.d(exports, {
                default: () => DEFAULT_EXPORT,
                a: () => a,
                b: () => b
            });
            const DEFAULT_EXPORT = 3;
            const a = 1;
            const b = 2;
        }
    }

    var cache = {};
    function require(moduleId) {
        // 先看缓存里有没有已经缓存的模块对象,如果有就直接返回
        if (cache[moduleId]) {
            return cache[moduleId].exports;
        }
        // module.exports 默认值是一个空对象
        var module = { exports: {} };
        cache[moduleId] = module;
        // 会在模块的代码执行时候给 module.exports 赋值
        modules[moduleId].call(module.exports, module, module.exports, require);
        return module.exports;
    }
    /***
     * 将 definition 的属性都放到 exports 里面(用代理的方式实现)
    */
    require.d = (exports, definition) => {
        for (let key in definition) {
            Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
        }
    }
    /***
     * 新增 2 个属性 Symbol.toStringTag 和 __esModule,用于标识原来是 esModule 模块
    */
    require.r = (exports) => {
        Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); // Object.prototype.toString.call(exports) === [object Module]
        Object.defineProperty(exports, '__esModule', { value: true }); // exports.__esModule=true
    }

    // ./src/index.js 中的代码
    (() => {
        let title = require('./src/a.js');
        console.log(title);
    })();
})();

ESModules 加载 ESModules

ESModules 加载 ESModulesESModules 全部需要转成 CommonJs 规范;

加载图解

打包文件分析

(() => {
    var modules = {
        // esModule 模块 => Commonjs 模块:
        //  - export default 会变成 exports.default
        //  - export name 会变成 exports.name
        "./src/index.js": ((module, exports, require) => {
            require.r(exports); // 先标识这是一个 esModule
            var obj = require("./src/a.js");
            console.log(obj);
        }),
        "./src/a.js": ((module, exports, require) => {
            // 不管是 commonjs 还是 esModule 最后都编译成 common.js
            // 如果原来是 es module 的话,就把 exports 传给 r 方法处理一下,exports.__esModule = true,以后就可以通过这个属性来判断原来是不是一个 esModule
            require.r(exports);
            require.d(exports, {
                default: () => DEFAULT_EXPORT,
                a: () => a,
                b: () => b,
            });
            const DEFAULT_EXPORT = 3;
            const a = 1;
            const b = 2;
        })
    }

    var cache = {};
    function require(moduleId) {
        // 如果存在缓存,直接从缓存中获取
        if (cache[moduleId]) {
            return cache[moduleId].exports;
        }
        // module.exports 默认值是一个空对象
        var module = { exports: {} };
        cache[moduleId] = module;
        // 会在模块的代码执行时候给 module.exports 赋值
        modules[moduleId].call(module.exports, module, module.exports, require);
        return module.exports;
    }

    /***
     * 将 definition 的属性都放到 exports 里面(用代理的方式实现)
    */
    require.d = (exports, definition) => {
        for (let key in definition) {
            Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
        }
    }
    /***
     * 新增 2 个属性 Symbol.toStringTag 和 __esModule,用于标识原来是 esModule 模块
    */
    require.r = (exports) => {
        Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); // Object.prototype.toString.call(exports) === [object Module]
        Object.defineProperty(exports, '__esModule', { value: true }); // exports.__esModule=true
    }

    // ./src/index.js 的代码
    (() => {
        require("./src/index.js");
    })();
})();

ESModules 加载 CommonJs

ESModules 加载 CommonJsESModules 需要转成 CommonJs 规范;

加载图解

打包文件分析

(() => {
    var modules = {
        // esModule 模块 => Commonjs 模块:
        //  - export default 会变成 exports.default
        //  - export name 会变成 exports.name
        "./src/index.js":
            ((module, exports, require) => {
                require.r(exports); // 先表示这是一个 esModule
                var title = require("./src/a.js");
                // 这个 n 有什么用? 在这个方根本不知道 a.js 是一个 esModule 还是 commonjs
                var title_default = require.n(title);
                console.log((title_default())); //默认值
            }),
        './src/a.js': (module, exports, require) => {
            // commonjs 不需要转换
            module.exports = {
                a: 1,
                b: 2,
                c: 3,
            }
        }
    }

    var cache = {};
    function require(moduleId) {
        // 如果存在缓存,直接从缓存中获取
        if (cache[moduleId]) {
            return cache[moduleId].exports;
        }
        // module.exports 默认值是一个空对象
        var module = { exports: {} };
        cache[moduleId] = module;
        // 会在模块的代码执行时候给 module.exports 赋值
        modules[moduleId].call(module.exports, module, module.exports, require);
        return module.exports;
    }

    /***
     * 属性兼容获取器(esModule、commonjs 都能获取)
    */
    require.n = (exports) => {
        var getter = exports.__esModule ? () => exports.default : () => exports;
        return getter;
    }
    /***
     * 将 definition 的属性都放到 exports 里面(用代理的方式实现)
    */
    require.d = (exports, definition) => {
        for (let key in definition) {
            Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
        }
    }
    /***
     * 新增 2 个属性 Symbol.toStringTag 和 __esModule,用于标识原来是 esModule 模块
    */
    require.r = (exports) => {
        Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); // Object.prototype.toString.call(exports) === [object Module]
        Object.defineProperty(exports, '__esModule', { value: true }); // exports.__esModule=true 
    }

    //./src/index.js 的代码
    (() => {
        require("./src/index.js");
    })();
})();
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. CommonJs 加载 CommonJs
    1. 1.1. 加载图解
    2. 1.2. 打包文件分析
  2. 2. CommonJs 加载 ESModules
    1. 2.1. 加载图解
    2. 2.2. 打包文件分析
  3. 3. ESModules 加载 ESModules
    1. 3.1. 加载图解
    2. 3.2. 打包文件分析
  4. 4. ESModules 加载 CommonJs
    1. 4.1. 加载图解
    2. 4.2. 打包文件分析