tree shaking
tree shaking 其实是 找出使用的代码,将未使用的代码剔除掉。
基于 ES6 的静态引用,tree shaking 通过扫描所有 ES6 的 export,找出被 import 的内容并添加到最终代码中。 webpack 的实现是把所有 import 标记为有使用/无使用两种,在后续压缩时进行区别处理。
tree shaking 只支持es Module 引入的文件。
Code Splitting 代码分割
Code Splitting
本质上与webpack
是没有任何关系的。通过合理的代码分割,可以让我们的项目性能更高。
webpack
实现代码分割,两种方式:
- 同步代码分割
optimization: {
splitChunks: { //代码分割
chunks: 'all'
}
}
- 异步代码 ,无需做任何配置,会自动进行代码分割,放置到新的文件中。
splitChunkPlugin插件
默认webpack就可以使用代码分割了,依赖于splitChunkPlugin
这个插件。可以在optimization
中配置:
optimization: {
splitChunks: { //代码分割
}
}
splitChunks:{}
什么都不写跟splitChunks
的默认配置是一样的,下面就是splitChunks
的默认配置。
splitChunks: {
chunks: "async",
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
参数解析:
1.chunks
chunks:'initial'
指的是在做代码分割的时候只对同步代码
生效。chunks:'async'
指的是在做代码分割的时候只对异步代码
生效。chunks:'all'
指的是在做代码分割的时候对同步和异步代码
都生效,但还需要做一些其他的配置cacheGroups
如下。
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
}
2.minSize 大于最小的大小才会开始做代码分割,小于这个值不会做代码分割
3.minChunks 当一个模块用了至少多少次之后才进行拆分
4.maxAsyncRequests 同时加载的模块数最多是多少个
5.maxInitialRequests 入口文件加载的模块数(首页加载的模块数)最多多少个
6.automaticNameDelimiter 文件生成时候组和文件间的连接符
7.cacheGroups 对分割的文件进行分组
8.priority属性 满足条件的多个缓存组 priority优先级越高就放到哪个组当中
9.reuseExistingChunk属性 如果一个模块之前已经被打包过了,那么打包的时候会忽略这个模块的引用,直接用之前已经引用过的。
css代码分割
webpack
团队专门针对 webpack4.x
写了一个插件来做这件工作,那就是 mini-css-extract-plugin
npm i mini-css-extract-plugin -D
需要用到该插件的是生产环境,开发环境,我们不需要去把 CSS
单独分离出来,首先,修改 webpack.prod.js
文件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
rules:[{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
}, {
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
}]
可以看出,和开发相比,我们只是把 style-loader
的引用整体改为了 MiniCssExtractPlugin.loader
接下来,还需要在 plugins
中添加引用
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[name].chunk.css'
})
]
顺便说下css代码的压缩方式
npm ioptimize-css-assets-webpack-plugin -D
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
optimization:{
minimizer: [new OptimizeCSSAssetsPlugin({})]
}
webpack与浏览器缓存(caching)
output:{
filename:'[name].[contenthash].js',
chunkFilename:'[name].[contenthash].chunk.js',
},
contenthash
内容变换会自动生成hash 生产环境中要用 避免缓存,如果打包的内容没有变,打包的时候contenthash
也不会改变。
针对老一点的4.x版本,可能会需要一下额外的配置:
optimization:{
runtimeChunk:{
name:'runtime'
}
}
这样的话会多了一个runtime
文件,这个文件是将包与包之前的关系内容都放到这里,处理main.js
和vendors~.js
的依赖关系。
shimming
// 如果你用了$ 并且你没有引入jquery 这个插件就会偷偷的帮你引入
const webpack = require('webpack');
new webpack.ProvidePlugin({
$:'jquery',
_:'lodash'
})
imports-loader
可以改变this的指向
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
use:[
{
loader:'babel-loader'
},
{
loader:'imports-loader?this=>window'
}
]
},
webpack env环境变量的配置
env可以在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"
},
对env的设置可以让自己可以判断出当前是开发环境,还是生产环境,对应的做不同的webpack处理,如下:
module.exports = (env)=>{
if(env && env.production){
return merge(commonConfig,prodConfig);
}else{
return merge(commonConfig,devConfig);
}
}