更新 webpack4 的部分配置
- 問題
1盐肃、不能再使用 extract-text-webpack-plugin提取 css 文件,而是用 mini-css-extract-plugin
2、production 模式下 optimization 的配置中森逮,要加上 concatenateModules: false, 否則打出的包會有問題妖谴,這似乎是 webpack 的bug
- 新配置 optimization 中的 SplitChunksPlugin
SplitChunksPlugin 提供了兩種控制 chunk 抽取模塊范圍的方式:
第一種是 test 屬性。這個屬性可以傳入字符串酵熙、正則或者函數(shù)轧简,所有的 module 都會去匹配 test 傳入的條件,如果條件符合匾二,就被納入這個 chunk 的備選模塊范圍哮独。
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all'
}
第二種方式是 chunks 屬性拳芙。chunks 可以是字符串,比如 'all'|'async'|'initial'皮璧,分別代表了全部 chunk舟扎,按需加載的 chunk 以及初始加載的 chunk。chunks 也可以是一個函數(shù)悴务,在這個函數(shù)里我們可以拿到 chunk.name睹限。
// 有 a, b, c 三個入口,我們希望 a讯檐,b 的公共代碼單獨打包為 common
optimization: {
splitChunks: {
cacheGroups: {
common: {
chunks(chunk) {
return chunk.name !== 'c'
}
name: 'common',
minChunks: 2
}
}
}
}
以下為原文:
本文記錄webpack2中的常用配置項和插件
1羡疗、常用配置
module.exports = {
cache: true, //開啟緩存功能,這樣只有變化的文件才會重新加載别洪,可提升構(gòu)建速度
entry:{},
output: {},
module: {},
resolve: {},
externals:{},
plugins:{}
}
1.1 entry
-
單入口時key為app叨恨,value寫上相對于webpack.config.js的入口文件路徑即可,如:
單入口
注意:value還可以是數(shù)組挖垛,這種情況要注意順序特碳,確保主入口在數(shù)組的末位上!
-
多入口時key為app的是主入口晕换,其他key可自己取名午乓,但要加引號,如:
多入口
注意:有幾個入口闸准,webpack就會打幾個包(bundle)出來益愈,打出來的包的文件名與這里的key對應,比如上圖會打出類似app.js和vendor.js兩個文件(這里省略了hash)夷家。
1.2 output
- path
規(guī)定打包后的文件放哪兒蒸其,必須是絕對路徑,常取值為:
__dirname+’/build’或path.resolve(__dirname,’build’) - filename
規(guī)定打包后的文件的名字库快,對于單入口文件摸袁,可以取一個固定的名字,如’build.js’义屏,對于多入口文件靠汁,要使用[name].bundle.js或[id].bundle.js來對應,其中name和id是根據(jù)多入口文件對象的屬性動態(tài)確定的 - publicPath
規(guī)定線上地址闽铐,打包后的文件中資源的引用地址會根據(jù)這個地址而改變蝶怔,一般取為’/assets/’ - chunkFilename
webpack可以做代碼分割,這個屬性規(guī)定那些做了代碼分割的塊(chunk)的名字
默認使用 [id].js
webpack中的path兄墅、publicPath踢星、contentBase的區(qū)分
1.3 module
- rules:數(shù)組
數(shù)組中每一項類似于這樣配置:
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory=true', //當使用多個loader時,請用use而不是loaders代替loader
include: [resolve('src'), resolve('test')],
exclude: [resolve('node_modules')]
}
有時還會有query或options配置隙咸,二者都是use:{options}的簡寫沐悦,所以在用了use后就不需要這兩個配置了成洗,如下(一個loader對應一個options,使用多個loader時用use):
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
{
loader: 'less-loader',
options: {
noIeCompat: true
}
}
]
- noParser
防止 webpack 解析任何與給定正則表達式相匹配的文件,忽略大型庫文件(library)可以提高構(gòu)建性能
noParse: /jquery|lodash/
1.4 resolve
配置模塊如何解析
- root:字符串或值為字符串的數(shù)組藏否,絕對路徑泌枪,配置alias中依賴項的基地址
- alias
創(chuàng)建 import 或 require 的別名,來確保模塊引入變得更簡單秕岛。
對象碌燕,key為變量名,值為路徑继薛。key指定的變量將成為全局變量修壕,比如想在任何文件中都是用jquery而不必每次都顯示引入,可以這樣{$:jquery文件的地址}遏考,地址可以是相對地址(相對root指定)慈鸠,也可是絕對地址(使用path.resolve(__dirname,’jquery’)). - extensions:數(shù)組,文件擴展名灌具,某文件的擴展名在該數(shù)組中時青团,該文件在引入時可省略擴展名,常取值有[‘’ , ’.js’ , ‘.json’ , ‘.scss’ , ‘.vue’]
- modules
告訴 webpack 解析模塊時應該搜索的目錄
resolve: {
extensions: ['.js', '.vue', '.json'],
modules: [
resolve('src'), //實際返回了src的路徑咖楣,會優(yōu)先于node_modules搜索
resolve('node_modules')
],
alias: {
'vue$': 'vue/dist/vue.common.js',
'src': resolve('src'),
'assets': resolve('src/assets'),
'components': resolve('src/components'),
'styles': resolve('src/styles'),
'utils':resolve('src/utils'),
'demos':resolve('src/demos'),
'cnode':resolve('src/cnode')
}
}
1.5 externals
提供了不從 bundle 中引用依賴的方式督笆。也就是所創(chuàng)建的 bundle 依賴于那些存在于用戶環(huán)境(consumer environment)中的依賴。比如jquery是用script的方式從html引入的诱贿,要想在其他模塊中引入的時候就可以使用這個配置
// html
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
// 配置
externals: {
$: 'jQuery' //key不加引號娃肿,value是腳本里的全局對象,這里value還可以是數(shù)組或?qū)ο笾槭硎镜暮x大不一樣料扰,可參看[這里](http://www.css88.com/doc/webpack2/configuration/externals/)
}
// 其他模塊引入的方式
import $ from 'jquery';
1.6 performance、stat
performance:某個打包后的包超過給定閾值時給出提示
stat:控制webpack打包后輸出哪些信息
1.7 plugins
plugins是除module外最為重要的配置了焙蹭,插件機制提供了loader無法完成的功能晒杈,常用的plugin有:
- CommonsChunkPlugin
- DefinePlugin
- HtmlWebpackPlugin
- UglifyjsWebpackPlugin
- ExtractTextWebpackPlugin
- OptimizeCSSPlugin
- CompressionWebpackPlugin
- SourceMapDevToolPlugin
- FriendlyErrorsPlugin
- BundleAnalyzerPlugin
2、插件用法配置
- CommonsChunkPlugin
new webpack.optimize.CommonsChunkPlugin(options)
options的配置:
name:抽取出公共代碼后的模塊名孔厉,若沒有filename項拯钻,該項也決定打包后的文件名
chunks:從哪些模塊中抽取公共代碼,若省略烟馅,則從所有模塊中抽人低ァ(一般是從入口模塊抽)
minChunks:number|Infinity|function(module, count) -> boolean
為數(shù)字A時然磷,表示模塊必須被引用超過A次才提取到公共代碼里郑趁;為infinity時,表示無窮姿搜,不抽取任何模塊寡润;為函數(shù)時捆憎,函數(shù)返回true就抽取,實例:
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function(module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
})
- DefinePlugin
允許你創(chuàng)建一個在編譯時可以配置的全局常量梭纹。
new webpack.DefinePlugin({
'process.env': config.dev.env
})
注意這里定義的常量是在業(yè)務模塊中使用的躲惰,并不是在webpack這些配置文件中使用,因為webpack本身運行在node環(huán)境下变抽,node中自身就有process等全局變量础拨。如在入口main.js中不用聲明process.env就可以直接使用process.env判斷環(huán)境
- HtmlWebpackPlugin
生成一個HTML5文件,該文件的 body 中使用script 標記引用了所有 webpack bundle绍载。若有多個webpack入口點诡宗,它們都將包含在生成的HTML中,使用script
標記引用击儡。如果有任何CSS資源在webpack的 output 中塔沃,(例如,使用ExtractTextPlugin提取的CSS)那么這些資源將被包含在HTML head 中阳谍,使用<link>
標記引用蛀柴。實例:
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpackConfig = {
entry: 'index.js',
output: {
path: 'dist',
filename: 'index_bundle.js'
},
plugins: [new HtmlWebpackPlugin()]
};
//生成一個文件 dist/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack App</title>
</head>
<body>
<script src="index_bundle.js"></script>
</body>
</html>
配置:
-
title
: 生成的html中的title -
filename
: 生成的html的名字 -
template
: 用哪個模板來生成html -
inject
:true | 'head' | 'body' | false
取true或body時,all javascript 放在body底部,'head'
放head里 -
favicon
:指定生成的html的favicon -
minify
:{...} | false
壓縮生成的html -
hash
:true | false
是否給所有scripts和css添加hash -
cache
: 只有當html中內(nèi)容變化了才重新輸出矫夯,默認true -
showErrors
:true | false
錯誤細節(jié)是否寫到html鸽疾,默認true -
chunks
: 只添加哪些chunk -
excludeChunks
: 去掉哪些chunk
- UglifyjsWebpackPlugin
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
})
// 或使用這個代替
var ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
new ParallelUglifyPlugin({
cacheDir: '.cache/',
uglifyJS: {
output: {
comments: false,
beautify: false
},
compress: {
warnings: false,
drop_console: true
}
}
}),
配置項和uglify一樣的
- ExtractTextWebpackPlugin
將所有的 入口chunk (entry chunks) 中的 require("style.css") 或import 'style.css' 移動到分開的 css 文件.
需要兩步:1、rules中配置 ExtractTextPlugin.extract 2训貌、plugins中配置new ExtractTextPlugin("styles.css")
const ExtractTextPlugin = require("extract-text-webpack-plugin");
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin("styles.css"),
]
- OptimizeCSSPlugin
去除重復的CSS代碼
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
// 配置
plugins: [
new OptimizeCSSPlugin()
]
- CompressionWebpackPlugin
壓縮資源
var CompressionPlugin = require("compression-webpack-plugin");
// 配置
plugins: [
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.html$/,
threshold: 10240,
minRatio: 0.8
})
]
asset: 目標資源名稱肮韧。 [file] 會被替換成原始資源。[path] 會被替換成原始資源的路徑旺订, [query] 會被替換成查詢字符串弄企。默認值是 "[path].gz[query]"。
algorithm: 可以是 function(buf, callback) 或者字符串区拳。對于字符串來說依照 zlib 的算法(或者 zopfli 的算法)拘领。默認值是 "gzip"。
test: 所有匹配該正則的資源都會被處理樱调。默認值是全部資源约素。
threshold: 只有大小大于該值的資源會被處理。單位是 bytes笆凌。默認值是 0圣猎。
minRatio: 只有壓縮率小于這個值的資源才會被處理。默認值是 0.8乞而。
- BundleAnalyzerPlugin
分析打包構(gòu)成
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
plugins: [
new BundleAnalyzerPlugin({
// Can be `server`, `static` or `disabled`.
// In `server` mode analyzer will start HTTP server to show bundle report.
// In `static` mode single HTML file with bundle report will be generated.
// In `disabled` mode you can use this plugin to just generate Webpack Stats JSON file by setting `generateStatsFile` to `true`.
analyzerMode: 'server',
// Host that will be used in `server` mode to start HTTP server.
analyzerHost: '127.0.0.1',
// Port that will be used in `server` mode to start HTTP server.
analyzerPort: 8888,
// Path to bundle report file that will be generated in `static` mode.
// Relative to bundles output directory.
reportFilename: 'report.html',
// Module sizes to show in report by default.
// Should be one of `stat`, `parsed` or `gzip`.
// See "Definitions" section for more information.
defaultSizes: 'parsed',
// Automatically open report in default browser
openAnalyzer: true,
// If `true`, Webpack Stats JSON file will be generated in bundles output directory
generateStatsFile: false,
// Name of Webpack Stats JSON file that will be generated if `generateStatsFile` is `true`.
// Relative to bundles output directory.
statsFilename: 'stats.json',
// Options for `stats.toJson()` method.
// For example you can exclude sources of your modules from stats file with `source: false` option.
// See more options here: https://github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21
statsOptions: null,
// Log level. Can be 'info', 'warn', 'error' or 'silent'.
logLevel: 'info'
})
]
3送悔、webpack 配置熱更新步驟
這里熱更新是指局部重新加載,而非整個網(wǎng)頁重新加載。
- 開啟webpack-dev-sever的hot:true
module.exports = {
port: 3000,
contentBase: './src',
hot:true
}
- 引入熱加載插件 HotModuleReplacementPlugin
module.exports = [
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
}),
new HtmlWebpackPlugin({
template: resolve('src/index.html'),
filename: resolve('dist/index.html')
}),
new webpack.HotModuleReplacementPlugin() // 熱加載插件
]
- 在入口文件接收熱更新
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
if (module.hot) {
module.hot.accept() // 這里不用寫特定組件路徑
}