diff --git a/website/docs/en/plugins/ignore-plugin.mdx b/website/docs/en/plugins/ignore-plugin.mdx index 69df51a760f0..1f5fd471707c 100644 --- a/website/docs/en/plugins/ignore-plugin.mdx +++ b/website/docs/en/plugins/ignore-plugin.mdx @@ -1,45 +1,147 @@ --- -description: 'This plugin will prevent the generation of modules for import or require calls matching the regular expressions' +description: 'Ignore selected imports so their modules are not resolved or included in the bundle.' --- # IgnorePlugin -This plugin will prevent the generation of modules for `import` or `require` calls matching the regular expressions. +This plugin ignores selected module references, so files referenced by matching `import` or `require` statements are not included in the bundle. + +## How it works + +Rspack examines each module reference before resolution. For a direct `import` or `require`, it checks the unresolved module specifier. For a dynamic lookup such as `require('./locale/' + name)`, it checks the context path extracted from the expression. Rspack ignores the module reference when the configured regular expression matches this value or the filter function returns `true`. Other module references are resolved and bundled normally. + +`IgnorePlugin` does not replace an ignored module with an empty module. Instead, Rspack skips resolving it and does not generate the corresponding module. If the bundle executes the code generated for the matching `import` or `require`, that code throws an error whose `code` is `MODULE_NOT_FOUND` at runtime. Before using the plugin, make sure this code will not run in the target environment, or that the referencing code already handles a missing module. + +Use [`resourceRegExp`](#resourceregexp) or [`checkResource`](#checkresource) to select module references to ignore. To limit a regular-expression rule by the referencing module's directory, combine [`contextRegExp`](#contextregexp) with [`resourceRegExp`](#resourceregexp). + +## Common use cases + +Use `IgnorePlugin` only when omitting the referenced module is safe. Common cases include: + +- Removing groups of resources that a library discovers dynamically, such as Moment.js locale modules that the application does not use. +- Excluding optional or environment-specific modules when their code path will not run, or when the referencing code handles a missing module. +- Restricting an ignore rule to references from a particular package or directory, so the same module specifier can still resolve elsewhere. ## Examples -When using the following configuration: +### Ignore a specific import + +The following configuration ignores every module reference whose unresolved module specifier is exactly `./optional-feature`, regardless of the referencing module's directory: ```js title="rspack.config.mjs" import { rspack } from '@rspack/core'; export default { + entry: './src/index.js', plugins: [ new rspack.IgnorePlugin({ - resourceRegExp: /^\.\/locale$/, - contextRegExp: /moment$/, + resourceRegExp: /^\.\/optional-feature$/, }), ], }; ``` -which means any require statement matching './locale' from any directories ending with 'moment' will be ignored. +For example, the entry contains this static import: + +```js title="src/index.js" +import './optional-feature'; +``` + +Because `contextRegExp` is omitted, the rule applies to module references from every directory. Other module specifiers are resolved normally. + +Rspack does not generate a module for `./optional-feature` or replace it with an empty module. The generated JavaScript does not retain the original `import` syntax. Instead, Rspack emits a missing-module expression at the corresponding position. When the entry evaluates this expression, it throws an error whose `code` is `MODULE_NOT_FOUND`: + +```js title="dist/main.js (simplified)" +Object( + (function __rspack_missing_module() { + const error = new Error("Cannot find module './optional-feature'"); + error.code = 'MODULE_NOT_FOUND'; + throw error; + })(), +); +``` + +This example deliberately demonstrates the runtime failure caused by executing an ignored static import. + +### Ignore Moment.js locales + +Moment.js loads locales dynamically with `require('./locale/' + name)`. Rspack extracts `./locale` as the context path for this expression. To ignore the lookup only when the referencing module is in a directory ending in `moment`, configure both `resourceRegExp` and `contextRegExp`: + +```js +new rspack.IgnorePlugin({ + resourceRegExp: /^\.\/locale$/, + contextRegExp: /moment$/, +}); +``` + +The entry can import Moment.js normally: + +```js title="src/index.js" +import moment from 'moment'; + +console.log(moment().format()); +``` + +Rspack tests `resourceRegExp` against the extracted context path `./locale`, not the resolved path `moment/locale`. Because both regular expressions match, the emitted bundle keeps Moment.js itself but contains no modules from `moment/locale`: + +```js title="dist/main.js (simplified)" +// Moment.js core is included in the bundle. +// No moment/locale/*.js modules are included. +``` ## Options -- **Type:** +### resourceRegExp + +- **Type:** `RegExp` +- **Default:** `undefined` + +Rspack tests `resourceRegExp` before resolution. For a direct module reference, the tested value is the unresolved module specifier. For a dynamic module lookup, it is the context path extracted from the expression. For example, `import './optional-feature'` is tested as `./optional-feature`, while `require('./locale/' + name)` is tested as `./locale`. Neither value is a resolved absolute path. -```ts -| { - /** A RegExp to test the resource against. */ - resourceRegExp: RegExp; - /** A RegExp to test the context (directory) against. */ - contextRegExp?: RegExp; - } -| { - /** A Filter function that receives `resource` and `context` as arguments, must return boolean. */ - checkResource: (resource: string, context: string) => boolean; - } +When the expression matches and `contextRegExp` is omitted, Rspack does not generate the referenced module, regardless of the referencing module's directory. When `contextRegExp` is set, both expressions must match. If `resourceRegExp` is omitted, provide `checkResource`; omitting both is not valid according to the public options type. + +```js +new rspack.IgnorePlugin({ + resourceRegExp: /^\.\/optional-feature$/, +}); ``` +### contextRegExp + +- **Type:** `RegExp` - **Default:** `undefined` + +Tests the referencing module's directory (`context`), normally an absolute path. Rspack evaluates this expression only after `resourceRegExp` matches, and skips module generation only when both expressions match. + +If omitted, a `resourceRegExp` match applies regardless of the referencing module's directory. `contextRegExp` has no effect without `resourceRegExp`; use the `context` parameter of `checkResource` when using the function form. + +```js +new rspack.IgnorePlugin({ + resourceRegExp: /^\.\/optional-feature$/, + contextRegExp: /[/\\]legacy$/, +}); +``` + +### checkResource + +- **Type:** + + ```ts + (resource: string, context: string) => boolean; + ``` + +- **Default:** `undefined` + +Runs before Rspack resolves each module reference. `resource` is the same value tested by `resourceRegExp`: the unresolved module specifier for a direct reference, or the extracted context path for a dynamic lookup. `context` is the referencing module's directory. Return `true` to stop resolution and module generation. Return `false` to continue processing. + +This is the function-based alternative to `resourceRegExp` and `contextRegExp`. If it is omitted, provide `resourceRegExp`. To restrict a function match by the referencing module's directory, test `context` inside the function. + +Rspack evaluates `checkResource` before the regular expression options. If both forms are supplied, returning `true` takes priority and stops resolution and module generation immediately. Returning `false` lets Rspack evaluate `resourceRegExp` and `contextRegExp` next. Normal resolution continues only when neither form ignores the module reference. + +```js +new rspack.IgnorePlugin({ + checkResource(resource, context) { + return resource === './optional-feature' && /[/\\]legacy$/.test(context); + }, +}); +``` diff --git a/website/docs/zh/plugins/ignore-plugin.mdx b/website/docs/zh/plugins/ignore-plugin.mdx index 4eb606cadb9c..a189cfcec49c 100644 --- a/website/docs/zh/plugins/ignore-plugin.mdx +++ b/website/docs/zh/plugins/ignore-plugin.mdx @@ -1,45 +1,147 @@ --- -description: "这意味着,在以 'moment' 结尾的目录下,如果导入语句匹配 './locale' ,那么这个 './locale' 资源不会被打包。" +description: '忽略指定的导入,使对应模块不进入构建产物。' --- # IgnorePlugin 此插件将会忽略指定的导入文件,让这些 `import` 或 `require` 包含的文件不被打包。 +## 工作原理 + +Rspack 会在解析前检查每一处模块引用。对于直接的 `import` 或 `require`,参与匹配的是尚未解析的模块标识符;对于 `require('./locale/' + name)` 等动态模块查找,参与匹配的是从表达式中提取的上下文路径。当配置的正则表达式匹配该值,或过滤函数返回 `true` 时,Rspack 会忽略该模块引用,不再生成对应模块。其他模块引用仍会正常解析并打包。 + +`IgnorePlugin` 不会将被忽略的模块替换为空模块。Rspack 会跳过对该模块的解析,也不会生成对应模块。如果构建产物执行到匹配的 `import` 或 `require` 所生成的代码,这段代码会在运行时抛出一个 `code` 为 `MODULE_NOT_FOUND` 的错误。使用插件前,应确保相关代码不会在目标环境中执行,或引用方代码已经处理了模块不存在的情况。 + +使用 [`resourceRegExp`](#resourceregexp) 或 [`checkResource`](#checkresource) 选择要忽略的模块引用。若要根据引用方模块所在的目录限定正则表达式的匹配范围,请将 [`contextRegExp`](#contextregexp) 与 [`resourceRegExp`](#resourceregexp) 组合使用。 + +## 常见使用场景 + +只有在省略被引用模块不会影响正常运行时,才应使用 `IgnorePlugin`。常见场景包括: + +- 排除第三方库动态查找、但当前应用并不需要的一组资源,例如未使用的 Moment.js 语言包。 +- 排除可选模块或仅在特定运行环境中使用的模块,前提是相关代码路径不会执行,或引用方代码已经处理模块不存在的情况。 +- 将忽略规则限定在特定包或目录,使其他位置使用相同模块标识符时仍可正常解析。 + ## 示例 -当使用以下配置时: +### 忽略指定导入 + +以下配置会忽略所有在解析前模块标识符恰好为 `./optional-feature` 的模块引用,不限制引用方模块所在的目录: ```js title="rspack.config.mjs" import { rspack } from '@rspack/core'; export default { + entry: './src/index.js', plugins: [ new rspack.IgnorePlugin({ - resourceRegExp: /^\.\/locale$/, - contextRegExp: /moment$/, + resourceRegExp: /^\.\/optional-feature$/, }), ], }; ``` -这意味着,在以 'moment' 结尾的目录下,如果导入语句匹配 './locale' ,那么这个 './locale' 资源不会被打包。 +例如,入口文件中包含一个与规则匹配的静态导入: + +```js title="src/index.js" +import './optional-feature'; +``` + +由于省略了 `contextRegExp`,这条规则会对所有目录中的模块引用生效,其他模块标识符仍会正常解析。 + +Rspack 不会为 `./optional-feature` 生成模块,也不会将它替换为空模块。生成的 JavaScript 不会保留原始的 `import` 语法,而是在对应位置生成一个缺失模块表达式。入口执行到该表达式时,会抛出一个 `code` 为 `MODULE_NOT_FOUND` 的错误: + +```js title="dist/main.js(简化)" +Object( + (function __rspack_missing_module() { + const error = new Error("Cannot find module './optional-feature'"); + error.code = 'MODULE_NOT_FOUND'; + throw error; + })(), +); +``` + +此示例特意展示执行被忽略的静态导入时产生的运行时错误。 + +### 忽略 Moment.js 语言包 + +Moment.js 通过 `require('./locale/' + name)` 动态加载语言包。Rspack 会从该表达式中提取 `./locale` 作为上下文路径。若只想在引用方模块位于路径以 `moment` 结尾的目录时忽略这项动态查找,需要同时配置 `resourceRegExp` 和 `contextRegExp`: + +```js +new rspack.IgnorePlugin({ + resourceRegExp: /^\.\/locale$/, + contextRegExp: /moment$/, +}); +``` + +入口文件可以正常导入 Moment.js: + +```js title="src/index.js" +import moment from 'moment'; + +console.log(moment().format()); +``` + +Rspack 会使用提取出的上下文路径 `./locale` 匹配 `resourceRegExp`,而不是使用解析后的路径 `moment/locale`。两个正则表达式均匹配,因此构建产物会保留 Moment.js 本身,但不会包含 `moment/locale` 中的模块: + +```js title="dist/main.js(简化)" +// 构建产物中包含 Moment.js 核心代码。 +// 构建产物中不包含 moment/locale/*.js 模块。 +``` ## 选项 -- **类型:** +### resourceRegExp + +- **类型:** `RegExp` +- **默认值:** `undefined` + +Rspack 会在解析前使用 `resourceRegExp` 进行匹配。对于直接模块引用,参与匹配的是尚未解析的模块标识符;对于动态模块查找,参与匹配的是从表达式中提取的上下文路径。例如,`import './optional-feature'` 会以 `./optional-feature` 参与匹配,而 `require('./locale/' + name)` 会以 `./locale` 参与匹配,两者都不会使用解析后的绝对路径。 -```ts -| { - /** 用于匹配资源文件 */ - resourceRegExp: RegExp; - /** 用于匹配请求的目录 */ - contextRegExp?: RegExp; - } -| { - /** 根据资源和请求的目录进行过滤 */ - checkResource: (resource: string, context: string) => boolean; - } +正则表达式匹配且未配置 `contextRegExp` 时,Rspack 不会生成被引用的模块,也不限制引用方模块所在的目录。配置 `contextRegExp` 后,两个正则表达式必须同时匹配。如果省略 `resourceRegExp`,则必须提供 `checkResource`;按照公开选项类型,两者不能同时省略。 + +```js +new rspack.IgnorePlugin({ + resourceRegExp: /^\.\/optional-feature$/, +}); ``` +### contextRegExp + +- **类型:** `RegExp` - **默认值:** `undefined` + +用于匹配引用方模块所在的目录(`context`),该值通常是绝对路径。Rspack 仅在 `resourceRegExp` 匹配后才检查此正则表达式,两个正则表达式同时匹配时才会停止生成对应模块。 + +省略此选项时,`resourceRegExp` 的匹配结果不受引用方模块所在目录的限制。`contextRegExp` 不能脱离 `resourceRegExp` 单独生效;使用函数形式时,应在 `checkResource` 中检查 `context` 参数。 + +```js +new rspack.IgnorePlugin({ + resourceRegExp: /^\.\/optional-feature$/, + contextRegExp: /[/\\]legacy$/, +}); +``` + +### checkResource + +- **类型:** + + ```ts + (resource: string, context: string) => boolean; + ``` + +- **默认值:** `undefined` + +Rspack 会在解析每一处模块引用前调用此函数。`resource` 与 `resourceRegExp` 的匹配值相同:对于直接模块引用,它是尚未解析的模块标识符;对于动态模块查找,它是提取出的上下文路径。`context` 是引用方模块所在的目录。返回 `true` 时停止解析且不生成对应模块;返回 `false` 时继续处理。 + +这是 `resourceRegExp` 和 `contextRegExp` 的函数形式替代方案。如果省略此选项,则必须提供 `resourceRegExp`。需要按目录限制函数的匹配范围时,请在函数内部检查 `context`。 + +Rspack 会先执行 `checkResource`,再检查正则表达式选项。如果同时提供两种形式,返回 `true` 的结果优先,会立即停止解析且不生成对应模块;返回 `false` 后,Rspack 会继续检查 `resourceRegExp` 和 `contextRegExp`。只有两种形式都未忽略该模块引用时,Rspack 才会继续执行常规解析。 + +```js +new rspack.IgnorePlugin({ + checkResource(resource, context) { + return resource === './optional-feature' && /[/\\]legacy$/.test(context); + }, +}); +```