Skip to main content

webpack5 配置项(一)

target

指定 webpack 构建环境,如果项目集成了browserslist,则默认值为browserslist,否则为web

entry

entry的配置主要分为以下几种:

string | string[]

如果entry指定为一个具体的文件路径字符串或者一个字符串数组,则 webpack 会从解析这个模块开始构建依赖树,生成单独的 chunk 并命名为main。对于 SPA 应用来说一般采取这种配置。

object

如果是一个对象,则属性名为 chunk 的名称,属性值则为 chunk 打包入口,常用来构建多页应用。

dependOn

对象属性dependOn指定在多个 chunk 之间共享的相同的 chunk 名称,例如多个入口共享reactreact-dom这些库,则可以通过以下配置将reactreact-dom抽离到一个单独的 chunk 中,然后其他入口的模块通过dependOn共享这个 chunk,避免多个入口打包时需要构建相同的依赖模块。

  entry: {
home: './home.js',
shared: ['react', 'react-dom', 'redux', 'react-redux'],
catalog: {
import: './catalog.js',
filename: 'pages/catalog.js',
dependOn: 'shared',
},
personal: {
import: './personal.js',
filename: 'pages/personal.js',
dependOn: 'shared',
},
},

import

import指定 chunk 包含的模块,可以是单个字符串路径,或者一个字符串数组。

filename

webpack 默认从output.filename生成入口 chunk 的名称,不过也可以在entry中通过指定单独的filename

output

output的配置项相当复杂,不过一般常用的是以下几项:

path

生产环境打包输出文件夹,需要指定一个绝对路径,所以一般需要用到path.resolve来构建这个路径

  output: {
path: path.resolve(__dirname, 'dist'),
}

filename

如果指定filename为单个的字符串,并且entry是单个入口,那么就对应单个 bundle js

但是鉴于大部分情况下都会使用 code-splitting 的模式,则需要使用以下可替换模板字符串模式来为每个 chunk 指定特定的文件名称

  output: {
filename: "static/js/[name].[contenthash:8].js",
}

其中name表示多个entry指定的 chunk 名称,或者通过 SplitChunksPlugin 拆分的多个 chunk 的名称;而contenthash则对应 chunk 打包的资源内容生成的 hash 值,有利于 web 持久化缓存资源请求。

chunkFilename

chunkFilename用于指定按需加载的 chunk 的名称,webpack 支持使用动态导入import()的语法,这些异步加载的模块都会被使用chunkFilename创建为单独的 chunk.

  output: {
chunkFilename: "static/js/[name].[contenthash:8].chunk.js",
}

clean

是否生成输出文件之前清空path目录,可以干掉CleanWebpackPlugin 了。

compareBeforeEmit

告知 webpack 在写入到输出文件系统时检查输出的文件是否已经存在并且拥有相同内容

assetModuleFilename✨

assetModuleFilename属于 webpack5 新增的关于输出非jsjson资源的文件名名称,例如图片,视频等静态资源。

 output: {
assetModuleFilename: 'static/media/[name].[hash][ext]'
}

module

静态资源处理

webpack5 其中一个更新是内置了对部分非jsjson资源模块的处理,来替代过去需要配置的loader。在 webpack5 中定义的资源类型rules.type有以下几种值:

  • asset/resource:发送单独的文件请求并导出 URL,可以替换file-loader
  • asset/inline:将某些资源转换成 Base64 编码的 data URL,从而减少 HTTP 请求,可以替换之前的url-loader
  • asset/source:导出资源的源代码,可替换raw-loader
  • asset:在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现,这个需要配合parser.dataUrlCondition来使用。

其他模块类型还有:

  • javascript/auto:支持所有模块导入语法:CommonJS、AMD、ESM 等

  • javascript/esm:只支持 ESM 语法

  • javascript/dynamic:仅支持 CommonJS 和 AMD 模块语法,ESM 不可用

  • json:可通过 requireimport 导入 .json格式的数据

  • webassembly/syncwebassembly/async:支持使用 ESM 导入 WASM 模块,例如

import init from './example.wasm'

init().then((exports) => {
exports.test()
})

rules.parser

如果 rules.type 的值为 asset,那么 rules.parser 选项可能是一个对象或一个函数,其作用是配合parser.dataUrlCondition来指定文件大小阈值来将文件内容编码为 Base64,还是将其当做单独文件 emit 到输出目录。例如处理图片资源可以使用以下配置:

module: {
rules: {
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 1024 * 4, // 4KB
},
},
},
}
}

如果 rules.type 被设置成 'json',那么 rules.parser.parse 选择可能会是一个方法,该方法实现自定义的逻辑,以解析模块的源和并将它转换成 JavaScript 对象。 它可能在没有特定加载器的时候,对将 toml, yaml 和其它非 JSON 文件导入成导入非常有用:

module.exports = {
//...
module: {
rules: [
{
test: /\.toml/,
type: 'json',
parser: {
parse: toml.parse,
},
},
],
},
};

rules.issuer

指定当前模块关联的模块的匹配规则,例如处理 react 中引入的.svg模块的时候,同时需要匹配到 react 模块类型才会应用该规则,这样在 CSS 文件中通过url引入的.svg文件就不会受到影响。

module: {
rules: [
{
// allow to import SVG as React components.
test: /\.svg$/,
use: [
{
loader: '@svgr/webpack',
},
],
// 关联模块类型
issuer: {
and: [/\.(ts|tsx|js|jsx|md|mdx)$/],
},
},
]
}

rules.resourceQuery

resourceQuery用来处理模块路径中查询字符串部分,例如import svg from './assets/file.svg?url',例如svg的情况,在 React 中,svg 一般可以作为图标组件单独使用,同时也可以传给imgsrc属性,作为url,配置如下:

  module: {
rules: [
{
type: 'asset',
resourceQuery: /url/, // *.svg?url
},
{
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ['@svgr/webpack'],
},
],
},
import svg from './assets/file.svg?url'
import Svg from './assets/file.svg'

const App = () => {
return (
<div>
<img src={svg} width="200" height="200" />
<Svg width="200" height="200" viewBox="0 0 3500 3500" />
</div>
)
}

noParse

指定一个 RegExp,让 webpack 忽略该模式匹配的模块的构建,例如lodashjquery等。可以提升构建性能。

  module: {
noParse: /jquery|lodash/,
},

cache✨

webpack5 集成了缓存模块和 chunk 的配置,并且开发模式默认开启,从而提升构建速度。

tip

cache:truecache: { type: 'memory' }效果相同,都是指定 webpack 仅在构建期间使用内存存储缓存,可以加快热更新的速度,但是重启 WDS 仍然很慢。可以使用以下配置项

maxGenerations

定义内存缓存中未使用的缓存项的生命周期。

  • maxGenerations: 1:在一次编译中未使用的缓存被删除
  • maxGenerations: Infinity:缓存将永远保存
tip

设置cache: { type: 'filesystem' }则会指定 webpack 将缓存内容存储到硬盘,从而在二次构建中提速,可以使用以下额外配置项

buildDependencies

指定 webpack 缓存失效的策略,推荐是指定config: [__filename],在 webpack 配置或者 webpack 依赖的模块版本发生改变时重建缓存内容。

  cache: {
buildDependencies: {
defaultWebpack: ['webpack/lib/'],
config: [__filename],
}
}

webpack 默认使用'webpack/lib/'查找依赖项版本

cacheDirectory

指定缓存目录,默认是node_modules/.cache/webpack

name

指定缓存的名称

store

指定 webpack 什么时候将数据存放在文件系统中,只支持一个字符串值pack,含义是当编译器闲置时候,将缓存数据都存放在一个文件中。

maxAge

缓存的过期时间,毫秒为单位,默认是一个月时间。

maxMemoryGenerations

定义在文件系统中未使用的缓存项的生命周期,开发模式下默认是10,生产模式则是Infinity

  • maxMemoryGenerations: 0:将项目缓存到内存中,直到它们被序列化到磁盘。一旦序列化,下一次读取将再次从磁盘反序列化它们。这种模式将最小化内存使用,但会带来性能成本。
  • maxMemoryGenerations: 1:从内存缓存中清除已序列化且在至少一次编译中未使用的项。当再次使用它们时,它们将从磁盘反序列化。这种模式将最小化内存使用量,同时仍将活动项保留在内存缓存中。

version

设置缓存的版本,更新缓存的版本,可以让缓存失效。