日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【读书笔记】《深入浅出Webpack》

發布時間:2023/12/13 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【读书笔记】《深入浅出Webpack》 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Webpack版本

分析版本為3.6.0
4.0為最近升級的版本,與之前版本變化較大,編譯輸出的文件與3.0版本會不一致,目前項目中使用的版本3.0版本,所以基于3.0版本進行分析學習。

Webpack構建流程

  • 初始化:啟動構建,讀取與合并配置參數,加載Plugin,實例化Complier
  • 編譯:從Entry發出,針對每個Module串行調用對應的Loader去轉換文件內容,再找到該Module依賴的Module,遞歸進行編譯處理。
  • 輸出:對編譯后對Module組合成Chunk,把Chunk轉換成文件,輸出到文件系統。

輸出文件分析

原輸出文件結構:

簡化后的文件結構:

(function(modules) {// 模擬 require 語句function __webpack_require__() {}// 執行存放所有模塊數組中的第0個模塊__webpack_require__(0); })([/*存放所有模塊的數組*/])

分割代碼時輸出

當使用按需加載加載文件時,Webpack的輸出文件會發生變化。

// 異步加載 show.js import('./show').then((show) => {// 執行 show 函數show('Webpack'); });

重新構建后會輸出兩個文件,分別是執行入口文件bundle.js和異步加載文件0.bundle.js
異步加載文件默認輸入的文件名為 [id].js,可以在Webpack配置文件的output項中配置輸出文件名
其中0.bundle.js內容如下:

// 加載在本文件(0.bundle.js)中包含的模塊 webpackJsonp(// 在其它文件中存放著的模塊的 ID[0],// 本文件所包含的模塊[// show.js 所對應的模塊(function (module, exports) {function show(content) {window.document.getElementById('app').innerText = 'Hello,' + content;}module.exports = show;})] );

bundle.js內容如下:

(function (modules) {/**** webpackJsonp 用于從異步加載的文件中安裝模塊。* 把 webpackJsonp 掛載到全局是為了方便在其它文件中調用。** @param chunkIds 異步加載的文件中存放的需要安裝的模塊對應的 Chunk ID* @param moreModules 異步加載的文件中存放的需要安裝的模塊列表* @param executeModules 在異步加載的文件中存放的需要安裝的模塊都安裝成功后,需要執行的模塊對應的 index*/window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {// 把 moreModules 添加到 modules 對象中// 把所有 chunkIds 對應的模塊都標記成已經加載成功 var moduleId, chunkId, i = 0, resolves = [], result;for (; i < chunkIds.length; i++) {chunkId = chunkIds[i];if (installedChunks[chunkId]) {resolves.push(installedChunks[chunkId][0]);}installedChunks[chunkId] = 0;}for (moduleId in moreModules) {if (Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {modules[moduleId] = moreModules[moduleId];}}while (resolves.length) {resolves.shift()();}};// 緩存已經安裝的模塊var installedModules = {};// 存儲每個 Chunk 的加載狀態;// 鍵為 Chunk 的 ID,值為0代表已經加載成功var installedChunks = {1: 0};// 模擬 require 語句,和上面介紹的一致function __webpack_require__(moduleId) {// ... 省略和上面一樣的內容}/*** 用于加載被分割出去的,需要異步加載的 Chunk 對應的文件* @param chunkId 需要異步加載的 Chunk 對應的 ID* @returns {Promise}*/__webpack_require__.e = function requireEnsure(chunkId) {// 從上面定義的 installedChunks 中獲取 chunkId 對應的 Chunk 的加載狀態var installedChunkData = installedChunks[chunkId];// 如果加載狀態為0表示該 Chunk 已經加載成功了,直接返回 resolve Promiseif (installedChunkData === 0) {return new Promise(function (resolve) {resolve();});}// installedChunkData 不為空且不為0表示該 Chunk 正在網絡加載中if (installedChunkData) {// 返回存放在 installedChunkData 數組中的 Promise 對象return installedChunkData[2];}// installedChunkData 為空,表示該 Chunk 還沒有加載過,去加載該 Chunk 對應的文件var promise = new Promise(function (resolve, reject) {installedChunkData = installedChunks[chunkId] = [resolve, reject];});installedChunkData[2] = promise;// 通過 DOM 操作,往 HTML head 中插入一個 script 標簽去異步加載 Chunk 對應的 JavaScript 文件var head = document.getElementsByTagName('head')[0];var script = document.createElement('script');script.type = 'text/javascript';script.charset = 'utf-8';script.async = true;script.timeout = 120000;// 文件的路徑為配置的 publicPath、chunkId 拼接而成script.src = __webpack_require__.p + "" + chunkId + ".bundle.js";// 設置異步加載的最長超時時間var timeout = setTimeout(onScriptComplete, 120000);script.onerror = script.onload = onScriptComplete;// 在 script 加載和執行完成時回調function onScriptComplete() {// 防止內存泄露script.onerror = script.onload = null;clearTimeout(timeout);// 去檢查 chunkId 對應的 Chunk 是否安裝成功,安裝成功時才會存在于 installedChunks 中var chunk = installedChunks[chunkId];if (chunk !== 0) {if (chunk) {chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));}installedChunks[chunkId] = undefined;}};head.appendChild(script);return promise;};// 加載并執行入口模塊,和上面介紹的一致return __webpack_require__(__webpack_require__.s = 0); }) (// 存放所有沒有經過異步加載的,隨著執行入口文件加載的模塊[// main.js 對應的模塊(function (module, exports, __webpack_require__) {// 通過 __webpack_require__.e 去異步加載 show.js 對應的 Chunk__webpack_require__.e(0).then(__webpack_require__.bind(null, 1)).then((show) => {// 執行 show 函數show('Webpack');});})] );

這里的 bundle.js 和上面所講的 bundle.js 非常相似,區別在于:

  • 多了一個 webpack_require.e 用于加載被分割出去的,需要異步加載的 Chunk 對應的文件;
  • 多了一個 webpackJsonp 函數用于從異步加載的文件中安裝模塊。

參考

深入淺出WebPack

轉載于:https://www.cnblogs.com/GeniusLyzh/p/8823749.html

總結

以上是生活随笔為你收集整理的【读书笔记】《深入浅出Webpack》的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。