根据webpack打包规则,实现简单的打包手写实现

首先导入导出分为几类

  • CommonJS导入CommonJS
  • EsModule导入CommonJS
  • EsModule导入EsModule

根据实现规则,简单代码样例

// index.js

// import log,{age} from "./log.js"
// // let log = require('./log.js')
// console.log('index.js内容')
// console.log("log", log,age)


// log.js
// CommonJS导出
module.exports ="logger"
// export default "jack"
// export const age = 18;

手写模拟实现代码

(function (modules) {
    // 缓存被加载过的模块
    let installedModules = {};

    // 定义一个__webpak_require__方法来替换 import require的加载操作
    function __webpack_require__(moduleId) {
        // 缓存优先,判断当前缓存中是否存在要被加载的模块,如果存在就直接返回
        if (installedModules[moduleId]) {
            return installedModules[moduleId].exports
        }

        // 如果当前缓存中不存在,就需要自己定义,执行被导入的模块内容加载
        let module = installedModules[moduleId] = {
            i: moduleId,
            l: false,
            exports: {}
        }

        // 调用当前moduleId对应的函数,完成内容的加载,__webpack_require__c参数存在是为了解决递归调用的问题
        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__)

        // 当上述方法调用结束之后,修改 l 的值,标识当前模块内容已经加载完成了
        module.l = true

        // 加载工作完成之后,将拿回来的内容返回至调用位置
        return module.exports
    }

    // 定义m属性来保存modules
    __webpack_require__.m = modules

    // 定义c属性用于保存cache
    __webpack_require__.c = installedModules

    // 定义o方法用于判断对象身上是否存在制定属性
    __webpack_require__.o = function (object, property) {
        return Object.prototype.hasOwnProperty(object, property)
    }

    // 定义d方法用于在对象身上添加制定属性,并且给该属性提供一个getter
    __webpack_require__.d = function (exports, name, getter) {
        if (!__webpack_require__.o(exports, name)) {
            Object.defineProperty(exports, name, {
                enumerable: true,
                get: getter
            });
        }
    }

    // 定义r方法用于标识当前模块EsModule
    __webpack_require__.r = function (exports) {
        if (typeof Symbol !== undefined && Symbol.toStringTag) {
            Object.defineProperty(exports, Symbol.toStringTag, {
                value: "module"
            })
        }
        Object.defineProperty(exports, "__esModule", {
            value: true
        })
    }

    // 定义n方法用于设置具体的getter
    __webpack_require__.n = function (module) {
        let getter = module && module.__esModule ? function getDefault() {
            return module['default']
        } : function getModuleExports() {
            return module
        }
        __webpack_require__.d(getter, 'a', getter)
        return getter
    }

    // 定义p属性,用于保存资源访问路径
    __webpack_require__.p = ""

    // 调用__webpack_require__方法,执行模块导入和加载操作
    return __webpack_require__(__webpack_require__.s = "./src/index.js")

})(
    // CommonJS导入CommonJS
    //     {
    //     "./src/index.js": (function (module, exports, __webpack_require__) {
    //         let log = __webpack_require__( /*! ./log.js */ "./src/log.js")
    //         console.log('index.js内容')
    //         console.log("log", log)
    //     }),
    //     "./src/log.js": (function (module, exports) {
    //         // CommonJS导出
    //         module.exports = "logger"
    //     })
    // }

    // EsModule导入CommonJS
    {
        "./src/index.js": (function (module, __webpack_exports__, __webpack_require__) {
            "use strict";
            __webpack_require__.r(__webpack_exports__);
            var _log_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( /*! ./log.js */ "./src/log.js");
            var _log_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(_log_js__WEBPACK_IMPORTED_MODULE_0__);
            console.log('index.js内容')
            console.log("log", _log_js__WEBPACK_IMPORTED_MODULE_0___default.a)
        }),
        "./src/log.js": (function (module, exports) {
            module.exports = "logger"
        })
    }

    // EsModule导入EsModule
    // {
    //     "./src/index.js": (function (module, __webpack_exports__, __webpack_require__) {
    //         "use strict";
    //         __webpack_require__.r(__webpack_exports__);
    //         var _log_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( /*! ./log.js */ "./src/log.js");
    //         console.log('index.js内容')
    //         console.log("log", _log_js__WEBPACK_IMPORTED_MODULE_0__["default"], _log_js__WEBPACK_IMPORTED_MODULE_0__["age"])
    //     }),
    //     "./src/log.js": (function (module, __webpack_exports__, __webpack_require__) {
    //         "use strict";
    //         __webpack_require__.r(__webpack_exports__);
    //         __webpack_require__.d(__webpack_exports__, "age", function () {
    //             return age;
    //         });
    //         __webpack_exports__["default"] = ("jack");
    //         const age = 18;
    //     })
    // }
)

通过编译生成的index.html,引入手写built.js文件,控制台可以正常打印

你可能感兴趣的:(根据webpack打包规则,实现简单的打包手写实现)