美文网首页
webpack是怎么根据模块引用实现模块合并

webpack是怎么根据模块引用实现模块合并

作者: 风雅欢乐 | 来源:发表于2020-05-01 19:27 被阅读0次

    假设我们有两个模块, 分别为index.js和a.js, 代码如下:

    // 模块a
    console.log("module a");
    module.exports = "a";
    

    另有index模块引入了模块a

    console.log("index module");
    var a = require("./a");
    console.log(a);
    

    在node环境中, 每个文件代表一个模块, 那么它是如何确保每个模块的变量不互相污染呢? 在node环境中, 每个模块内部的代码, 都被放入了一个函数环境内, 模块代码中所使用的的module, require, exports等都是这个函数的参数, 正因如此, 我们才能够在模块代码中直接使用require函数和module对象.

    那么合并后的模块的代码就相当于

    (function (modules) {
        // 提供require函数等
    
        // 执行入口模块
        require("./src/index.js");
    })({
        "./src/a.js": function (module, exports, require) {
            console.log("module a");
            module.exports = "a";
        },
        "./src/index.js": function (module, exports, require) {
            console.log("index module");
            var a = require("../src/a.js");
            console.log(a);
        }
    });
    

    每一个模块的路径, 作为唯一标识, 可以确定一个模块. 这个模块放入一个函数中. require的模块也使用统一的路径格式. 这个立即执行函数里面, 就需要提供模块代码需要的require函数, module和exports对象. 并且立即执行函数里面, 一定会执行入口模块.

    由于commonjs模块化标准会对模块进行缓存, require函数的作用, 就是查看某个模块是否曾经被加载过, 如果是, 则直接返回该模块的导出结果, 如果不是, 则运行该模块, 并且返回该模块导出的结果, 并且将该模块缓存. 那么这个立即执行函数中, 就需要有一个对象, 保存所有的缓存模块.
    代码如下

    (function (modules) {
        // 提供require函数等
        var installedModules = {
            "./src/a.js": {
                i: "./src/a.js",        // 模块id
                l: false,                 // 是否完成导入
                exports: "a"          // 模块的导出内容
            }
        };
    
        function require(moduleId) {
            if (installedModules[moduleId]) {
                return installedModules[moduleId].exports;
            }
            var module = installedModules[moduleId] = {
                i: moduleId,        // 模块id
                l: false,                 // 是否完成导入
                exports: {}          // 模块的导出内容
            };
            modules[moduleId].call(module.exports, module, module.exports, require);
            module.l = true;     // 此时完成载入, 设置l为true
            return module.exports;
        }
    
        // 执行入口模块
        require("./src/index.js");
    })({
        "./src/a.js": function (module, exports, require) {
            console.log("module a");
            module.exports = "a";
        },
        "./src/index.js": function (module, exports, require) {
            console.log("index module");
            var a = require("../src/a.js");
            console.log(a);
        }
    });
    

    相关文章

      网友评论

          本文标题:webpack是怎么根据模块引用实现模块合并

          本文链接:https://www.haomeiwen.com/subject/xvnqghtx.html