# 优化构建结果
# 2.1 构建结果分析
借助插件 webpack-bundle-analyzer (opens new window)我们可以直观的看到打包结果中,文件的体积大小、各模块依赖关系、文件是够重复等问题,极大的方便我们在进行项目优化的时候,进行问题诊断。
- 安装
$ npm i -D webpack-bundle-analyzer
- 配置插件
// 引入插件
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const config = {
// ...
plugins:[
// ...
// 配置插件
new BundleAnalyzerPlugin({
// analyzerMode: 'disabled', // 不启动展示打包报告的http服务器
// generateStatsFile: true, // 是否生成stats.json文件
})
],
};
- 修改启动命令
"scripts": {
// ...
"analyzer": "cross-env NODE_ENV=prod webpack --progress --mode production"
},
执行编译命令 npm run analyzer
打包结束后,会自行启动地址为 http://127.0.0.1:8888 的 web 服务,访问地址就可以看到
如果,我们只想保留数据不想启动 web 服务,这个时候,我们可以加上两个配置
new BundleAnalyzerPlugin({
analyzerMode: 'disabled', // 不启动展示打包报告的http服务器
generateStatsFile: true, // 是否生成stats.json文件
})
这样再次执行打包的时候就只会产生 state.json 的文件了
# 2.2 压缩 CSS
- 安装 optimize-css-assets-webpack-plugin
$ npm install -D optimize-css-assets-webpack-plugin
- 修改 webapck.config.js 配置
// 压缩css
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
// ...
const config = {
// ...
optimization: {
minimize: true,
minimizer: [
// 添加 css 压缩配置
new OptimizeCssAssetsPlugin({}),
]
},
// ...
}
// ...
- 查看打包结果
# 2.3 压缩 JS
在生成环境下打包默认会开启 js 压缩,但是当我们手动配置 optimization 选项之后,就不再默认对 js 进行压缩,需要我们手动去配置。
因为 webpack5 内置了terser-webpack-plugin 插件,所以我们不需重复安装,直接引用就可以了,具体配置如下
const TerserPlugin = require('terser-webpack-plugin');
const config = {
// ...
optimization: {
minimize: true, // 开启最小化
minimizer: [
// ...
new TerserPlugin({})
]
},
// ...
}
# 2.4 清除无用的 CSS
purgecss-webpack-plugin (opens new window) 会单独提取 CSS 并清除用不到的 CSS
- 安装插件
$ npm i -D purgecss-webpack-plugin
- 添加配置
// ...
const { PurgeCSSPlugin } = require('purgecss-webpack-plugin')
const glob = require('glob'); // 文件匹配模式
// ...
function resolve(dir){
return path.join(__dirname, dir);
}
const PATHS = {
src: resolve('src')
}
const config = {
plugins:[ // 配置插件
// ...
new PurgeCSSPlugin({
paths: glob.sync(`${PATHS.src}/**/*`, {nodir: true})
}),
]
}
- index.html 新增节点
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ITEM</title>
</head>
<body>
<p></p>
<!-- 使用字体图标文件 -->
<i class="iconfont icon-member"></i>
<div id="imgBox"></div>
<!-- 新增 div,设置 class 为 used -->
<div class="used"></div>
</body>
</html>
- 在 sass.scss 中添加样式
.used {
width: 200px;
height: 200px;
background: #ccc;
}
.unused {
background: chocolate;
}
- 执行一下打包
我们可以看到只有 .used 被保存下来 如何证明是这个插件的作用呢?注释掉再打包就可以看到,.unused 也会被打包进去,由此可证...
# 2.5 Tree-shaking
Tree-shaking 作用是剔除没有使用的代码,以降低包的体积
webpack 默认支持,需要在 .bablerc 里面设置 model:false,即可在生产环境下默认开启
了解更多 Tree-shaking 知识,推荐阅读 👉🏻 从过去到现在,聊聊 Tree-shaking (opens new window)
module.exports = {
presets: [
[
"@babel/preset-env",
{
module: false,
useBuiltIns: "entry",
corejs: "3.9.1",
targets: {
chrome: "58",
ie: "11",
},
},
],
],
plugins: [
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/plugin-proposal-class-properties", { loose: true }],
]
};
# 2.6 Scope Hoisting
Scope Hoisting 即作用域提升,原理是将多个模块放在同一个作用域下,并重命名防止命名冲突,通过这种方式可以减少函数声明和内存开销。
- webpack 默认支持,在生产环境下默认开启
- 只支持 es6 代码