> For AI agents: the complete documentation index is available at https://rspack.rs/zh/llms.txt, the full documentation bundle is available at https://rspack.rs/zh/llms-full.txt.

# SWC loader

[SWC](https://github.com/swc-project/swc)（Speedy Web Compiler）是基于 Rust 语言编写的高性能 JavaScript 和 TypeScript 转译和压缩工具。SWC 提供与 Babel 和 Terser 相似的能力，在单线程上它比 Babel 快 20 倍，在四核上它比 Babel 快 70 倍。

Rspack 提供了一个内置的 `builtin:swc-loader`，它是 [swc-loader](https://github.com/swc-project/pkgs/tree/main/packages/swc-loader) 的 Rust 版本，旨在提供更优的性能，Loader 的 [选项](https://swc.rs/docs/configuration/compilation) 与 JS 版本的 `swc-loader` 保持一致。

## 示例

如果需要在项目中使用 `builtin:swc-loader`，可以参考下面的示例进行配置。

### TypeScript 转译

比如对 `.ts` 文件进行转译：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.(?:js|mjs|ts)$/,
        exclude: [/node_modules/],
        loader: 'builtin:swc-loader',
        options: {
          detectSyntax: 'auto',
        },
      },
    ],
  },
};
```

### JSX 转译

对 React 的 `.jsx` 文件进行转译：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.(?:js|mjs|jsx|ts|tsx)$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            detectSyntax: 'auto',
            jsc: {
              transform: {
                react: {
                  pragma: 'React.createElement',
                  pragmaFrag: 'React.Fragment',
                  throwIfNamespace: true,
                  development: false,
                },
              },
            },
          },
        },
      },
    ],
  },
};
```

### 语法降级

SWC 提供了 [jsc.target](https://swc.rs/docs/configuration/compilation#jsctarget) 和 [env.targets](https://swc.rs/docs/configuration/compilation#envtargets) 来指定 JavaScript 语法降级的目标。

:::tip 来自 Rspack 的默认 target
如果既未配置 `env.targets` 也未配置 `jsc.target`，`builtin:swc-loader` 将自动从 Rspack 的 [`target`](https://rspack.rs/zh/config/target.md) 配置中推断出默认 target。

这意味着你可以依赖 Rspack 的 `target` 配置，而无需在 loader 选项中手动指定相同的 target。
:::

#### jsc.target

[jsc.target](https://swc.rs/docs/configuration/compilation#jsctarget) 用于指定 ECMA 版本，例如 `es5`，`es2015`，`es2016` 等。

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

#### env.targets

[env.targets](https://swc.rs/docs/configuration/compilation#envtargets) 使用 [browserslist](https://github.com/browserslist/browserslist) 的语法来指定浏览器范围，例如：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            env: {
              targets: [
                'chrome >= 87',
                'edge >= 88',
                'firefox >= 78',
                'safari >= 14',
              ],
            },
            // ...other options
          },
        },
      },
    ],
  },
};
```

:::tip
`jsc.target` 和 `env.targets` 不能同时配置，使用时根据需求选择其中一个即可。
:::

### Polyfill 注入

当你在项目中使用高版本的 JavaScript 语法和 API 时，为了让编译后的代码能稳定运行在低版本的浏览器中，通常需要完成两部分降级：语法降级和 polyfill 注入。

SWC 支持注入 [core-js](https://github.com/zloirock/core-js) 作为 API polyfill，可以通过 [env.mode](https://swc.rs/docs/configuration/compilation#envmode) 和 [env.coreJs](https://swc.rs/docs/configuration/compilation#envcorejs) 来配置：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules[\\/]core-js/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            env: {
              mode: 'usage',
              coreJs: '3.26.1',
              targets: [
                'chrome >= 87',
                'edge >= 88',
                'firefox >= 78',
                'safari >= 14',
              ],
            },
            isModule: 'unknown',
            // ...other options
          },
        },
      },
    ],
  },
};
```

注意事项：

- 请确保通过 [exclude](https://rspack.rs/zh/config/module-rules.md#rulesexclude) 来排除 `core-js` 包，因为 `core-js` 如果被 SWC 编译，将无法正常工作。
- 当需要引用非 ES modules 的模块时，需要添加 [isModule: 'unknown'](https://swc.rs/docs/configuration/compilation#ismodule)，以便 SWC 能够正确识别模块类型。

## 类型声明

你可以使用 `@rspack/core` 导出的 `SwcLoaderOptions` 类型来开启类型提示：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'builtin:swc-loader',
          /** @type {import('@rspack/core').SwcLoaderOptions} */
          options: {
            // some options
          },
        },
      },
    ],
  },
};
```

- `rspack.config.ts`:

```ts
import type { SwcLoaderOptions } from '@rspack/core';

export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            // some options
          } satisfies SwcLoaderOptions,
        },
      },
    ],
  },
};
```

## 选项

`builtin:swc-loader` 不读取 `.swcrc` 文件，而是通过 Rspack 配置中的 loader `options` 配置 SWC。下面介绍常用的 SWC 选项和 Rspack 特有选项，完整的 SWC 选项请参考 [SWC 配置](https://swc.rs/docs/configuration/swcrc)。

### detectSyntax


[Added in v2.0.0](https://github.com/web-infra-dev/rspack/releases/tag/v2.0.0)

- 类型：`false | "auto"`
- 默认值：`false`

当设置为 `"auto"` 时，`builtin:swc-loader` 会根据资源文件扩展名推断 `jsc.parser`。当一条规则需要同时处理 `.js`、`.jsx`、`.ts`、`.tsx` 等多种模块类型时，这个选项尤其有用。

推断规则：

- `.js`、`.jsx`、`.mjs`、`.cjs` -> `{ syntax: "ecmascript", jsx: true }`
- `.ts`、`.mts`、`.cts` -> `{ syntax: "typescript", tsx: false }`
- `.tsx` -> `{ syntax: "typescript", tsx: true }`
- 无法识别扩展名的资源 -> `{ syntax: "typescript", tsx: true }`

> 如果显式设置了 `jsc.parser.syntax`，`detectSyntax` 不会再推断语法。

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

### jsc.transform.react

配置 React 的 JSX 转换，包括 JSX runtime 和 Fast Refresh 支持。

配置 JSX 转换时，如果未显式指定 `jsc.transform.react.development`，它会根据 Rspack 的 [`mode`](https://rspack.rs/zh/config/mode.md) 自动设置。

配置步骤请参考 [React 集成指南](https://rspack.rs/zh/guide/integrations/react.md)和 [Fast Refresh 配置](https://rspack.rs/zh/guide/integrations/react.md#fast-refresh)。

### jsc.transform.reactCompiler


[Added in v2.1.0](https://github.com/web-infra-dev/rspack/releases/tag/v2.1.0)

- 类型：`boolean | object`
- 默认值：`false`

启用 React Compiler，自动优化 React 代码。设置为 `true` 时使用默认配置，也可以传入对象来自定义 `target`、`compilationMode` 等选项。

配置步骤和示例请参考[通过 builtin:swc-loader 使用 React Compiler](https://rspack.rs/zh/guide/integrations/react.md#using-builtinswc-loader)。

### jsc.experimental.plugins


Stability: Experimental

:::warning
Wasm 插件和 SWC 的版本存在一定的绑定关系，需要选择和对应 SWC 版本兼容的 Wasm 插件才能正常执行。

详见 [常见问题 - SWC 插件版本不匹配](https://rspack.rs/zh/errors/swc-plugin-version.md)。
:::

Rspack 支持在 `builtin:swc-loader` 里加载 SWC 的 Wasm 插件, 你可以通过如下配置启用 Wasm 插件

```js
{
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            jsc: {
              experimental: {
                plugins: [
                  [
                    '@swc/plugin-remove-console',
                    {
                      exclude: ['error'],
                    },
                  ],
                ],
              },
            },
          },
        },
      },
    ];
  }
}
```

这是 Wasm 插件的一个[示例](https://github.com/rstackjs/rstack-examples/blob/d4b8aaef9915ed0f540edbe504217c3d1afe8989/rspack/builtin-swc-loader/rspack.config.js#L45)。

#### 设置缓存目录

当你使用 SWC 的 Wasm 插件时，SWC 默认会生成缓存文件在当前项目的 `.swc` 目录下，如果你希望调整该目录，可以修改 `cacheRoot` 配置，如：

```js title="rspack.config.mjs"
import path from 'node:path';

export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            jsc: {
              experimental: {
                cacheRoot: path.join(
                  import.meta.dirname,
                  './node_modules/.cache/swc',
                ),
              },
            },
          },
        },
      },
    ],
  },
};
```

### transformImport

移植自 [babel-plugin-import](https://github.com/umijs/babel-plugin-import)，配置基本保持一致。

但不能使用函数进行配置，例如 `customName`，`customStyleName` 等，这是因为这些函数必须由 Rust 调用，这种调用会造成一些性能劣化，受到 [modularize\_imports](https://crates.io/crates/modularize_imports) 的启发，简单的函数逻辑其实可以通过模版来代替，因此 `customName`，`customStyleName` ，这些配置可以传入字符串作为模版来代替函数，提高性能。

我们以下面代码为例说明:

```ts
import { MyButton as Btn } from 'foo';
```

添加以下配置：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        loader: 'builtin:swc-loader',
        options: {
          transformImport: [
            {
              libraryName: 'foo',
              customName: 'foo/es/{{ member }}',
            },
          ],
        },
      },
    ],
  },
};
```

其中的 `{{ member }}` 会被替换为相应的引入成员，转换后:

```ts
import Btn from 'foo/es/MyButton';
```

可以看出配置 `customName: "foo/es/{{ member }}"` 的效果等同于配置 `` customName: (member) => `foo/es/${member}` ``，但是不会有 Node-API 的调用开销。

模版字符串中还内置了一些有用的辅助函数，还是以上面的导入语句为例：

配置如下：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        loader: 'builtin:swc-loader',
        options: {
          transformImport: [
            {
              libraryName: 'foo',
              customName: 'foo/es/{{ kebabCase member }}',
            },
          ],
        },
      },
    ],
  },
};
```

会转换成下面的结果:

```ts
import Btn from 'foo/es/my-button';
```

除了 `kebabCase` 以外还有 `camelCase`、`snakeCase`、`upperCase`、 `lowerCase` 和 `legacyKebabCase`、`legacySnakeCase` 可以使用。

其中 `legacyKebabCase`/`legacySnakeCase` 使用跟 babel-plugin-import\@1.13.7 之前的版本相同的转换逻辑。

其他配置可以直接查看 [babel-plugin-import](https://www.npmjs.com/package/babel-plugin-import)。

再以经典的 4 版本的 [ant-design](https://4x.ant.design/) 为例，我们只需要如下配置：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        loader: 'builtin:swc-loader',
        options: {
          transformImport: [
            {
              libraryName: 'antd',
              style: '{{member}}/style/index.css',
            },
          ],
        },
      },
    ],
  },
};
```

上面的配置会将 `import { Button } from 'antd';` 转换成

```ts
import Button from 'antd/es/button';
import 'antd/es/button/style/index.css';
```

然后就可以在页面中看到样式文件自动被引入并且生效了。

当然如果你已经配置了对 `less` 的支持，也可以直接使用如下配置：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        loader: 'builtin:swc-loader',
        options: {
          transformImport: [
            {
              libraryName: 'antd',
              style: true,
            },
          ],
        },
      },
    ],
  },
};
```

上面的配置会将 `import { Button } from 'antd';` 转换成：

```ts
import Button from 'antd/es/button';
import 'antd/es/button/style';
```

### rspackExperiments

Rspack 内置的实验性功能。

:::warning
`rspackExperiments.import` 已迁移至顶层 [`transformImport`](#transformimport) 选项。`rspackExperiments.import` 选项已废弃，将在未来版本中移除。
:::

#### rspackExperiments.reactServerComponents


Stability: Experimental

- 类型：`boolean | object`
- 默认值：`false`

设置为 `true` 可启用 React Server Components 转换，也可以传入对象来自定义配置。

所需插件和配置示例请参考 [React Server Components 指南](https://rspack.rs/zh/guide/integrations/rsc.md)。

### collectTypeScriptInfo


[Added in v1.7.0](https://github.com/web-infra-dev/rspack/releases/tag/v1.7.0)

从 TypeScript 的 AST 中收集信息，以供 Rspack 后续过程进行消费，提供对 TypeScript 更好的开发体验和更小的产物体积。

为了保证收集到的信息的准确性，用户需要确保 `builtin:swc-loader` 后续的 Normal Loader 不会去修改这些已经被收集到的相关信息对应的 AST，以免导致收集到的信息和实际的代码不一致的情况。

#### collectTypeScriptInfo.typeExports


[Added in v1.7.0](https://github.com/web-infra-dev/rspack/releases/tag/v1.7.0)

- **类型：** `boolean`
- **默认值：** `false`

是否收集类型导出信息，提供给 [`typeReexportsPresence`](https://rspack.rs/zh/config/module-parser.md#javascripttypereexportspresence) 使用，用于 `'tolerant'` 模式下检查子模块的类型导出。

详细示例可参考：[type reexports presence 示例](https://github.com/rstackjs/rstack-examples/tree/main/rspack/type-reexports-presence)

#### collectTypeScriptInfo.exportedEnum


[Added in v1.7.0](https://github.com/web-infra-dev/rspack/releases/tag/v1.7.0)

- **类型：** `boolean | 'const-only'`
- **默认值：** `false`

是否收集导出的 `enum` 信息，提供给 Rspack 对 `enums` 进行跨模块的内联优化。

- `true` 将收集所有 `enum` 信息，包括 `const enum` 和普通 `enum`。
- `false` 不收集任何 `enum` 信息。
- `'const-only'` 仅收集 `const enum` 信息，仅对 `const enum` 进行跨模块的内联优化。

```js title="rspack.config.mjs"
const isProduction = process.env.NODE_ENV === 'production';

export default {
  module: {
    rules: [
      {
        test: /\.(?:js|mjs|ts)$/,
        use: [
          {
            loader: 'builtin:swc-loader',
            options: {
              detectSyntax: 'auto',
              collectTypeScriptInfo: {
                exportedEnum: isProduction,
              },
            },
          },
        ],
      },
    ],
  },
};
```

由于该功能依赖模块导出的使用信息（[optimization.usedExports](https://rspack.rs/zh/config/optimization.md#optimizationusedexports)），所以建议仅在 `mode = "production"` 时开启该功能。

详细示例可参考：[inline enum 示例](https://github.com/rstackjs/rstack-examples/tree/main/rspack/inline-enum)

:::info
默认会对所有 `enum` 进行内联优化，若仅对 `const enum` 进行内联请使用 `'const-only'` 并配置 `transform.tsEnumIsMutable = true`，详细示例可参考：[inline const enum 示例](https://github.com/rstackjs/rstack-examples/tree/main/rspack/inline-const-enum)
:::
