摘要:方法一中的插件就是在階段刪除目標文件夾。而想要優化該插件,思路就是在階段刪除上一次打包后留下的廢棄文件。
場景
很多人使用webpack打包文件,為了防止瀏覽器緩存,經常會這樣設置:
output: { path: path.resolve(__dirname, "./dist"), filename: "bundle-[hash:5].js" }
給文件hash編碼后加在文件名后面,只要文件修改,都會生成不同的文件名。但是,經過多次打包后,往往會遇到這樣的情況:
/dist目錄 |-- bundle-6ece9.js |-- bundle-b41c3.js |-- bundle-d303d.js |-- index.html |-- style-6ece9.css |-- style-b41c3.css |-- style-d303d.css
除了我們的index.html如海邊的礁石一般巍然不動,js、css文件都仿佛拉幫結派,一茬一茬的。該怎么刪除這些重復的文件呢?
解決方法一很多人都推薦使用“clean-webpack-plugin”插件,它能在Webpack編譯之前就刪除所有文件。
優點:輕量級插件,配置簡單。
缺點:在大型項目中,如果只改變了一個文件卻需要刪除其他所有未改變的文件,這些文件數量不定但對性能還是有一定影響,因此這個插件性能上還有提升空間。
寫過Webpack插件的前端同行,可能知道compiler對象以及相關的事件鉤子。
在此介紹兩種與本文相關的鉤子:
compile:開始編譯,在創建 compilation 對象之前;
done:所有的編譯過程已完成。
方法一中的clean-webpack-plugin插件就是在compile階段刪除目標文件夾。而想要優化該插件,思路就是在done階段刪除上一次打包后留下的廢棄文件。
這時有一個新的問題,在done階段,項目中所有文件都編譯完成,存放在dist文件夾中了,怎么區分哪些是這次打包產生的新文件,哪些是上一次打包產生的舊文件呢?
這里,再介紹一下compilation對象。
compilation 對象代表了一次單一的版本 webpack 構建和生成編譯資源的過程,compilation 對象可以訪問所有的模塊和它們的依賴(大部分是循環依賴)。
了解compilation對象的概念后,介紹一下它的一個屬性assets。compilation.assets的值是一個對象,其中每一屬性名都是本次打包產生的文件的文件名,打印出來如下:
assets: { "bundle-a82da.js": { existsAt: "...distundle-a82da.js" }, "style-cc549.css": ConcatSource { children: [Object], existsAt: "...diststyle-cc549.css", emitted: true }, "index.html": { source: [Function: source], size: [Function: size], existsAt: "...distindex.html", emitted: true } }
因此,通過assets屬性我們就解決了如何區分本次打包與之前打包產生的文件的問題。只需要遍歷一次dist目錄所有文件,若assets對象中不包含該文件的文件名,那就說明這是“前朝余孽”,直接斬立決。
核心代碼如下:
buildDir = this.buildDir; compiler.plugin("done", function (compat) { //獲取資源數組對象 const newlyCreatedAssets = compat.compilation.assets; const unlinked = []; fs.readdir(path.resolve(buildDir), (err, files) => { files.forEach(file => { //刪除當前打包資源組中不存在的文件 if (!newlyCreatedAssets[file]) { fs.unlink(path.resolve(buildDir + file)); unlinked.push(file); } }); if (unlinked.length > 0) { console.log("刪除文件: ", unlinked); } }); });
使用時只需要傳入目標文件夾的目錄url即可,如“./dist/”。
插件為了方便的使用,我做了一個插件上傳到npm倉庫。
1.初始化npm
npm init
2.安裝模塊
npm i webpack-remove-hashed-files --save-dev
3.修改webpack.config.js
const removeFiles = require("webpack-remove-hashed-files"); //你的打包目標文件夾 //your distnation folder const buildDir = "./dist/"; //……修改plugins //...modify plugins plugins:[ new removeFiles(buildDir) ]
源碼請看我的github倉庫
總結我的方法主要是判斷文件是否為本次打包產生來減少文件刪除的時間,但是相比較于clean-webpack-plugin插件,功能還缺少刪除白名單和文件名正則匹配等,這些都會在我有空的時間添加。
另外可能有的同行覺得clean-webpack-plugin不能滿足某些需求,不妨試試我的這款插件,也許有意外之喜。
參考看清楚真正的 Webpack 插件
如何編寫一個插件?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90256.html
摘要:打包分析與性能優化背景在去年年末參與的一個項目中,項目技術棧使用,生產環境全量構建將近三分鐘,項目業務模塊多達數百個,項目依賴數千個,并且該項目協同前后端開發人員較多,提高構建效率,成為了改善團隊開發效率的關鍵之一。 webpack打包分析與性能優化 背景 在去年年末參與的一個項目中,項目技術棧使用react+es6+ant-design+webpack+babel,生產環境全量構建將...
摘要:由于項目的不斷擴大,只會影響我們定位功能和問題的速度,因此對冗余文件進行清理,是很重要的。我們在項目中使用的,自動將各個圖標進行。 進入公司之后,接手的便是前人留下來的一個大項目。慶幸的是整個項目擁有完善的產品功能文檔,但是由于項目過于龐大,老舊。包含了打包過慢,冗余文件過多等諸多問題。想要快速的解決這些問題,想要完全把功能重構一遍的話,成本太高了。一個一個文件來過,時間成本也比較大。...
答案自己谷歌或百度找。 一、來源背景 面試題是來自微博@牛客網發布的真實大廠前端面經題目,我一直在收集題目長期一個一個的記錄下來的,可能會有重復,但基本前端的面試大綱和需要掌握的知識都在其中了,面試題僅做學習參考,學習者閱后也要用心鉆研其中的原理,重要知識需要系統學習、透徹學習,形成自己的知識鏈。 二、532道前端真實大廠面試題 express和koa的對比,兩者中間件的原理,koa捕獲異常多種情...
答案自己谷歌或百度找。 一、來源背景 面試題是來自微博@牛客網發布的真實大廠前端面經題目,我一直在收集題目長期一個一個的記錄下來的,可能會有重復,但基本前端的面試大綱和需要掌握的知識都在其中了,面試題僅做學習參考,學習者閱后也要用心鉆研其中的原理,重要知識需要系統學習、透徹學習,形成自己的知識鏈。 二、532道前端真實大廠面試題 express和koa的對比,兩者中間件的原理,koa捕獲異常多種情...
閱讀 1628·2021-10-12 10:11
閱讀 3748·2021-09-03 10:35
閱讀 1439·2019-08-30 15:55
閱讀 2122·2019-08-30 15:54
閱讀 993·2019-08-30 13:07
閱讀 1004·2019-08-30 11:09
閱讀 569·2019-08-29 13:21
閱讀 2645·2019-08-29 11:32