treeShaking
动态打包有用的结构
(只支持ES Module)
optimization: {
//配置treeShaking
usedExports: true
},
将不需要动态引入的文件 放在数组中(package.JSON)
dev和Pro分开打包
分别创建一个webpack.dev
一个webpack.prod
文件
然后再package.json文件做如下更改
消除冗余代码
将共同的代码写入一个js文件中
然后引入第三方模块 webpack-merge 进行拼接
也可以事先弄好build
代码拆分(code Splitting)
代码分割,和webpack无关
webpack中实现代码分割,两种方式
- 同步代码: 只需要在webpack.common.js中做optimization的配置即可
- 异步代码(import): 异步代码,无需做任何配置,会自动进行代码分割,放置到新的文件中
自行拆分
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
使用code Splitting
optimization: {
splitChunks: {
chunks: 'all'
}
},
异步代码
babel配置
plugins: ["@babel/plugin-syntax-dynamic-import"]
SplitChunksPlugin 参数配置
webpack魔法注释
optimization: {
splitChunks: {
//生效范围(异步async同步 or 全部all)
chunks: 'all',
//代码分割最大多少分割
minSize: 30000,
// 分割后最大文件大小(分不开就算了)
// maxSize
//用了多少次才会被分割
minChunks: 1,
//同时加载模块数
maxAsyncRequests: 5,
//入口文件代码分割最大数目
maxInitialRequests: 3,
//文件分割连接符号[vendors~main.js]
automaticNameDelimiter: '~',
name: true,
//同步代码分割规则[类似缓存组]
cacheGroups: {
//检测是否满足规则
vendors: {
//检测是否在目标文件夹下
test: /[\\/]node_modules[\\/]/,
// 优先级类似z-index
priority: -10,
//打包后的名称
filename: 'vendors.js',
},
//不在目标文件夹的配置
default: {
priority: -20,
//引入过会复用
reuseExistingChunk: true,
filename: 'common.js'
}
}
}
},
LazyLoading
在使用之后才会加载(vue react路由的动态加载)
每一个被分割的js文件都是一个chunk
打包分析
"scripts": {
/*用于打包分析的配置*/
"dev-build": "webpack --profile --json > stats.json --config ./build/webpack.dev.js",
},
这样就会自动生成一份分析文件stats.json放在根目录下。
进入如下网址上传分析文件则会自动分析
Prefetching
webpack希望所有的代码均按需加载,只加载现在用的代码即可
在加载完当前页面后,带宽被释放后继续加载异步文件
document.addEventListener('click', () =>{
import(/* webpackPrefetch: true */ './click.js').then(({default: func}) => {
func();
})
});
PreLoading
和主文件一起加载放在最后
preload chunk 会在父 chunk 加载时,以并行方式开始加载。prefetch chunk 会在父 chunk 加载结束后开始加载
preload chunk 具有中等优先级,并立即下载。prefetch chunk 在浏览器闲置时下载
preload chunk 会在父 chunk 中立即请求,用于当下时刻。prefetch chunk 会用于未来的某个时刻
浏览器支持程度不同
css代码分割(仅支持线上环境)
output: {
filename: '[name].js',
//间接文件文件名称
chunkFilename: '[name].chunk.js',
path: path.resolve(__dirname, '../dist')
}
安装插件
引入插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
{
test: /\.scss$/,
use: [
// 'style-loader', 这里不适用styleloader了
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
},
修改package.json
"sideEffects": [
"*.css"
],
css压缩
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
optimization: {
minimizer: [new OptimizeCSSAssetsPlugin({})]
},
plugins: [
new MiniCssExtractPlugin({
//直接引用的会被合并打包在这里
filename: '[name].css',
//其余的会被打包在这里
chunkFilename: '[name].chunk.css'
})
]
Caching
output: {
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].js'
}
后面会跟一个hash值
shimming
解决webpack打包的兼容性问题
引入webpack:const webpack = require('webpack');
在plugins中加入配置
使所有模块中的this指向window
进行如下配置
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader'
}, {
loader: 'imports-loader?this=>window'
}]
},]
环境变量的使用
package.json
"scripts": {
"dev-build": "webpack --config ./build/webpack.common.js",
"dev": "webpack-dev-server --config ./build/webpack.common.js",
"build": "webpack --env.production --config ./build/webpack.common.js"
},
commin.js
module.exports = (env) => {
if(env && env.production) {
return merge(commonConfig, prodConfig);
}else {
return merge(commonConfig, devConfig);
}
}