一、概念
一个模块中可能会有多个方法, 只要其中的某个方法用到了, 整个文件就会打包到 bundle 中, 摇树优化就是只把用到的方法打包到 bundle 中, 而没有用到的则通过“摇树”的方式在 uglify 阶段去除掉.
webpack 默认支持摇树优化, 只需要在 .babelrc 中设置 modules: false 即可, 同时在 production mode 的情况下是默认开启的.
webpack 之前是使用 uglifyjs 来实现压缩的, 后来不怎么维护了, 就改用了 terser.
需要注意
必须是 ES6 的写法, CJS 的方式不支持
你 npm 别人的库, 如果不是 ES6 写法也不生效
babel-loader 可能导致 Tree-shaking 失效
二、实现
去掉 console
npm install uglifyjs-webpack-plugin
// 配置 webpack.prod.config.js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
output: {
comments: false // 删除注释
},
compress: {
drop_console: true, // 删除所有 console
drop_debugger: true, // 删除所有 debugger
pure_funcs: ['console.log', 'console.error'] // 删除 console.log、console.error
}
}
})
]
}
}
// 配置 vue.config.js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
configureWebpack: config => {
let optimization = {...} // 配置与上述相同
Object.assign(config, { optimization })
}
}
去掉无用CSS
方案一: PurifyCSS
原理 遍历代码, 识别已经用到的 css class
环境 webapck4
依赖
代码
npm i purgecss-webpack-plugin -D
const path = require('path')
const glob = require('glob')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const PurgeCSSPlugin = require('purgecss-webpack-plugin')
const PATHS = {
src: path.join(__dirname, 'src')
}
modeule.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
new PurgeCSSPlugin({
paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }),
}),
]
}
方案二: uncss
原理 通过 document.querySelector 来识别是否存在对应的选择器
要求
1、HTML需要通过 jsdom 加载
2、样式通过 PostCSS 解析
开启副作用标识
原理 通过配置的方式, 标识代码是否有副作用, 从而为 TreeShaking 提供更大的压缩空间
环境 webapck4
webpack 会识别代码中未使用的导出内容(或者压根没有导入的), 并依赖 terser 检测代码的副作用, 如果没有副作用则会跳过该模块, 不将其打包
通过程序的方式来判断一个模块是否具有副作用是一件极其耗时的工作, 且因为JS是动态语言, 那么判断的结果也不一定准确, 因此如果能人为的标识本模块是否具有副作用或者所有文件都没有副作用就显得非常重要
需要注意的是, 如果在多人协同工作的过程中, 你添加了 sideEffects: false 无副作用标示, 但其他同事写了一个有副作用的模块, 且没有在 package.json 中配置, 而那个同事又刚好不知道这个属性的作用, 那么他将不断的挠头问自己, 为什么明明有这个函数, 本地也是对的, 放到线上就不对了(只在 production mode 生效)
// usedExports: 识别无用代码 未使用的导出内容不会打包,依赖于 terser 检测代码的副作用
// sideEffects: 开启副作用标识功能, 当值为 false 时, 允许跳过整个模块/文件.
module.exports = {
// webpack 在生产环境下可启用更多优化项
mode: 'production', // 生产环境
optimization: {
// usedExports: true,
sideEffects: false // 指定所有文件都没有副作用
}
}
// 如果存在有副作用模块需要单独声明, 则在 package.json 配置
{
"sideEffects": [
"*.css",
"./src/extends.js"
]
}
三、问题
暂无