Webpack4 中引入的 Tree Shaking 技术能够做到精确的按需引入使用的代码,从而减小 bundle 的体积,提升网站性能。本文将详细介绍如何使用 Webpack4 中的 Tree Shaking 技术来优化前端的代码。
什么是 Tree Shaking?
Tree Shaking 是一种 JavaScript 代码优化技术,它能够分析代码依赖关系并删除掉无用的代码。
在 Webpack 中,Tree Shaking 是通过静态分析代码中的 import 和 export 声明来确定哪些代码被使用,哪些被废弃。
例如,在下面的示例中,只有 util1 中的 add 函数被使用,util2 中的 sub 函数没有被使用。
// javascriptcn.com 代码示例 // utils1.js export const add = (a, b) => { return a + b } // utils2.js export const sub = (a, b) => { return a - b } // app.js import { add } from './utils1' console.log(add(1, 2))
Tree Shaking 技术会将 util2 中的 sub 函数移除,只保留 app.js 中使用的 add 函数,使 bundle 体积更小,加载更快。
配置 Webpack4 进行 Tree Shaking
在 Webpack4 中,使用 Tree Shaking 需要开启 production 模式,并在 optimization 属性中设置参数。
// javascriptcn.com 代码示例 const path = require('path') module.exports = { mode: 'production', entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, optimization: { usedExports: true } }
配置 optimization.usedExports 选项为 true 可以开启 Tree Shaking 功能,将未被使用的代码标记为 unused,从而能够被 Tree Shaking 移除。
检查 Tree Shaking 结果
为了检查 Tree Shaking 是否正常工作,我们需要使用 source-map-explorer 工具来查看生成的 bundle.js 中未被使用的代码,进一步确认是否被移除。
// javascriptcn.com 代码示例 const path = require('path') const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') module.exports = { mode: 'production', entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, optimization: { usedExports: true }, plugins: [ new BundleAnalyzerPlugin() ] }
Webpack4 中有多个第三方工具可供选择来分析源代码,其中 Bundle Analyzer 是很好的一个。
在配置文件中添加 BundleAnalyzerPlugin 插件,运行 webpack 后访问 http://127.0.0.1:8888 即可看到分析结果。
Webpack4 Tree Shaking 踩坑指南
在实际使用过程中,可能会遇到 Tree Shaking 无法正常工作的情况。下面介绍几个常见的问题和解决办法。
1. 无法识别 CommonJS 模块
// math.js exports.add = (a, b) => { return a + b; };
如果在代码中使用 CommonJS 模块导出,在 Tree Shaking 中会被当作动态引用,而不能被优化,导致无法正常工作。解决办法是将代码改为使用 ES6 的 import 模块方式。
// math.js export const add = (a, b) => { return a + b; };
2. 使用 new Function 动态生成代码
在某些情况下,代码中使用 new Function 动态生成代码,无法被 Tree Shaking 移除。
const moduleName = 'lodash' const fn = new Function(`return require('${moduleName}')`) console.log(fn())
解决办法是改为静态引用方式。
import _ from 'lodash' console.log(_)
3. 使用 webpack.IgnorePlugin 忽略部分模块
在使用 webpack.IgnorePlugin 插件忽略掉一些模块时,也可能导致 Tree Shaking 无法正常工作,因为被忽略的模块不会出现在模块依赖关系树中,被误认为是没有使用的模块。
下面是一个使用 IgnorePlugin 插件忽略 moment.js 这个库的例子。
// javascriptcn.com 代码示例 const webpack = require('webpack') const path = require('path') module.exports = { mode: 'production', entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, optimization: { usedExports: true }, plugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/) ] }
解决办法是手动将 moment.js 设为外部库,告诉 Webpack 不需要对它进行 Tree Shaking。
// javascriptcn.com 代码示例 const webpack = require('webpack') const path = require('path') module.exports = { mode: 'production', entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, optimization: { usedExports: true }, externals: { moment: 'moment' } }
总结
使用 Webpack4 中的 Tree Shaking 技术,可以极大地减少 bundle 体积,提升页面性能。但要注意一些常见的踩坑点,尤其是对一些不常见的代码结构要格外小心,避免影响到 Tree Shaking 的正常工作。
完整的示例代码:https://github.com/shadowcat-me/webpack4-tree-shaking
推荐阅读:https://webpack.js.org/guides/tree-shaking/
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653dfa207d4982a6eb7948ff