webpack cjs運(yùn)行時(shí)分析示例詳解
準(zhǔn)備工作(接上篇文章的示例也可以):
1. 在index.js文件中引入任一js文件
import sum from './sum'; const result = sum(1,2); console.log(result);
2. sum文件
const sum = (a, b) => {
return a+b;
}
export default sum3. build.js文件
const path = require('path');
const webpack = require('webpack');
function wrapBuild() {
return webpack({
entry: './index.js',
mode: 'none',
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
infrastructureLogging: {
debug: true,
level: 'log',
}
})
}
wrapBuild().run((err, stat) => {
const startTime = stat.startTime;
const endTime = stat.endTime;
console.log('構(gòu)建時(shí)間: ', endTime - startTime);
})4. 命令行執(zhí)行node ./build.js 生成打包產(chǎn)物main.js。
(截圖未完整, 共87行)

5. 什么是運(yùn)行時(shí)代碼?
通過webpack打包得到的文件(如/build/main.js的骨架代碼), 其中包含了一些webpack如何將多個(gè)模塊集合在一起的代碼, 可粗暴理解為webpack runtime 打包過后的代碼。可通過node build/main.js可直接調(diào)試。
6. 示例打包js資源后的運(yùn)行時(shí)代碼分析:(含注解)
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ([
/* 0 */, // ---模塊0, 入口模塊 可以理解為index.js模塊
/* 1 */ // ---模塊1,打包過后的sum.js
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
const sum = (a, b) => {
return a+b;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (sum);
/***/ })
/******/ ]);
/************************************************************************/
/******/ // 模塊緩存
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // 模塊加載器, 模擬實(shí)現(xiàn)common.js的require
/******/ function __webpack_require__(moduleId) {
/******/ // 根據(jù)moduleId從緩存中讀取module
/******/ var cachedModule = __webpack_module_cache__[moduleId];
// 若緩存中存在該模塊,則返回當(dāng)前的module.exports
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // 緩存中不存在該模塊,則去__webpack_modules__里取。
// 創(chuàng)建一個(gè)新的模塊, 寫入cache對(duì)象, key為moduleId, value 為 exports對(duì)象
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // 調(diào)用包裹函數(shù),計(jì)算模塊信息,解析出相關(guān)模塊內(nèi)容(如:exports)
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // 返回當(dāng)前解析過后的module.exports
/******/ return module.exports;
/******/ }
var __webpack_exports__ = {};
// 加載入口函數(shù)
(() => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _sum__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
const result = (0,_sum__WEBPACK_IMPORTED_MODULE_0__["default"])(1,2);
console.log(result);
})();
/******/ })()
;
該運(yùn)行時(shí)代碼一共做了三件事:
- __webpack_modules__ : 維護(hù)一個(gè)所有模塊的數(shù)組,通過深度優(yōu)先遍歷將其全部轉(zhuǎn)換為AST,以供給后面的包裹函數(shù)解析
- __webpack_require__: 手動(dòng)實(shí)現(xiàn)一個(gè)模塊加載器;優(yōu)先從緩存列表__webpack_module_cache__中讀取模塊,并返回其exports內(nèi)容。如果緩存中沒有,則調(diào)用包裹函數(shù)解析出模塊exports等重要內(nèi)容,存入緩存列表中并返回exports。
- 調(diào)用__webpack_require_(0): 運(yùn)行入口模塊.
7. 疑問?
- 如果不對(duì)模塊進(jìn)行緩存,會(huì)有什么問題?
- 模塊內(nèi)容重復(fù)計(jì)算,消耗性能。
- 每個(gè)模塊只在第一次引用的時(shí)候產(chǎn)生一個(gè)對(duì)象,后面都是引用該對(duì)象,減少代碼復(fù)雜度。
- module.exports和exports有什么區(qū)別?
- 默認(rèn)情況下,Node準(zhǔn)備的exports變量和module.exports變量實(shí)際上是同一個(gè)變量,并且初始化為空對(duì)象,我們可以把要輸出的東西直接加入在這個(gè)空對(duì)象里面;但是,如果我們要輸出的是一個(gè)函數(shù)或數(shù)組,那么,只能給module.exports賦值,給exports賦值是無效的,因?yàn)橘x值后,module.exports仍然是空對(duì)象。
- 結(jié)論:
- 如果要輸出一個(gè)鍵值對(duì)象{},可以利用exports這個(gè)已存在的空對(duì)象{},并繼續(xù)在上面添加新的鍵值;
- 如果要輸出一個(gè)函數(shù)或數(shù)組,必須直接對(duì)module.exports對(duì)象賦值。
- 建議直接對(duì)module.exports賦值,可以應(yīng)對(duì)任何情況;
參考文獻(xiàn)
詳細(xì)的可移步大佬的文章
到此這篇關(guān)于webpack cjs運(yùn)行時(shí)分析的文章就介紹到這了,更多相關(guān)webpack cjs運(yùn)行時(shí)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS 刪除字符串最后一個(gè)字符的實(shí)現(xiàn)代碼
本篇文章主要是對(duì)JS刪除字符串最后一個(gè)字符的實(shí)現(xiàn)代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2014-02-02
Javascript中查找不以XX字符結(jié)尾的單詞示例代碼
我在寫這篇文章之前花了2個(gè)多小時(shí)在弄正則表達(dá)式,下為大家介紹下具體的實(shí)現(xiàn)思路,感興趣的朋友可以參考下2013-10-10
js實(shí)現(xiàn)當(dāng)前輸入框高亮顯示的方法
這篇文章主要介紹了js實(shí)現(xiàn)當(dāng)前輸入框高亮顯示的方法,涉及javascript針對(duì)輸入框樣式動(dòng)態(tài)設(shè)置的技巧,非常美觀大方,簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-08-08
JavaScript實(shí)現(xiàn)刪除,移動(dòng)和復(fù)制文件的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)刪除,移動(dòng)和復(fù)制文件的方法,涉及javascript使用ActiveXObject控件操作文件的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08
js 返回時(shí)間戳所對(duì)應(yīng)的具體時(shí)間
返回unix時(shí)間戳所對(duì)應(yīng)的具體時(shí)間的代碼2010-07-07
JavaScript基于ChatGPT?API實(shí)現(xiàn)劃詞翻譯瀏覽器腳本
最近?GitHub?上有個(gè)基于?ChatGPT?API?的瀏覽器腳本,openai-translator,?短時(shí)間內(nèi)?star?沖到了?9.7k,拋開?tauri?是使用?rust?部分,那瀏覽器部分實(shí)現(xiàn)還是比較簡(jiǎn)單的,今天我們就來手動(dòng)實(shí)現(xiàn)一下2023-03-03

