前言
随着 Web 前端技术的不断发展,前端工程师的日常开发也变得更加繁琐,特别是当项目规模变大的时候,前端产物的体积也会不断增加。而体积过大不仅会影响页面的加载速度,也会影响用户体验,因此对于企业和前端工程师来说,对前端产物的体积进行优化显得尤为重要。在这篇文章中,将着重介绍如何使用 webpack4 来优化前端产物的体积。
产物体积分析
在进行产物体积优化时,首先需要了解产物的体积结构,这里以 vue-cli 3 项目为例,使用 npm run build
命令生成产物,然后使用 webpack-bundle-analyzer 插件进行体积分析,使用结果如下所示:
从上图可以看出,app.js
这个文件的体积占比过大,这是因为 app.js
为应用入口模块,包含了所有的业务逻辑代码和组件库代码,因此需要将 app.js
进行拆分和按需加载,以此来减少打包后的体积。
代码分离
在前端工程化中,使用模块化开发可以有效地避免代码重复、提高开发效率,Webpack 也提供了多种方式来实现代码分离,其主要有以下几种:
入口起点
在 entry
中配置多个入口文件,每个入口文件都会生成一个产物,相互之间没有依赖关系,适用于简单的项目,但当项目复杂度增加时,配置多个入口文件将变得困难。
module.exports = { entry: { app: './src/app.js', vendor: './src/vendor.js', }, output: { filename: '[name].[hash].js', }, };
代码分离 + 动态导入
Webpack 4 推荐使用动态导入来实现代码分离,即使用 import()
或 require.ensure()
来进行代码分离,结合 webpackChunkName
参数可以设置输出文件的名称。
import('./path/to/module') .then(module => { // do something with the module }) .catch(error => { // handle error });
require.ensure(['./path/to/module'], () => { const module = require('./path/to/module'); // do something with the module }, 'myModule');
SplitChunksPlugin 插件
SplitChunksPlugin
插件可以将公共模块提取出来,避免代码重复,并生成一个或多个新的代码块,以此来实现对代码的分离。
module.exports = { optimization: { splitChunks: { chunks: 'all', 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, }, }, }, }, };
动态 Polyfill
随着浏览器标准的不断升级,前端开发中逐渐出现了一些新的语法和 API,为了兼容旧的浏览器,JavaScript 开发人员往往需要使用 polyfill 来填充这些新特性,如果所有的 polyfill 都被打包到了产物中,那么必然会造成产物体积的增加。对此,Webpack 提供了 @babel/plugin-transform-runtime
插件来实现动态加载 polyfill,只有实际需要使用到的才会被加载。
// .babelrc { "plugins": ["@babel/plugin-transform-runtime"] }
Tree Shaking
Tree Shaking 可以消除产物中未被使用的代码,以此来达到减少产物体积的效果。Webpack 通过静态分析的方式检测代码中未被使用的部分,然后将其删除,而实现这一功能的核心工具是 UglifyJSPlugin
。
// webpack.config.js const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); module.exports = { //... optimization: { minimizer: [ new UglifyJsPlugin({ uglifyOptions: { compress: { unused: true, drop_debugger: true, }, output: { comments: false, }, }, cache: true, parallel: true, sourceMap: true, }), ], }, //... };
环境变量注入
在前端开发中,我们可能需要针对不同的环境进行不同的操作,比如使用不同的 API 地址、不同的 CDN 链接等等,这时候通过环境变量来进行控制会更加便捷。Webpack 提供了 DefinePlugin
插件来实现环境变量注入:
// webpack.config.js const webpack = require('webpack'); const env = process.env.NODE_ENV; module.exports = { //... plugins: [ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify(env), }, }), ], //... };
总结
通过本文的介绍,我们了解了Webpack 4 的一些常见的产物体积优化技术,其中包括代码分离、动态 Polyfill、Tree Shaking、环境变量注入等等。这些技术虽然很简单,但结合实际项目,可以将产物体积减少至少一半以上。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65aefe50add4f0e0ff86aac5