webpack cjs運行時分析示例詳解
準備工作(接上篇文章的示例也可以):
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 sum
3. 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('構建時間: ', endTime - startTime); })
4. 命令行執(zhí)行node ./build.js 生成打包產(chǎn)物main.js。
(截圖未完整, 共87行)
5. 什么是運行時代碼?
通過webpack打包得到的文件(如/build/main.js的骨架代碼), 其中包含了一些webpack如何將多個模塊集合在一起的代碼, 可粗暴理解為webpack runtime 打包過后的代碼??赏ㄟ^node build/main.js可直接調(diào)試。
6. 示例打包js資源后的運行時代碼分析:(含注解)
/******/ (() => { // 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__ = {}; /******/ /******/ // 模塊加載器, 模擬實現(xiàn)common.js的require /******/ function __webpack_require__(moduleId) { /******/ // 根據(jù)moduleId從緩存中讀取module /******/ var cachedModule = __webpack_module_cache__[moduleId]; // 若緩存中存在該模塊,則返回當前的module.exports /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // 緩存中不存在該模塊,則去__webpack_modules__里取。 // 創(chuàng)建一個新的模塊, 寫入cache對象, key為moduleId, value 為 exports對象 /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // 調(diào)用包裹函數(shù),計算模塊信息,解析出相關模塊內(nèi)容(如:exports) /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // 返回當前解析過后的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); })(); /******/ })() ;
該運行時代碼一共做了三件事:
- __webpack_modules__ : 維護一個所有模塊的數(shù)組,通過深度優(yōu)先遍歷將其全部轉(zhuǎn)換為AST,以供給后面的包裹函數(shù)解析
- __webpack_require__: 手動實現(xiàn)一個模塊加載器;優(yōu)先從緩存列表__webpack_module_cache__中讀取模塊,并返回其exports內(nèi)容。如果緩存中沒有,則調(diào)用包裹函數(shù)解析出模塊exports等重要內(nèi)容,存入緩存列表中并返回exports。
- 調(diào)用__webpack_require_(0): 運行入口模塊.
7. 疑問?
- 如果不對模塊進行緩存,會有什么問題?
- 模塊內(nèi)容重復計算,消耗性能。
- 每個模塊只在第一次引用的時候產(chǎn)生一個對象,后面都是引用該對象,減少代碼復雜度。
- module.exports和exports有什么區(qū)別?
- 默認情況下,Node準備的exports變量和module.exports變量實際上是同一個變量,并且初始化為空對象,我們可以把要輸出的東西直接加入在這個空對象里面;但是,如果我們要輸出的是一個函數(shù)或數(shù)組,那么,只能給module.exports賦值,給exports賦值是無效的,因為賦值后,module.exports仍然是空對象。
- 結論:
- 如果要輸出一個鍵值對象{},可以利用exports這個已存在的空對象{},并繼續(xù)在上面添加新的鍵值;
- 如果要輸出一個函數(shù)或數(shù)組,必須直接對module.exports對象賦值。
- 建議直接對module.exports賦值,可以應對任何情況;
參考文獻
詳細的可移步大佬的文章
到此這篇關于webpack cjs運行時分析的文章就介紹到這了,更多相關webpack cjs運行時內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
fireworks菜單生成器mm_menu.js在 IE 7.0 顯示問題的解決方法
由于公司官網(wǎng)采用的是dreamwaver / fireworks 內(nèi)建的彈出式菜單的JS,在IE7下發(fā)現(xiàn)菜單項文字顯示都變成一排,無法正確瀏覽.2009-10-10最簡單的JavaScript驗證整數(shù)、小數(shù)、實數(shù)、有效位小數(shù)正則表達式
這篇文章主要介紹了最簡單的JavaScript驗證整數(shù)、小數(shù)、實數(shù)、有效位小數(shù)正則表達式,其中包含保留1位小數(shù)、保留2位小數(shù)、保留3位小數(shù)等正則,需要的朋友可以參考下2015-04-04javascript 觸發(fā)HTML元素綁定的函數(shù)
只能觸發(fā)函數(shù)的執(zhí)行,并不能完全模擬出實際的點擊。2010-09-09js禁止document element對象選中文本實現(xiàn)代碼
禁止document element對象選中文本在某在情況下還是很有必要的接下來本文將使用js實現(xiàn),感興趣的各位可以參考下哈2013-03-03