前言
Webpack 是前端开发中不可或缺的工具,它能将多个模块打包成一个或多个 bundle。这个过程不只是简单的文件合并,Webpack 具有强大的插件系统,能够优化代码,提高开发效率。本文将介绍一些 Webpack 的技巧,包括如何使用之前可能未曾听闻的功能,以及一些最佳实践。
入门
在使用 webpack 前,需要了解一些基本概念。
- 入口文件(entry):webpack 打包的起点
- 出口文件(output):webpack 打包后生成的文件
- 模块(module):webpack 可以处理的各种文件,包括 js、css、png 等等
- 加载器(loader):用于处理特定类型的文件,如将 sass 转为 css
- 插件(plugins):webpack 的核心功能,可以用来优化代码、提高开发效率
下面是一个简单的 webpack 配置文件的示例:
-- -------------------- ---- ------- ----- ---- - ---------------- -------------- - - ------ ----------------- ------- - --------- ------------ ----- ----------------------- ------- -- ------- - ------ - - ----- ---------- ---- - --------------- ------------- ------------- - - - -- -------- -- --展开代码
在上述配置中,entry 指定了入口文件,output 指定了生成的文件名和路径。module.rules 下的一个规则表示,当 webpack 遇到以 .scss 结尾的文件时,会先使用 sass-loader 将该文件转为 css,再由 css-loader 处理,最后用 style-loader 将处理好的 css 插入到 html 页面中。
技巧
使用别名
在默认情况下,当你导入某个模块时,webpack 会从 node_modules 中进行查找,如果你的项目路径比较深,导入模块的路径也就会比较长。为了解决这个问题,可以使用别名(alias)。
在 webpack 配置文件中添加以下代码:
-- -------------------- ---- ------- ----- ---- - ---------------- -------------- - - -- --- -------- - ------ - ---- ----------------------- ------ - - --展开代码
此时,使用 @ 符号来表示 src 目录便十分方便:
import foo from '@/foo';
精细控制生成的文件名
我们可以在 output 属性的 filename 中使用占位符,例如:
module.exports = { // ... output: { filename: '[name].[hash].js', path: path.resolve(__dirname, 'dist') } };
hash 可以防止浏览器缓存,每次打包生成的文件都不同。而 name 表示 entry 中定义的属性名。
优化生产环境配置
在生产环境中,我们通常需要对代码进行压缩。这可以通过在配置文件中添加插件 UglifyJsPlugin 实现。但是,webpack 4 内置了一个 mode 选项,可以根据该选项自动开启优化功能,包括代码压缩、性能优化等等。可以在命令行中添加 --mode production,并删除配置文件中已经不再需要的属性。
使用 source map
在代码出现异常时,我们会知道哪一行代码出现了问题。不过,如果使用 webpack 开发多人协作项目,我们需要将错误信息及时反馈给其他人,方便他们调试。此时,就需要 source map。
在配置文件中添加 devtool 属性即可启用 source map:
module.exports = { // ... devtool: 'source-map' };
更多关于 source map 的内容参见:
处理图片
webpack 可以处理各种类型的文件,包括图片。我们可以使用 url-loader 或 file-loader 处理图片,将图片编码为 base64 或将图片拷贝到 output 目录中,然后将路径写到打包后的文件中。
-- -------------------- ---- ------- -------------- - - -- --- ------- - ------ - - ----- ---------------------- ------- ------------- -------- - ------ ----- ----- ---------------------- ----------- --------- ----------- --------- - - - - --展开代码
该规则表示处理以 png、jpg、jpeg、gif 结尾的文件。当文件大小不超过 8192 字节时,将该文件编码为 base64 字符串,否则将该文件拷贝到 output 目录下的 images 目录中,并将该文件的路径替换成 /images/xxx.png 的形式。
拆分代码
当我们的项目越来越复杂,打包出来的 bundle.js 会越来越大,这会对加载速度造成负面影响。为了提高网页加载速度,我们可以将代码分离成多个 chunk,这样浏览器就可以并行加载多个小的文件,从而提高速度。
在添加 optimization.splitChunks 到配置文件即可启用拆分代码功能:
module.exports = { // ... optimization: { splitChunks: { chunks: 'all' } } };
该选项会将所有的 node_modules 下的模块抽离到一个单独的文件夹中。
优化构建速度
当项目特别大时,打包和重新打包需要的时间也会越来越久。下面我们可以通过一些方法来优化构建速度。
可以尝试使用 cache-loader 和 hard-source-webpack-plugin 插件,缓存第一次打包后的模块,加快二次构建速度。
-- -------------------- ---- ------- -------------- - - -- --- ------- - ------ - - ----- -------- ------- --------------- -------- - --------------- ----------------------- --------- -- -------- -------------- - - -- -------- - --- ------------------------- - --展开代码
cacheDirectory 指定了缓存路径,exclude 指定了哪些文件夹不编译。
HardSourceWebpackPlugin 会缓存 modules 和 chunks,以增量构建模式的形式提速 webpack 构建时间。
编写优秀的 Vue 组件
当使用 Vue 开发时,需要注意一些性能问题。例如,当一个组件不需要 props 时,应该将其在父组件中写死(如:将字符串、常量等直接赋值给子组件),而不是从父组件中动态传递。这样可以减少组件更新的次数,从而提高性能。
以 Footer.vue 组件为例,当该组件中的内容不需要进行更新时,应该直接写死,而不是将一个字符串传给该组件。
<!-- 当 Footer.vue 每次重新构建时,其内容都不会更新 --> <template> <footer> <span>所有版权归©️ 2021 于晓鹤</span> </footer> </template>
当然,如果其中的内容需要更新,传递 props 也是合理的。
结语
以上是 Webpack 的一些技巧和最佳实践。Webpack 的功能非常强大,可以满足大部分前端开发的需求。当遇到问题时,可以通过 Webpack 官网或社区提供的资源来寻求帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67bd79f1a231b2b7edff29e5