前言:webpack资料网上一抓一大把,但是很多时候对新技术的学习速度往往赶不上技术本身的更新速度。不排除有时候费尽心思学习的却是早已被淘汰的😂。因此本文立足webpack官网,基础篇主要整理了webpack新版的一些基础配置及作用介绍,包括开发中推荐的配置及新旧版本中差异化的地方。
如果你对webpack5聊熟于心,那么本文可能不适合你,有兴致路过的话还望多多指教嘴下留情咯,毕竟你的几分钟背后是我的几小时😭☕️ 如果对《Webpack配置指南:从基础到高阶专栏-高阶优化篇》感兴趣,可以顺道看看👁
不足的地方还望各位佬提出来,一起进步🍺☕️
entry配置
- 最简配置-字符
entry: './xx/xx.js'
- 支持对象
输出文件[name]配置默认取值是入口文件名称,入口文件可以通过给entry配置成对象的形式指定,key即为[name]的值,如果不指定将entry的key,按上述字符串形式配置则默认为main
entry: {
index: path.resolve(__dirname, "/src/index.js"),
},
output
clean
默认情况下,如果不做配置的话,每次打包不会清除之前已存在的文件,需要配置output的clean为true清理已存在的文件。
注意:之前版本需要使用clean-webpack-plugin插件实现文件清理,webpack5已将该能力内置
filename: 用于动态生成文件名
常用:[name].xx.js
name根据入口文件生成,如果没指定入口文件名称(entry配置的key),则默认是main
哈希值:
常见的有:fullhash、chunkhash、contenthash
注意:旧版中hash的配置在新版中已被标记过时:
✧ [fullhash]
适用场景:如果你的项目有多个不同类型的输出文件(如 JavaScript 文件、CSS 文件、图片等),并且你希望确保每个构建的整体状态都能被准确标识,fullhash可以帮助你实现这一点。这样,当你检查构建版本时,可以通过fullhash值快速确定整个项目的构建状态是否发生了变化。
不适用场景:在大型项目中,如果只对某个模块进行了修改,使用 [fullhash] 会导致所有文件的文件名都发生变化,从而使所有文件都需要重新下载,这会浪费大量的网络资源和时间,降低用户体验。
✧ [chunkhash]
chunkhash 是根据每个 chunk(模块组)的内容生成的哈希值
适用场景:非常适合大型项目中不同模块的缓存控制。当对某个模块进行修改时,只有该模块所在的代码块文件名会发生变化,其他模块的缓存不受影响,这样可以提高缓存效率,减少不必要的文件重新下载。例如,在一个包含多个模块的 Web 应用中,当更新了其中一个模块的代码,使用 [chunkhash] 可以确保只有相关的代码块文件需要重新下载,而其他模块的代码可以继续使用缓存版本。
不适用场景:如果项目中模块之间的划分不够清晰或者代码块的定义不够合理,可能会导致一些不必要的文件重新下载。例如,如果两个模块的代码块划分不合理,其中一个模块的修改可能会影响到另一个模块的代码块文件名,从而使另一个模块也需要重新下载。
✧ [contenthash]
适用场景:在对缓存精准控制要求较高的场景下是最佳选择。例如,在处理 CSS 和 JavaScript 文件时,如果希望只有当文件自身内容发生变化时才改变文件名,使用 [contenthash] 可以确保 CSS 和 JavaScript 文件的缓存独立控制,互不影响。当 CSS 文件中的样式发生变化,只有 CSS 文件的文件名会改变,JavaScript 文件不受影响;反之亦然。
不适用场景:在一些需要考虑模块之间关联和整体缓存更新的项目中,可能不太适用。例如,在一个项目中,如果需要确保所有文件在项目有任何改动时都能统一更新缓存,使用 [contenthash] 可能会导致部分文件缓存未更新,从而出现功能异常。
综合考虑:
➢ 如果项目较小且更新频率较高,作为一个整体进行更新,[fullhash] 可能是一个简单有效的选择。
➢ 对于大型项目,尤其是模块划分清晰的项目,[chunkhash] 通常能提供较好的缓存控制效果。
➢ 如果对缓存精准控制有较高要求,特别是在处理不同类型文件(如 CSS 和 JavaScript)的缓存独立控制时,contenthash 是最合适的选择。
chunkFilename
非入口文件输出配置, 例如通过import等方式按需加载的文件打包后会走chunkFilename的配置。
assetModuleFilename
诸如图片、字体等资源的输出命名配置,这些一般属于webpack内置实现,我们可以通过这个配置自定义输出路径和名称。
path
指定文件的输出路径,通常我们使用的是拼接后的绝对路径。
path: path.resolve(__dirname, "dist"),
publicPath
用于指定在浏览器中访问打包文件时的基础路径。
➢ 在开发环境中,如果使用了webpack-dev-server,可能会将publicPath设置为/,表示所有打包文件都可以从根路径访问。
➢ 在生产环境中,如果将文件部署到特定的服务器目录下,可能需要根据实际情况设置publicPath。例如,如果文件部署在服务器的/assets目录下,则publicPath可设置为/assets/。
library和libraryTarget
library指定打包后的库的名称
libraryTarget指定打包后用何种规范(umd/cmd/amd/esm)暴露给外部,其值如下:
devServer
progress
显示编译进度
hot
热模块替换,实现在不重载整个页面的情况下,更新局部改动,热模块替换原理
webpack-dev-serverv4开始默认开启HMR,会自动启用webpack.HotReplacementPlugin
open
告诉 dev-server 在服务器已经启动后打开浏览器。设置其为 true 以打开你的默认浏览器、
devServer: {
open: true,
},
还可以配置打开一个或多个指定页面
devServer: {
open: ['/my-page', '/another-page'],
},
还可以指定用哪个浏览器打开
open: {
app: {
name: 'google-chrome',
},
},
port
指定监听请求端口,也可以自动让其启用一个端口
devServer: {
port: 'auto',
},
proxy
通常用于配置前端代理,常用配置如下:
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: { '^/api': '' },
secure: false // 默认情况下,将不接受在 HTTPS 上运行且证书无效的后端服务器。 如果需要覆盖,可以这样修改配置
},
},
常见处理文件的loader
常见的比如:style-loader、css-loader、less-loader、sass-loader、stylus-loader 等,包括处理图片的file-loader,只是file-loader是webpack已实现内置的。 另外style-loade实际开发中基本不会使用,将样式通过生成style标签,以字符串的形式嵌入的方式会使得文件本身体积太大,一般会使用MiniCssExtractPlugin插件代替,高级篇中有讲到,该插件会将css单独处理出来。
sass和styl可以实现css样式的简写,尤其是styl语法更为简单,感兴趣的可以深入研究一下
其它常用的loader如下:
webpack已将处理图片资源的loader默认集成了,一般来说有inline和resource两种模式,默认情况下webpack 会自动在 resource 和 inline 之间进行选择:小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。通过inline配置webpack将 会输出的 data URI类型,默认是呈现为使用 Base64 算法编码的文件内容。
配置基本同上,只是字体我们不希望是dataURI的形式,因此需要手动配置type为asset/resouce
plugins
《Webpack配置指南-从基础到高阶专栏-高阶优化篇》有所涉及,后续还会出Plugins篇,专门整理常见的各类plugins配置及作用。
sourcemap配置
包含源代码和构建后代码的行列映射关系,方便错误追踪。 devtool的类型官网列的非常多,感兴趣的可以深入研究下每种的区别和差异,本文只总结了分别用于开发和生产模式的两种最佳配置。
- 开发模式 cheap-module-source-map
优点:只包含行映射,编译速度快
缺点:没有列映射
mode: "development",
devtool: "cheap-module-source-map",
- 生产模式 source-map
优点:包含行/列映射
缺点:编译速度慢
resolve
在 Webpack 中,resolve配置项主要用于指定如何解析模块路径,主要配置及作用如下:
模块路径解析规则:
-
可以定义模块的查找路径规则,让 Webpack 能够准确地找到项目中引入的各种模块。例如,可以指定在哪些目录下查找 JavaScript 模块、CSS 文件、图片等资源。
-
通过设置extensions属性,可以指定在引入模块时可以省略的文件扩展名。例如,如果设置extensions: ['.js', '.jsx', '.ts'],那么在引入模块时,如果没有指定文件扩展名,Webpack 会依次尝试这些扩展名来查找模块。
别名配置:
- 使用alias属性可以为模块路径设置别名。这在项目中模块路径较长或者需要统一管理模块路径时非常有用。例如,可以设置alias: { '@components': path.resolve(__dirname, 'src/components') },这样在项目中就可以使用@components/MyComponent来代替相对较长的路径src/components/MyComponent
优化模块查找性能:
合理的resolve配置可以减少 Webpack 在查找模块时的时间消耗,提高构建速度。特别是在大型项目中,明确模块的查找路径和设置别名可以避免不必要的文件系统遍历,比如设置resolve的modules可以指定查找目录。
const path = require('path');
module.exports = {
//...其他配置项
resolve: {
// 可以省略的文件扩展名
extensions: ['.js', '.jsx', '.ts', '.tsx', '.css', '.scss', '.png', '.jpg', '.jpeg', '.gif'],
// 设置别名
alias: {
'@styles': path.resolve(__dirname, 'src/styles'),
'@components': path.resolve(__dirname, 'src/components'),
},
// 指定模块查找的目录,这里优先在项目的 node_modules 目录查找模块
modules: [path.resolve(__dirname, 'node_modules')],
},
};
stats
自定义打包日志的输出,感兴趣的可以自己研究一下:stats
optimization
《Webpack配置指南-从基础到高阶专栏-高阶优化篇》有所涉及,包括代码分割及JS、Css压缩等。
mode
有 production 、 development 和 none三种类型,可通过webpack配置文件或者配置脚本通过CLI配置:--mode=development
其它专栏文章推荐:
《手撕源码系列专栏》文章
《重学JavaScript专栏》相关文章推荐: