對於咱們引入的一些第三方包,好比jQuery
,在這些包內部是確定不會依賴別的包,因此根本不須要webpack去解析它內部的依賴關係,能夠在webpack
配置文件中的module
屬性下加上noParse
屬性,它的值是一個正則表達式,用來匹配無需解析的模塊,這樣能夠節約webpack
的打包時間,提升打包效率。css
module:{
noParse:/jquery/
}
複製代碼
須要注意的是必須確保添加的包中沒有依賴別的包,不然會報依賴錯誤。 vue
項目中依賴的一些第三方包好比react
、vue
通常狀況下包的內容不會發生改變,而每一次打包都要對它們進行構建顯然是不合理的,這會很浪費性能。正確的作法應該是將這些第三方包只打包一次,以後直接引用就能夠,直到第三方包須要更新版本時再從新進行構建。這樣咱們在打包的時候只須要構建咱們的業務代碼便可。react
Dllplugin
插件能夠幫助咱們把這些不作修改的包抽取爲動態連接庫,而且會生成一個名爲manifest.json的文件,這個文件是用來讓DLLReferencePlugin
映射到相關的依賴上去的。jquery
以React
爲例抽取Dll
webpack
React
抽取爲Dll的webpack
配置文件webpack.react.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
mode: 'development',
// 入口文件:將要配置成Dll的庫放進來
entry: {
react: [
'react'
]
},
// 輸出文件
output: {
// 輸出文件名
filename: '[name]_dll.js',
// 輸出文件路徑
path: path.resolve(__dirname, '../dist'),
// 將打包好的結果暴露在全局
library: '[name]_dll'
},
plugins: [
new webpack.DllPlugin({
// dll文件名
name: '[name]_dll',
// 清單文件路徑
path: path.resolve(__dirname, '../dist/mainfest.json')
})
]
}
複製代碼
DllReferencePlugin
這個插件通常是在webpack
的主配置文件中配置,在plugins
配置下添加以下配置,manifest
文件會將對dll文件的應用映射到模塊的id
上,而後在須要的時候來引用Dll
文件。web
new webpack.DllReferencePlugin({
// (絕對路徑) manifest (或者是內容屬性)中請求的上下文
context: __dirname,
// 清單文件路徑
manifest: path.resolve(__dirname, '../dist/manifest.json')
})
複製代碼
webpack.react.js
配置文件,通常狀況下能夠在package.json中添加運行腳本命令scripts:{
"build:react": "webpack --config ./build/webpack.react.js"
}
複製代碼
在命令行中運行該命令,這會在dist
目錄下生成react
的Dll
文件,還會生成一個mainfest.json
文件,這個文件包含了import
和require
的request
到模塊id
的映射。DLLReferencePlugin
也會引用這個文件。而後再進行打包,就不會對react
重複打包,而是直接引用生成的react_dll
文件。正則表達式
代碼優化的最終目的是爲了用戶體驗的優化,各類壓縮、拆分操做都應該圍繞最終目標展開。shell
把webpack
的mode
設置爲production
,進行生產模式打包的時候webapck
會自動進行如下優化npm
webpack
會在打包時移除引入了可是未引用的代碼,可是隻有經過ES6模塊系統中import
語法引入的纔會適用tree shaking
,減少生產環境下文件的體積,自動實現最基本的優化json
分析模塊之間的依賴關係,會盡量的將打散的模塊合併到一個函數中去。須要注意的是這種優化方式也是隻有經過ES6
模塊系統中import
語法引入的模塊才適用,而且只有那些只被引用的一次的模塊纔有可能被合併。
全部代碼自動使用UglifyJsPlugin
進行壓縮。
mini-css-extract-plugin
能夠將CSS拆分爲單獨的文件,使CSS文件能夠被異步加載,加快頁面加載呈現的速度。
使用方法:
$ npm i mini-css-extract-plugin -D
複製代碼
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
...,
module: {
rules: [
...,
{
test: /\.css$/,
// 將原來多有使用style-loader來處理的地方替換爲使用MiniCssExtractPlugin.loader
// use: ['style-loader', 'css-loader'],
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
...,
new MiniCssExtractPlugin({
// 生成的文件名
filename: '[name].css'
})
]
}
複製代碼
optimize-css-assets-webpack-plugin
插件能夠用來壓縮CSS文件,但使用該插件會致使webpack默認的js壓縮配置沒法生效,因此還須要手動對js代碼進行壓縮,js壓縮使用官方推薦的terser-webpack-plugin
使用方法:
$ npm i optimize-css-assets-webpack-plugin terser-webpack-plugin -D
複製代碼
const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
module.exports = {
...,
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
}
}
複製代碼
使用方法:只需在主配置文件中添加以下配置便可
Optimization: {
splitChunks: {
Chunks: 'all'
}
}
複製代碼
有不少的第三方包內部會作國際化處理,包含不少的語言包,而這些語言包對咱們來講時沒有多大用處的,只會增大包的體積,咱們徹底能夠忽略掉這些語言包,從而提升構建效率,減少包的體積。
以moment爲例,首先找到moment中語言包所在的文件夾,而後在webpack配置文件中添加插件
// 該方法的兩個參數都是正則,第一個參數表示要忽略的路徑,第二個表示該資源所在目錄,在該文件夾下引入的語言包都會被忽略
new webpack.IgnorePlugin(/\.\/locale/, /moment/)
複製代碼
這時候moment使用默認語言英語,若是要使用別的語言,能夠手動引入須要使用的語言包。
import moment from 'moment'
import 'moment/locale/zh-cn'
moment.locale('zh-CN')
複製代碼
在頁面中有一些代碼塊可能並非在頁面初始化的時候就須要使用的,須要用戶的某些操做出發纔會使用,若是用戶不觸發這個操做那這個代碼塊可能永遠不會被使用。咱們能夠將這些某個操做觸發纔會使用的代碼塊按需加載進來,而不是在頁面建立的時候直接加載,這樣能夠加快初始頁面的加載速度。
// 假設在頁面中有一個id爲btn的按鈕,當點擊這個按鈕的時候須要對時間進行操做
const btn = document.querySelector('#btn')
btn.onclick = e => import(/* webpackChunkName: "moment" */ 'moment').then(module => {
var moment = module.default;
moment().format('YYYY-MM-DD')
})
複製代碼
可是使用懶加載會影響用戶體驗,因此在懶加載的同時可使用魔法註釋:Prefetching
,能夠在首頁資源加載完畢後,空閒時間時,將動態導入的資源加載進來,這樣便可以提升頁面加載速度又保證了用戶體驗。
const btn = document.querySelector('#btn')
btn.onclick = e => import(/* webpackChunkName: "moment" *//* webpackPrefetch: true */ 'moment').then(module => {
var moment = module.default;
moment().format('YYYY-MM-DD')
})
複製代碼
webpack每次版本更新都會在性能上有很大提高,官方也推薦保持版本的更新。