Webpack4.x出來也有一段時間了,網上已經有不少關於Webpack4.x原理和新特性的介紹,好比零配置等,這邊就不重複了。css
最近將以前基於Webpack3.x寫的一個多頁面項目升級到4.x,記錄和總結Webpack3.x升級到4.x遇到的問題以及解決方案。html
項目預覽gif:vue
區分3.x和4.x不一樣以外,也對Webpack進行了構建優化,並分別配置了Webpack3.x和Webpack4.x的基礎配置文件託管在Github,能夠用在項目中,減小配置的時間。node
Webpack3.x:github.com/czero1995/w…react
Webpack4.x:github.com/czero1995/w…jquery
開發環境: npm run dev
生產環境: npm run build
複製代碼
區分開發環境能夠提升Webpack打包效率,好比webpack
開發環境中:ios
配置調試模式devtool:cheap-source-mapgit
配置devServer:保存自動刷新github
生產環境:
配置調試模式devtool:inline-source-map
加載提取CSS組件
加載PostCss插件(瀏覽器前綴,提升兼容性)
添加每次Build時先刪除以前Build的文件
壓縮代碼
清空代碼註釋和空格
加載PostCss插件
從4.0開始:運行webpack必定要加參數
-- mode development 或者 --mode production,
分別對應開發環境和生產環境,不然會報警告:
3.x (package.json)
"scripts": {
"build": "webpack --optimize-minimize",
"dev": "webpack-dev-server --config webpack.dev.config.js"
},
複製代碼
4.x (package.json)
"scripts": {
"build": "webpack --optimize-minimize --mode production",
"dev": "webpack-dev-server --config webpack.dev.config.js --mode development"
},
複製代碼
在Webpack3.x中還保留以前版本的loaders,與rules並存均可以使用,在新版中徹底移除了loaders,必須使用rules。不然會報錯,將module下面的loaders改成rules便可
4.x須要安裝webpack-cli,否則運行不起來
npm install webpack-cli --save
複製代碼
在webpack3.x中typescript使用正常,升級到webpack4.x以後就用不了typescript了,由於版本過低 修改typescript版本,個人事5.2.2,在package.json中修改ts-loader版本號,或者刪掉,從新執行 npm install ts-loader便可
Webpack結合Ejs能夠作到組件化開發,共用HTML代碼,好比多個頁面的頭部和底部,用組件引入的方式,方面後面的開發和維護。
3.x中正常使用,4.x會報ejsRenderLoder of undefined,須要修改htmlplugin的配置。 3.x爲:
template: 'ejs-render-loader!pages/index.ejs',
複製代碼
4.x爲
template: 'ejs-loader!pages/index.ejs',
複製代碼
在package.json中修改extract-text-webpack-plugin版本號
"extract-text-webpack-plugin": "^v4.0.0-alpha.0",
複製代碼
自帶的js壓縮插件是單線程執行的,而webpack-parallel-uglify-plugin能夠並行的執行 開發環境不作無心義的操做
不少配置,在開發階段是不須要去作的,咱們能夠區分出開發和線上的兩套配置,這樣在須要上線的時候再全量編譯便可,好比代碼壓縮,目錄內容清理,計算文件hash,提取css文件等
babel-loader在執行的時候,可能會產生一些運行期間重複的公共文件,形成代碼體積大多餘,同時也會減慢編譯效率
能夠加上cacheDirectory參數或使用transform-runtime插件試試
// webpack.config.js
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true
}]
// .bablerc
{
"presets": [
"env",
"react"
],
"plugins": ["transform-runtime"]
}
複製代碼
happypack會採用多進程去打包構建
複製代碼
webpack打包的時候,有時不須要解析某些模塊的加載(這些模塊並無依賴,或者並根本沒有模塊化),咱們能夠直接加上這個參數,直接跳過這種解析
module:{
noParse: /node_modules\/(jquery.js)
}
複製代碼
這是最複雜也是提高效果最明顯的一步,原理是將第三方庫文件單獨打包一次,之後的編譯都不須要在編譯打包第三方庫
拷貝靜態資源文件,引入DllPlugin和DllReferencePlugin來提早構建一些第三方庫,來優化Webpack阿寶。
而在生產環境時,就須要將提早構建好的包同步到dist中
對於commonChunkPlugin,webpack每次打包實際仍是須要去處理這些第三方庫,只是打包完以後,能把第三方庫和咱們本身的代碼分開。 而DllPlugin則是能把第三方代碼徹底分離開,即每次只打包項目自身的代碼。 在build/文件夾下新建webpack.dll.config.js文件,複製一下代碼:
const path = require("path")
const webpack = require("webpack")
module.exports = {
// 你想要打包的模塊的數組
entry: {
vendor: ['vue/dist/vue.esm.js', 'axios', 'vue-router', 'vuex']
},
output: {
path: path.join(__dirname, '../static/js'), // 打包後文件輸出的位置
filename: '[name].dll.js',
library: '[name]_library'
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, '.', '[name]-manifest.json'),
name: '[name]_library',
context: __dirname
}),
// 壓縮打包的文件
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]
}
複製代碼
在build/webpack.dev.config.js和build/webpack.prod.config.js中添加plugins
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./vendor-manifest.json')
}),
複製代碼
在根目錄下的index.html下引入預編譯的庫
<script src="./static/js/vendor.dll.js"></script>
複製代碼
在package.json/scripts下中添加dll命令
"dll": "webpack --config ./build/webpack.dll.config.js"
複製代碼
運行:
npm run dll
複製代碼
而後再
npm run dev或npm run build
複製代碼
提取公共代碼 使用CommonsChunkplugin提取公共的模塊,能夠減小文件體積,也有助於瀏覽器層的文件緩存
npm run dll
npm run dev 或npm run build
複製代碼