摘要:默認做法是告訴瀏覽器這個文件的緩存時間,然后當文件內容被修改,則需要重命名該文件告訴瀏覽器需要重新下載和緩存,例如也能做類似的工作。
上一篇介紹了 Webpack 優化項目的四種技巧,分別是通過 UglifyJS 插件實現對 JavaScript 文件的壓縮,css-loader 提供的壓縮功能,配置NODE_ENV可以進一步去掉無用代碼,tree-shaking幫助找到更多無用代碼
這一篇主要講 Webpack 的改進緩存(hash)、切割代碼
使用 hash開發過程經常需要一邊預覽代碼運行結果一邊修改代碼,這個時候文件版本控制就顯得尤為重要。默認做法是告訴瀏覽器這個文件的緩存時間,然后當文件內容被修改,則需要重命名該文件告訴瀏覽器需要重新下載和緩存,例如:
WebpackManifestPlugin 相比HtmlWebpackPlugin是一個更靈活的解決方案,尤其是面對復雜的服務端的部分。它能生成JSON文件,包含文件名以及與其對應(映射)的 hash 過的文件名
{ "bundle.js": "bundle.8e0d62a03.js" }
提示:Webpack的 hash 函數是不穩定的,這意味著在不同開發環境等條件下下,即便是同一個文件,webpack 依然會計算出不同的 hash 去標識這個相同的文件。正因為此,如果你有跨平臺開發的需求,可以使用webpack-chunk-hash去代替webpack的原生的hash函數算法。更多關于 webpack hash 的問題可以查看:here
切割代碼想象一下你要開發一個大型網站,有首頁和文章頁,文章頁里有文章內容和評論系統,但是你要將網站正常工作的代碼都打包到一個文件里,這顯然是不科學的。每次你修改其中一個模塊,整改打包文件都要重新編譯重新打包和生成,這意味著你僅僅只是修改一下評論模塊,但當用戶只訪問首頁,他們依然會下載這些暫時無用的代碼,從而影響首頁訪問的加載速度
這個時候就需要切割打包文件,把它切割為首頁和文章頁所需的兩個打包文件,當用用戶訪問首頁時,只加載首頁的打包文件,當訪問文章頁的時候,只加載文章頁的打包文件,配置如下:
module.exports = { // 設置多個入口點,webpack給每個入口文件生成對應的打包文件 // 從而實現不同頁面加載不同的打包文件 entry: { homepage: "./index.js", article: "./article.js" }, output: { // [name]對應的是入口點的 name,如 homepage、article filename: "[name].[chunkhash].js" }, plugins: [ // 生成打包資源列表 json 文件 new WebpackManifestPlugin(), // 取代 webpack 原生的 hash 函數 new WebpackChunkHash(), // 生成依賴包的塊文件,轉移所有的`node_modules`依賴到一個特別的該文件中 // 這允許你更新你的代碼時,無需更新依賴 new webpack.optimize.CommonsChunkPlugin({ name: "vendor", minChunks: m => m.context && m.context.includes("node_modules"), }), // 生成 `webpack’s runtime` 自身的代碼文件 // 這允許你更新你的代碼時,無需更新其他無關代碼 new webpack.optimize.CommonsChunkPlugin({ name: "runtime", chunks: ["vendor"], minChunks: Infinity, }), // 標識每個模塊 hash 值,當你添加新的模塊時,如果該模塊的依賴影響到別的模塊 // 就可以更新這些受影響的模塊從而區分舊的模塊 new webpack.HashedModuleIdsPlugin(), // 生成資源映射文件,包含文件名以及與其對應的hash過的文件名,用于其他插件或者服務 new ChunkManifestPlugin({ filename: "chunk-manifest.json", manifestVariable: "webpackManifest" }) ] };
上面這個配置將會生成6個文件:
// 兩個打包入口文文件,當你修改了業務代碼,它們也會跟著變化 homepage.a68cd93e1a43281ecaf0.js article.d07a1a5e55dbd86d572b.js // 通用依賴文件與 webpack’s runtime 的文件,前者當你依賴包變化也跟著變化,后者極少變化,除非使用的 webpack 版本這類情況變化了才會跟著變化 vendor.1ebfd76d9dbc95deaed0.js runtime.d41d8cd98f00b204e980.js // 兩個 manifest 文件,用于其他插件或服務,如 DllReferencePlugin manifest.json chunk-manifest.json按需切割代碼
除了按照不同頁面的切割為不同的入口文件外的切割代碼外,還可以按照構成頁面的組件的順序做到按需加載的去切割代碼
想象一下,有一個頁面布局方式如下所所示:
+-------------------------------+ | logo menu | +-------+----------------+------+ | | | | | left | | right| | bar | | bar | | | article | | | | content | | | | | | | | | | | +----------------+ | | | | | | | comments | | | | | | +-------+----------------+------+ | copyright | +-------------------------------+
當訪問這個頁面時,用戶希望首先能閱讀到文章的內容,諸如其他評論、側邊欄等其他頁面組成部分是可以被延后查看的。可惜的是,如果你將這些頁面組成部分都打包到一個文件里,用戶就需要等到整改打包文件加載后才能訪問到他想要訪問的內容
如何解決頁面中各部分的按需加載?webpack 允許你做這方面的優化去實現代碼的按需加載。首先你需要自己識別哪些代碼是要首先加載的,然后 webpack 會移動需要延遲加載的代碼到多帶帶的塊中,只有在當需要這些被延遲加載的代碼時,才會下載
假設有一個article-page.js業務代碼文件,當你打包加載其會全部加載,包括文章內容、評論和側邊欄,如下:
// article-page.js import { renderArticle } from "./components/article"; import { renderComments } from "./components/comments"; import { renderSidebar } from "./components/sidebar"; renderArticle(); renderComments(); renderSidebar();
做到按需加載則需要你將靜態的import修改為動態的import(),webpack 會自帶轉移這些代碼到多帶帶的塊中,只有當被需要時才會加載,如下:
// article-page.js import { renderArticle } from "./components/article"; renderArticle(); import("./comments.js") .then((module) => { module.renderComments(); }); import("./sidebar.js") .then((module) => { module.renderSidebar(); });
將靜態的import修改為動態的import()的操作會帶來提升首次訪問時加載性能,同事也會優化緩存,當你更改這些業務代碼時,只會修改對應的塊文件,從而不影響其他塊文件
當然,還需要重新設置 output ,如下:
// webpack.config.js module.exports = { output: { filename: "[name].[chunkhash].js", chunkFilename: "[name].[chunkhash].js", } };
output.chunkFilename可以標識按需加載的塊文件
提示:當你使用默認的 presets 的 babel 去編譯這些代碼,你會得到一個語法錯誤提示:Babel don’t understand import() out of the box. 要避免這個錯誤,你需要給babel安裝syntax-dynamic-import插件
externals在一個大型項目中,如果有兩段業務代碼有共同的依賴,通過 webpack 的externals,你在兩段代碼間可以共享這些依賴,如下:
// webpack.config.js module.exports = { externals: { "react": "React", "react-dom": "ReactDOM", } };
上面的做法是將這些框架或庫的對象掛靠在全局對象中,然后通過另外一個對象存儲對象名以及映射到對應模塊名的變量,webpack 就會替換所有所有模塊下的相關的引用,然后你需要手動引入這些被externals的框架或庫到網站入口文件中,如HtmlWebpackPlugin定義的template文件
總結這次介紹如何通過 webpack 克服瀏覽器緩存打包文件,不去更新新的打包文件的問題,以及講解了從不同的頁面的角度去切割代碼和從不同的頁面組成部分去切割代碼的過程,還有通過externals去分離去共有的框架和庫,從而實現對這些框架或庫的CDN資源加載
內容較多,大概就這樣~
文章首發于:https://www.linpx.com/p/webpa...
歡迎訪問我的博客:https://www.linpx.com
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/87393.html
摘要:這里要介紹的是工作流中的一種很普遍的代碼加工流程正常的業務邏輯開發流程需要經過預處理器如或,然后再經過后處理器如進行深加工。 還未看的,可以點擊查看上兩篇文章喲:Webpack 最佳實踐總結(一)、Webpack 最佳實踐總結(二) 好了,這篇是第三篇,也是完結篇,我感覺這一篇是最亂的一篇,湊合著看吧,不會讓你失望的 整合 CSS 加工流 有時候,前端項目中除了 JavaScript ...
摘要:這里要介紹的是工作流中的一種很普遍的代碼加工流程正常的業務邏輯開發流程需要經過預處理器如或,然后再經過后處理器如進行深加工。 還未看的,可以點擊查看上兩篇文章喲:Webpack 最佳實踐總結(一)、Webpack 最佳實踐總結(二) 好了,這篇是第三篇,也是完結篇,我感覺這一篇是最亂的一篇,湊合著看吧,不會讓你失望的 整合 CSS 加工流 有時候,前端項目中除了 JavaScript ...
摘要:基本開發環境創建的項目,作為代碼編寫工具插件推薦插件配置文章目錄項目目錄結構介紹框架選擇處理請求二次封裝項目目錄結構簡介業務相關靜態文件全局組件基礎樣式布局樣式及工具引入請求配置路由全局狀態管理工具文件入口文件主要配置文件頁面檢查配置測試 基本開發環境 vue-cli3 創建的項目,vscode 作為代碼編寫工具vscode插件推薦:vscode 插件配置 文章目錄 項目目錄結構介紹...
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...
摘要:它會代替所有的實例的值為,從而使知道那些判斷表達式總是錯誤的,從而刪除相關代碼,進一步壓縮打包文件模塊機制項目中使用的,通過也能通過打包有用的代碼,進一步減少大小。 好久沒寫文章,這次預計會帶來3篇的 Webpack 系列文章,將會在這幾天內更新完。 Webpack3 自今年6月20日正式發布而來,給我們帶來Scope Hoisting和Magic Comments兩大功能,可惜不在這...
閱讀 3546·2021-11-22 11:59
閱讀 950·2021-09-27 13:36
閱讀 3612·2021-09-24 09:47
閱讀 2260·2021-09-01 11:39
閱讀 979·2021-08-31 09:37
閱讀 2311·2021-08-05 10:01
閱讀 1673·2019-08-30 15:55
閱讀 701·2019-08-30 15:54