# Source: https://rspack.dev/config/module-rules.md

CC 4.0 License> The content of this section is derived from the content of the following links and is subject to the CC BY 4.0 license.
> 
> - [https://webpack.docschina.org/configuration/module/](https://webpack.docschina.org/configuration/module/)
> 
> The following contents can be assumed to be the result of modifications and deletions based on the original contents if not specifically stated.
> 
> 


# Module Rules

- **Type:** `(Rule | Falsy)[]`
- **Default:** `[]`

`module.rules` defines how Rspack processes different types of modules during the build.

It is an array of rules. Each rule is matched against a module's metadata when the module is resolved and created, such as its file path, file type, or query parameters. Once a rule matches, Rspack transforms or resolves the module according to the rule's configuration.

The most common use case is configuring [loaders](/guide/features/loader.md) for different kinds of modules. For example, transforming TypeScript into browser-executable JavaScript, or handling stylesheets, images, and other assets.

By combining various matching conditions with specific processing logic, `module.rules` provides fine-grained control over how different modules are built.

For example, use the [built-in swc-loader](/guide/features/builtin-swc-loader.md) to handle files ending with `.ts`:

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'builtin:swc-loader',
        options: {
          // loader options...
        },
      },
    ],
  },
};
```

## Concepts

### Rule

- **Type:** `Rule`
- **Default:** `{}`

Rule defines the conditions for matching a module and the behavior of handling those modules.

**Rule behavior**

Defines the processing behavior of the corresponding matching module, e.g. :

- Apply the list of Loader to these modules (`rules[].use`)
- Apply the module's type (`rules[].type`)
- Apply the module's resolve configuration (`rules[].resolve`)

### Condition

- **Type:**

```ts
type Condition =
  | string
  | RegExp
  | ((value: string) => boolean)
  | Conditions
  | LogicalConditions;

type Conditions = Condition[];

type LogicalConditions = {
  and?: Conditions;
  or?: Conditions;
  not?: Condition;
};
```

Defines a module's match conditions, common matches are [resource](#rulesresource), [resourceQuery](#rulesresourcequery), [include](#rulesinclude), and [exclude](#rulesexclude).

Example: app.js imports `./image.png?inline#foo`:

- `resource` is `/path/to/image.png`, and will match against with [rules\[\].resource](#rulesresource) Condition
- `resourceQuery` is `?inline`, and will match against with [rules\[\].resourceQuery](#rulesresourcequery) Condition
- `resourceFragment` is `#foo`, and will match against with [rules\[\].resourceFragment](#rulesresourcefragment) Condition

Condition represents the form of matching a given input, and it supports the following types:

- `String`: Given an input, the match is successful when the input string satisfies startsWith. Note: You can think of it as `input.startsWith(condition)`.
- `RegExp`: Given an input, the match is successful when the input string satisfies the regular expression. Note: You can think of it as `condition.test(input)`.
- `Condition[]`: A list of conditions. At least one of the Conditions must match.
- `LogicalConditions`: All Conditions must match.
  - `{ and: Condition[] }`: All Conditions must match.
  - `{ or: Condition[] }`: At least one of the Conditions must match.
  - `{ not: Condition }`: All Conditions must NOT match.
- `(value: string) => boolean`: If it's called with the input and return a truthy value, the match is succeeds.

### Nested rule

Nested Rule can be specified under the properties [`rules[].rules`](#rulesrules) and [`rules[].oneOf`](#rulesoneof), These rules are evaluated only when the parent Rule condition matches. Each nested rule can contain its own conditions.

The order of evaluation is as follows:

1. The parent Rule
2. [`rules[].rules`](#rulesrules)
3. [`rules[].oneOf`](#rulesoneof)

## rules\[].exclude

- **Type:** [`Condition`](#condition)
- **Default:** `undefined`

Excludes all modules that match this condition and will match against the absolute path of the resource (without query and fragment). This option cannot be present together with `rules[].resource`.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        exclude: /\.js$/,
      },
    ],
  },
};
```

## rules\[].include

- **Type:** [`Condition`](#condition)
- **Default:** `undefined`

Matches all modules that match this condition against the absolute path of the resource (without query and fragment). This option cannot be present together with `rules[].resource`.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        include: /\.js$/,
      },
    ],
  },
};
```

## rules\[].resource

- **Type:** [`Condition`](#condition)
- **Default:** `undefined`

Matches all modules that match this resource, and will match against Resource (the absolute path without query and fragment). This option cannot be present together with `rules[].test`.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        resource: /\.js$/,
      },
    ],
  },
};
```

## rules\[].resourceQuery

- **Type:** [`Condition`](#condition)
- **Default:** `undefined`

Matches all modules that match this resource against the Resource's query. Note: Containing `?`, when `rules[].resourceQuery` is `?raw`, it will match the resource request of `foo?raw`

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.css$/,
        resourceQuery: /inline/,
        type: 'asset/inline',
      },
    ],
  },
};
```

## rules\[].resourceFragment

- **Type:** [`Condition`](#condition)
- **Default:** `undefined`

Matches all modules that match this resource against the Resource's fragment. Note: Containing `#`, when `rules[].resourceFragment` is `#abc`, it will match the resource request of `foo#abc`

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        resourceFragment: '#abc',
      },
    ],
  },
};
```

## rules\[].test

- **Type:** [`Condition`](#condition)
- **Default:** `undefined`

Matches all modules that match this resource, and will match against Resource (the absolute path without query and fragment). This option cannot be present together with `rules[].resource`.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
      },
    ],
  },
};
```

## rules\[].issuer

- **Type:** [`Condition`](#condition)
- **Default:** `undefined`

Matches all modules that match this resource, and will match against Resource (the absolute path without query and fragment) of the module that issued the current module.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        issuer: /\.js$/,
      },
    ],
  },
};
```

## rules\[].issuerLayer

[Added in v1.0.0-beta.1](https://github.com/web-infra-dev/rspack/releases/tag/v1.0.0-beta.1)
- **Type:** `string`
- **Default:** `undefined`

Matches all modules that match this resource, and will match against layer of the module that issued the current module.

For more information about layers, see the [Layer guide](/guide/features/layer.md).

A basic example:

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        issuerLayer: 'other-layer',
      },
    ],
  },
};
```

A more complex example is the combination with [entry options](/config/entry.md#entrydescriptionlayer) to build modern and legacy bundles at the same time:

```js title="rspack.config.mjs"
export default {
  entry: {
    index: {
      import: './src/index.js',
      layer: 'modern',
    },
    'index-legacy': {
      import: './src/index.js',
      layer: 'legacy',
    },
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        issuerLayer: 'modern',
        options: {
          env: { targets: ['chrome >= 100'] },
        },
      },
      {
        test: /\.js$/,
        issuerLayer: 'legacy',
        options: {
          env: { targets: ['ie >= 11'] },
        },
      },
    ],
  },
};
```

## rules\[].dependency

- **Type:** [`Condition`](#condition)
- **Default:** `undefined`

Matches all modules that match this resource, and will match against the category of the dependency that introduced the current module, for example:

- `esm` for `import` and `import()`
- `cjs` for `require()`
- `url` for `new URL()` and `url()`.

For example, match all `.js` files, but exclude `url` type dependencies (such as `new URL('./path/to/foo.js', import.meta.url)`):

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        dependency: { not: 'url' },
      },
    ],
  },
};
```

## rules\[].scheme

- **Type:** [`Condition`](#condition)
- **Default:** `undefined`

Matches all modules that match this resource, and will match against the Resource's scheme.

For example, you can treat the inline data uri resource as a separate resource with the following configuration:

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        scheme: 'data',
        type: 'asset/resource',
      },
    ],
  },
};
```

## rules\[].mimetype

- **Type:** [`Condition`](#condition)
- **Default:** `undefined`

Matches modules based on [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types) instead of file extension. It's primarily useful for [data URI module](/api/runtime-api/module-methods.md#data-uri-module).

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        mimetype: 'text/javascript',
        use: [
          // ...
        ],
      },
    ],
  },
};
```

## rules\[].descriptionData

- **Type:** `{ [key: string]: Condition }`
- **Default:** `undefined`

`descriptionData` option allows you to match values of properties in the description file, typically `package.json`, to determine which modules a rule should apply to. This is a useful way to apply rules to specific modules based on metadata found in their `package.json`.

The object keys in `descriptionData` correspond to keys in the module's `package.json`, such as `name`, `version`, etc. Each key should be associated with a [`Condition`](#condition) for matching the `package.json` data.

For example, below we are applying the rule only to JavaScript resources with `'rspack'` string included in their `package.json` `name`.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        include: /node_modules/,
        descriptionData: {
          name: (packageJsonName) => packageJsonName.includes('rspack'),
        },
        // additional rule options...
      },
    ],
  },
};
```

## rules\[].with

[Added in v1.0.0-beta.1](https://github.com/web-infra-dev/rspack/releases/tag/v1.0.0-beta.1)
- **Type:** `{ [key: string]: Condition }`
- **Default:** `undefined`

`with` can be used in conjunction with [import attributes](https://github.com/tc39/proposal-import-attributes).

For example, the following configuration will match `{ type: "url" }` and will change the [`type`](/config/module-rules.md#rulestype) of the matched modules to `"asset/resource"`:

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        with: { type: 'url' },
        type: 'asset/resource',
      },
    ],
  },
};
```

The following import will match:

```ts
import url from './data' with { type: 'url' };
import('./data', { with: { type: 'url' } });
```

It should be noted that in order for Rspack to properly match the `with` syntax, when you use [builtin:swc-loader](/guide/features/builtin-swc-loader.md), you need to manually enable the `keepImportAttributes` configuration to preserve import attributes:

```diff title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        with: { type: 'url' },
        type: 'asset/resource',
      },
      {
        test: /\.ts$/,
        exclude: [/node_modules/],
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            experimental: {
+             keepImportAttributes: true,
            },
            parser: {
              syntax: 'typescript',
            },
          },
        },
        type: 'javascript/auto',
      },
    ],
  },
};
```

## rules\[].loader

`rules[].loader` is a shortcut to `rules[].use: [ { loader } ]`. See [rules\[\].use](/config/module-rules.md#rulesuse) for details.

## rules\[].options

`rules[].options` is a shortcut to `rules[].use: [ { options } ]`. See [rules\[\].use](/config/module-rules.md#rulesuse) for details.

## rules\[].parser

- **Type:** `Object`
- **Default:** `{}`

Parser options for the specific modules that matched by the rule conditions, this will override the parser options in `module.parser`.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.css/,
        parser: {
          namedExports: false,
        },
        type: 'css/module',
      },
    ],
  },
};
```

For specific parser options and the corresponding module type, you can refer to [`module.parser`](/config/module.md#moduleparser).

## rules\[].generator

- **Type:** `Object`
- **Default:** `{}`

Generator options for the specific modules that matched by the rule conditions, this will override the parser options in `module.generator`.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.png/,
        generator: {
          filename: '[contenthash][ext]',
        },
        type: 'asset',
      },
    ],
  },
};
```

For specific generator options and the corresponding module type, you can refer to [`module.generator`](/config/module.md#modulegenerator).

## rules\[].sideEffects

- **Type:** `boolean`

Flag the module for side effects, this will affect the result of [Tree Shaking](/guide/optimization/tree-shaking.md).

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /foo\.js$/,
        sideEffects: false,
      },
    ],
  },
};
```

## rules\[].enforce

- Type: `'pre' | 'post'`


Specifies the category of the loader. When not specified, it defaults to normal loader.

There is also an additional category "inlined loader" which are loaders applied inline of the import/require.

When specified as `'pre'`, the loader will execute before all other loaders.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        enforce: 'pre',
        loader: 'my-pre-loader',
      },
    ],
  },
};
```

When specified as `'post'`, the loader will execute after all other loaders.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        enforce: 'post',
        loader: 'my-post-loader',
      },
    ],
  },
};
```

There are two phases that all loaders enter one after the other:

- **Pitching phase:** the `pitch` method on loaders is called in the order `post, inline, normal, pre`. See [Pitching Loader](/api/loader-api/writing-loaders.md#pitching-loader) for details.
- **Normal phase:** the default method on loaders is executed in the order `pre, normal, inline, post`. Transformation on the source code of a module happens in this phase.

## rules\[].type

- **Type:**

```ts
type RuleType =
  | 'asset'
  | 'css'
  | 'css/auto'
  | 'css/module'
  | 'javascript/auto'
  | 'javascript/dynamic'
  | 'javascript/esm'
  | 'json';
```

Used to mark the type of the matching module, which affects how the module is handled by Rspack's built-in processing.

By default, Rspack will determine the type of the module based on the file extension. For example:

- `.js` files will be treated as `javascript/auto` modules.
- `.mjs` files, as well as `.js` files in packages with `type="module"` in package.json, will be treated as `javascript/esm` modules.
- `.json` files will be treated as `json` modules.
- `.css` files will be treated as `css/auto` modules.

For example, if you want to load a `.json` file through a custom loader, you'd need to set the type to `javascript/auto` to bypass Rspack's built-in JSON importing.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.json$/,
        type: 'javascript/auto',
        loader: 'custom-json-loader',
      },
    ],
  },
};
```

The meanings of all `type` options are as follows:

- `'javascript/auto'`: JavaScript modules. Rspack automatically determines the module type based on file content, providing the best compatibility.
- `'javascript/esm'`: JavaScript modules, treated as strict ES modules.
- `'javascript/dynamic'`: JavaScript modules, treated as Script.
- `'json'`: JSON data module, see [JSON](/guide/tech/json.md).
- `'css' | 'css/module' | 'css/auto'`: CSS module, see [Built-in CSS support](/guide/tech/css.md#built-in-css-support).
- `'asset' | 'asset/source' | 'asset/resource' | 'asset/inline' | 'asset/bytes'`: Asset module, see [Asset Module](/guide/features/asset-module.md).

## rules\[].layer

[Added in v1.0.0-beta.1](https://github.com/web-infra-dev/rspack/releases/tag/v1.0.0-beta.1)
- **Type:** `string`

Used to mark the layer of the matching module. A group of modules could be united in one layer which could then be used in split chunks, stats or [entry options](/config/entry.md#entrydescriptionlayer).

For more information about layers, see the [Layer guide](/guide/features/layer.md).

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        layer: 'layer-name',
      },
    ],
  },
};
```

## rules\[].use

- **Type:**

```ts
type RuleSetUse =
  | RuleSetUseItem[]
  | RuleSetUseItem
  | ((ctx: RawFuncUseCtx) => RuleSetUseItem[]);
type RuleSetUseItem = { loader: string; options: Record<string, any> } | string;
interface RawFuncUseCtx {
  resource?: string;
  realResource?: string;
  resourceQuery?: string;
  issuer?: string;
}
```

An array to pass the Loader package name and its options. `string[]` e.g.: `use: ['svgr-loader']` is shorthand for `use: [ { loader: 'svgr-loader' } ]`.
Loaders will be executed in right-to-left order.

```js title="rspack.config.mjs"
export default {
  //...
  module: {
    rules: [
      {
        //...
        use: [
          'svgr-loader',
          {
            loader: 'svgo-loader',
            options: {
              configFile: false,
            },
          },
        ],
      },
    ],
  },
};
```

A function can also be used:

```js title="rspack.config.mjs"
export default {
  //...
  module: {
    rules: [
      {
        test: /\.svg$/,
        type: 'asset',
        use: (info) => [
          {
            loader: 'svgo-loader',
            options: {
              plugins: [
                {
                  cleanupIDs: { prefix: basename(info.resource) },
                },
              ],
            },
          },
        ],
      },
    ],
  },
};
```

## rules\[].use.parallel

[Added in v1.3.1](https://github.com/web-infra-dev/rspack/releases/tag/v1.3.1)
- **Type**: `boolean`
- **Default:** `false`

Controls whether a given loader should run in worker threads for parallel execution. Loaders marked with `parallel` are scheduled across multiple threads, reducing pressure on the main thread and improving overall build performance.

- When set to `true`, the loader runs in a worker. Rspack automatically selects an appropriate number of worker threads.
- When set to `{ maxWorkers }`, you can explicitly define the maximum number of workers to use.
- When set to `false` or omitted, the loader runs on the main thread.

For example, enabling parallel execution for `less-loader`:

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          {
            loader: 'less-loader',
            parallel: true,
            options: {
              // loader options
            },
          },
        ],
      },
    ],
  },
};
```

When multiple loaders within the same rule have `parallel` enabled, Rspack executes them sequentially inside the same worker until it encounters a non-parallel loader or a Rust-implemented builtin loader. This preserves loader order while maximizing parallel efficiency.

:::tip

- The loader options must comply with the [HTML structured clone algorithm](https://nodejs.org/api/worker_threads.html#portpostmessagevalue-transferlist), otherwise transmission will fail.
- In worker mode, most methods on `LoaderContext._compilation`, `LoaderContext._compiler`, `LoaderContext._module` are not supported.

:::

## rules\[].resolve

Set specific module [resolve](/config/resolve.md) options based on the matching modules.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.css$/,
        resolve: {
          preferRelative: true,
        },
      },
    ],
  },
};
```

## rules\[].rules

- **Type:** <code>[Rule](#rules)\[]</code>
- **Default:** `undefined`

A kind of [Nested Rule](#nested-rule), an array of Rules that is also used when the parent Rule matches.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.css$/,
        // When a CSS file is matched, continue to use these nested rules
        rules: [
          {
            // Handle CSS files with "?raw" query
            resourceQuery: /raw/,
            type: 'asset/source',
          },
          {
            // Handle normal CSS files
            resourceQuery: {
              not: /raw/,
            },
            type: 'css/auto',
          },
        ],
      },
    ],
  },
};
```

## rules\[].oneOf

- **Type:** <code>([Rule](#rules) | Falsy)\[]</code>
- **Default:** `undefined`

A kind of [Nested Rule](#nested-rule), an array of Rules from which only the first matching Rule is used when the parent Rule matches.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.(png|jpg)$/i,
        oneOf: [
          {
            // Handle images with "?raw" query
            resourceQuery: /raw/,
            type: 'asset/source',
          },
          {
            // Otherwise, output as a separate file
            type: 'asset/resource',
          },
        ],
      },
    ],
  },
};
```

## rules\[].extractSourceMap

[Added in v1.6.0](https://github.com/web-infra-dev/rspack/releases/tag/v1.6.0)
- **Type**: `boolean`
- **Default:** `false`

Extracts existing source map data from files (from their `//# sourceMappingURL` comment), useful for preserving the source maps of third-party libraries.

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.m?js$/,
        extractSourceMap: true,
      },
    ],
  },
};
```