進入公司以後,接手的即是前人留下來的一個大項目。慶幸的是整個項目擁有完善的產品功能文檔,可是因爲項目過於龐大,老舊。包含了打包過慢,冗餘文件過多等諸多問題。想要快速的解決這些問題,想要徹底把功能重構一遍的話,成本過高了。一個一個文件來過,時間成本也比較大。所以在此篇文章中,咱們介紹一下我是如何配合webpack一步步進行分析,將項目進行優化的。
同時我針對思路封裝了一個 webpack-unused-files,用於查找項目中的冗餘文件,歡迎試用並star
原文連接
首先,咱們先大體看下咱們都有什麼問題,而後一步步進行解決前端
因爲項目的頻繁改動,有不少文件已經不被使用而且沒有被刪除。因爲項目的不斷擴大,只會影響咱們定位功能和問題的速度,所以對冗餘文件進行清理,是很重要的。可是咱們單憑肉眼很難識別哪一個文件是否被依賴的,所以還要經過webpack來解決。node
咱們來看一下webpack的輸出文件格式:webpack
{ ... chunks: [{ name: 'chunk-name', modules: [ // 每一個chunk中全部的依賴文件 ] }] ... }
因此說,根據這個stats.json,咱們能夠拿到在整個項目中拿到的全部項目文件:git
/** * 查詢依賴的模塊 */ function findSrcModules () { return new Promise((resolve, reject) => { fs.readFile(statPath, (err, data) => { if (err) return const json = JSON.parse(data) const assetsList = json.chunks let ret = [] // 拿到全部chunk的全部依賴文件 assetsList.forEach(chunk => { const modules = chunk.modules.map(item => item.name) ret = ret.concat(modules) }) // 去除node_modules中的文件 ret = ret.filter(item => item.indexOf('node_modules') < 0) resolve(ret) }) }) }
經過這一步,咱們能夠拿到項目中,全部打包依賴的文件。github
經過glob,咱們能夠獲取全部的文件:web
function getAllFilesInSrc () { const pattern = './src/**' return new Promise((resolve, reject) => { glob(pattern, { nodir: true }, (err, files) => { const ret = files.map(item => { return item.replace('./src', '.') }) resolve(ret) }) }) }
將兩個數組進行對比,沒有出如今依賴中的文件,就是冗餘文件。咱們能夠一鍵刪除shell
findSrcModules().then(ret => { getAllFilesInSrc().then(allFiles => { const unUsed = allFiles.filter(item => { return ret.indexOf(item) < 0 }) const join = p => path.join('./src', p) unUsed.forEach(file => { shelljs.rm(join(file)) }) }) })
根據上述冗餘文件的思路,咱們一樣能夠對第三方依賴進行處理,大體思路以下json
能夠說,拿到了全部依賴及依賴關係,咱們能夠很靈活的對其進行處理,拿到咱們想要的結果。segmentfault
該功能後續也會更新到webpack-unused-files中去。數組
讓人震驚的是,整個項目因爲種種緣由,打包後的大小有近20M的大小!雖然並非TO C項目,而且針對頁面進行了代碼拆分和懶加載,可是做爲一個「合格的前端」,這種現象是必定要修改的(沒錯!)。該如何下手呢?一個個的翻代碼,看看咱們都引用了什麼大依賴,看哪些項目過大未免太複雜了。咱們看看webpack給我嗎提供了什麼方案:
咱們知道,在webpack打包結束後,會自動在控制檯顯示打包結果。同時,他也提供了輸出依賴及大小的功能,咱們執行如下參數, 即可將全部的依賴進行展現,而且看到他們的大小了。
webpack --display-modules --sort-modules-by size
結果相似這樣:
咱們能夠很快的定位到排名前幾的js文件或者第三方依賴,決定該如何對其進行處置。
webpack提供了一個功能,將打包的全部依賴文件以及關係,以json格式進行輸出:
webpack --profile --json > stats.json
這是咱們整篇文章的一個基礎,不少人基於此封裝了很多可視化分析的工具,能夠直觀的看到各個
文件、chunk之間的依賴關係以及大小等,快速定位到大文件、大模塊
經過以上兩種方法,咱們能夠很好的對內容文件和依賴進行定位和分析,針對打包大小的優化方案網上已經有不少了,在此再也不進行贅述,提供幾個思路及參考:
針對打包時間的優化的文章其實也不少了,咱們在此僅提供一些思路。咱們主要提一點,經過構建會發現,項目中引用了大量的svg圖標以及國旗圖標,每次在靜態資源處理中,打包時間就會變的特別慢。
咱們在項目中使用的svg-sprite-loader,自動將各個svg圖標進行svg-spirte。可是咱們知道,這些圖標一旦引用,咱們不多進行修改。尤爲是像國旗圖標這種,可是每次構建咱們都須要進行重複打包。所以,咱們能夠提早把這些圖標進行svg-sprite。推薦一個網站,將各類svg圖標提早進行sprite並自動進行引用:
緩存與增量構建
經過對webpack輸出依賴關係的json的分析,咱們能夠直觀的拿到如下數據:
經過這些數據,咱們能夠很方便的對現有項目進行優化。
生命不息,倒騰不止。讓咱們對全部的噁心代碼說再見!