徹底解決Webpack打包慢的問題

2022-06-23 05:21:17 字數 4410 閱讀 7197

**:

我們先來看一下完全沒有任何優化的時候,webpack 的打包速度(使用了jsx和babel的loader)。下面是我們的測試檔案:

var react = require('react');

var reactaddonscsstransitiongroup = require('react-addons-css-transition-group');

var reactdom = require('react-dom');

var reactrouter = require('react-router');

var superagent = require("superagent");

var eventproxy = require("eventproxy");

執行

webpack test.js
在我的2015款rmbp13,i5處理器,全ssd下,效能是這樣的:

沒錯你沒有看錯,這幾個第三方輪子加起來有整整668個模組,全部打包需要20多秒。

這意味著什麼呢?你每次對業務**的修改,gulp 或者 webpack 監測到後都會重新打包,你要足足等20秒才能看到自己的修改結果。

但是需要重新打包的只有你的業務**,這些第三方庫是完全不用重新打包的,它們的存在只會拖累打包效能。所以我們要找一些方法來優化這個過程。

webpack 可以配置 externals 來將依賴的庫指向全域性變數,從而不再打包這個庫,比如對於這樣乙個檔案:

import react from 'react';

console.log(react);

如果你在 webpack.config.js 中配置了externals:

module.exports = 

//其它配置忽略......

};

等於讓 webpack 知道,對於react這個模組就不要打包啦,直接指向window.react就好。不過別忘了載入 react.min.js,讓全域性中有react這個變數。

我們來看看效能,因為不用打包 react 了所以速度自然超級快,包也很小:

import react from 'react';

import reactaddonscsstransitiongroup from 'react-addons-css-transition-group';

console.log(react);

對,你沒有看錯,我也沒有截錯圖,新加了乙個很小很小的動畫庫之後,效能又**了。從模組數來看,一定是 webpack 又把 react 重新打包了一遍。

我們來看一下為什麼乙個很小很小的動畫庫會導致 webpack 又傻傻地把 react 重新打包了一遍。找到 react-addons-css-transition-group 這個模組,然後看看它是怎麼寫的:

// react-addons-css-transition-group模組

// 入口檔案 index.js

module.exports = require('react/lib/reactcsstransitiongroup');

這個動畫模組就只有一行**,唯一的作用就是指向 react 下面的乙個子模組,我們再來看看這個子模組是怎麼寫的:

// react模組

// react/lib/reactcsstransitiongroup.js

var react = require('./react');

var reacttransitiongroup = require('./reacttransitiongroup');

var reactcsstransitiongroupchild = require('./reactcsstransitiongroupchild');

//....剩餘**忽略

這個子模組又反回去依賴了 react 整個庫的入口,這就是拖累 webpack 的罪魁禍首。

總而言之,問題是這樣產生的:

webpack 發現我們依賴了 react-addons-css-transition-group

webpack 去打包 react-addons-css-transition-group 的時候發現它依賴了 react 模組下的乙個叫 reacttransitiongroup.js 的檔案,於是 webpack 去打包這個檔案。

reacttransitiongroup.js 依賴了整個 react 的入口檔案 react.js,雖然我們設定了 externals ,但是 webpack 不知道這個入口檔案等效於 react 模組本身,於是我們可愛又敬業的 webpack 就把整個 react 又重新打包了一遍。

讀到這裡你可能會有疑問,為什麼不能把這個動畫庫也設定到 externals 裡,這樣不是就不用打包了嗎?

問題就在於,這個動畫庫並沒有提供生產環境的檔案,或者說這個庫根本沒有提供 react-addons-css-transition-group.min.js 這個檔案。

這個問題不只存在於 react-addons-css-transition-group 中,對於 react 的大多數現有庫來說都有這個依賴關係複雜的問題。

所以對於這個問題的解決方法就是,手工打包這些 module,然後設定 externals ,讓 webpack 不再打包它們。

我們需要這樣乙個lib-bundle.js檔案:

window.__lib["react"] = require("react");

window.__lib["react-addons-css-transition-group"] = require("react-addons-css-transition-group");

// ...其它依賴包

我們在這裡把一些第三方庫註冊到了window.__lib下,這些庫可以作為底層的基礎庫,免於重複打包。

然後執行webpack lib-bundle.js lib.js,得到打包好的lib.js。然後去設定我們的 externals :

var webpack = require('webpack');

module.exports =

//其它配置忽略......

};

這時由於 externals 的存在,webpack 打包的時候就會避開這些模組超多,依賴關係複雜的庫,把這些第三方 module 的入口指向預先打包好的lib.js的入口window.__lib,從而只打包我們的業務**。

同樣的 webpack 最近也新加入了這個功能:webpack.dllplugin。使用這個功能需要把打包過程分成兩步:

打包ddl包

引用ddl包,打包業務**

首先我們來打包ddl包,首先配置乙個這樣的ddl.config.js

const webpack = require('webpack');

const vendors = [

'react',

'react-dom',

'react-router',

// ...其它庫

];module.exports = ,

entry: ,

plugins: [

new webpack.dllplugin(),

],};

webpack.dllplugin 的選項中:

執行webpack,會輸出兩個檔案乙個是打包好的lib.js,乙個就是manifest.json,它裡面的內容大概是這樣的:

}

接下來我們就可以快樂地打包業務**啦,首先寫好打包配置檔案webpack.config.js

const webpack = require('webpack');

module.exports = ,

entry: ,

plugins: [

new webpack.dllreferenceplugin(),

],};

webpack.dllreferenceplugin 的選項中:

dllplugin 本質上的做法和我們手動分離這些第三方庫是一樣的,但是對於包極多的應用來說,自動化明顯加快了生產效率。

徹底解決webpack打包慢

前端開發乙個crm專案的時候,因為專案內容比較龐大,導致webpack編譯和打包都巨慢,實在是影響開發效率,所以著手公升級webpack。webpack4 es6 react是乙個全新的基於webpack4 react16 es6 antd mobile的前端架構實現方案,預設是antd mobil...

徹底解決 OBJC CLASS

最近在使用靜態庫時,總是出現這個問題。下面總結一下我得解決方法 1.m檔案沒有匯入 在build phases裡的compile sources 中新增報錯的檔案 2.framework檔案沒有匯入 靜態庫編譯時往往需要一些庫的支援,檢視你是否有沒有匯入的庫檔案 同樣是在build phases裡的...

徹底解決INSTALL FAILED UPDATE

按ctrl c退出系統,利用adb pull data system packages.xml命令將packages.xml放到你pc機本地,然後找到你需要的包名,刪除到的一段資料。例如 儲存packages.xml,然後adb push packages.xml data system將packa...