记录一下webpack的学习进度,目前用到的比较重要的是区分环境变量,打包动态链接库,与提取公共代码的功能,附带一些小插件。
区分环境变量
用途是区分开发环境或者生产环境的webpack执行内容或者代码运行内容
更改环境变量:
1.用webpack自带的DefinePlugin
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({
// 定义 NODE_ENV 环境变量为 production
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
],
};
2.用package.json的script来更改
需要安装cross-env使得windows能识别更改命令
package.json
{
//...
"scripts": {
"build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
"serve": "cross-env NODE_ENV=development webpack-dev-server",
"jq": "webpack --config webpack.config.react.js",
"delete": "rimraf node_modules"
},
}
然后在webpack.config.js中如果环境用到不同的配置,你可以这样写,当然在vue-cli3的vue.config.js中会有函数的形式更改module.exports对象(configureWebpack方法),更加方便
const isDev = process.env.NODE_ENV === 'development'
module.exports = {
//...
}
if (process.env.NODE_ENV === 'production') {
// 解决没区分环境变量而导致 npm run serve 后 dist文件夹被清空的问题
module.exports.plugins.push(
new CleanWebpackPlugin()
)
module.exports.optimization.minimizer.push(
new UglifyJsPlugin({
cache: true,
sourceMap: true,
parallel: true
})
)
}
动态链接库
webpack处理第三方引用库的方式非常多样,你可以选择把所有的引用都打包为一个vendor,也可以选择cdn的方式(externals)来引用他们,都有防止二次打包的功能,以打包jq为例。
const path = require('path')
const webpack = require('webpack')
module.exports = {
mode: 'development',
entry: {
jq: ['jquery']
},
output: {
filename: '_dll_[name].js',
path: path.resolve(__dirname, 'public/vendor'),
library: '_dll_[name]'
},
plugins: [
new webpack.DllPlugin({
name: '_dll_[name]',
path: path.resolve(__dirname, 'public/vendor', 'manifest.json')
})
]
}
// 在webpack.config.js中指定manifest.json
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, 'public/vendor', 'manifest.json')
}),
提取公共代码
对于单页面应用,webpack可以把多次引用的第三方库通过chunk的方式抽取出来,多页面应用可以抽取第三方库,还能把import的module代码抽取出来
module.exports = {
//...
optimization:{
splitChunks: {
// 表示选择哪些 chunks 进行分割,可选值有:async,initial和all
// chunks: 'all', // 表示新分离出的chunk必须大于等于minSize,默认为30000,约30kb。
// minSize: 30000, // 表示一个模块至少应被minChunks个chunk所包含才能分割。默认为1。
// minChunks: 1, // 表示按需加载文件时,并行请求的最大数目。默认为5。
// maxAsyncRequests: 5, // 表示加载入口文件时,并行请求的最大数目。默认为3。
// maxInitialRequests: 3, // 表示拆分出的chunk的名称连接符。默认为~。如chunk~vendors.js
// automaticNameDelimiter: '~', // 设置chunk的文件名。默认为true。当为true时,splitChunks基于chunk和cacheGroups的key自动命名。
// cacheGroups 下可以可以配置多个组,每个组根据test设置条件,符合test条件的模块,就分配到该组。
// 模块可以被多个组引用,但最终会根据priority来决定打包到哪个组中。
// 默认将所有来自 node_modules目录的模块打包至vendors组,
// 将两个以上的chunk所共享的模块打包至default组。
cacheGroups: {
vendor: {
chunks: 'all', // 表示选择哪些 chunks 进行分割,可选值有:async,initial和all
test: /node_modules/,
name: 'vendor', // 设置chunk的文件名。默认为true。当为true时,splitChunks基于chunk和cacheGroups的key自动命名。
minChunks: 1, // 表示一个模块至少应被minChunks个chunk所包含才能分割。默认为1。
maxInitialRequests: 5, // 表示加载入口文件时,并行请求的最大数目。默认为3。
maxAsyncRequests: 5, // 表示按需加载文件时,并行请求的最大数目。默认为5。
minSize: 20000, // 表示新分离出的chunk必须大于等于minSize,默认为30000,约30kb。
automaticNameDelimiter: '~', // 表示拆分出的chunk的名称连接符。默认为~。如chunk~vendors.js
priority: 100
},
common: {
chunks: 'all',
test: /[\\/]src[\\/]js[\\/]/,
name: 'common',
minChunks: 1, // 将两个以上的chunk所共享的模块打包至common组。
maxInitialRequests: 5,
minSize: 20000,
maxAsyncRequests: 5,
automaticNameDelimiter: '~',
priority: 60
}
}
}
小插件:
// 实现文件原样复制到打包后的文件夹
const CopyWpackPlugin = require('copy-webpack-plugin')
// 打包前自动清理dist目录
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// 多线程打包
const HappyPack = require('happypack')
网友评论