《Webpack 配置指南:从基础到高阶专栏》- 基础篇

440 阅读10分钟

前言: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的配置在新版中已被标记过时:

image.png

✧ [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的配置。

image.png

assetModuleFilename

诸如图片、字体等资源的输出命名配置,这些一般属于webpack内置实现,我们可以通过这个配置自定义输出路径和名称。

image.png

image.png

path

指定文件的输出路径,通常我们使用的是拼接后的绝对路径。

path: path.resolve(__dirname, "dist"),

publicPath

用于指定在浏览器中访问打包文件时的基础路径。

➢ 在开发环境中,如果使用了webpack-dev-server,可能会将publicPath设置为/,表示所有打包文件都可以从根路径访问。

➢ 在生产环境中,如果将文件部署到特定的服务器目录下,可能需要根据实际情况设置publicPath。例如,如果文件部署在服务器的/assets目录下,则publicPath可设置为/assets/。

library和libraryTarget

library指定打包后的库的名称

libraryTarget指定打包后用何种规范(umd/cmd/amd/esm)暴露给外部,其值如下:

image.png

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单独处理出来。

image.png sass和styl可以实现css样式的简写,尤其是styl语法更为简单,感兴趣的可以深入研究一下

image.png 其它常用的loader如下:

webpack已将处理图片资源的loader默认集成了,一般来说有inlineresource两种模式,默认情况下webpack 会自动在 resource 和 inline 之间进行选择:小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。通过inline配置webpack将 会输出的 data URI类型,默认是呈现为使用 Base64 算法编码的文件内容。

image.png

配置基本同上,只是字体我们不希望是dataURI的形式,因此需要手动配置type为asset/resouce

image.png

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

productiondevelopmentnone三种类型,可通过webpack配置文件或者配置脚本通过CLI配置:--mode=development

项目源码目前完整版配置(逐步整理中)参见

其它专栏文章推荐:

《手撕源码系列专栏》文章

《重学JavaScript专栏》相关文章推荐: