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

# Web Workers

本文将介绍在 Rslib 项目中如何配置和使用 [Web Workers](https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Using_web_workers)。

:::note

使用 Web Workers 时，仅支持生成 ESM 格式的产物，因此 [format](/zh/config/lib/format.md) 必须设置为 `'esm'`（默认值）。

:::

## 使用 Worker 构造器

### 基本用法

你可以使用标准构造器语法创建 Worker：

```ts title="index.ts"
new Worker(new URL('./worker.ts', import.meta.url));
```

Rslib 会重写 Worker URL，使其指向生成的 JavaScript 文件，并将 Worker 输出为 ES 模块：

```js title="index.js"
new Worker(new URL('./worker.js', import.meta.url), {
  type: 'module',
});
```

更多 Worker 语法可以查看 [Rspack - Web Workers](https://rspack.rs/zh/guide/features/web-workers)。

### 限制

Rslib 依赖静态分析处理 `new Worker` 及类似的 Worker API，因此必须直接传入 `new URL('./worker.ts', import.meta.url)`。URL 字符串和通过变量传入的 URL 对象均不受支持：

```ts
new Worker('./worker.ts');

const workerUrl = new URL('./worker.ts', import.meta.url);
new Worker(workerUrl);
```

### 产物模式

[lib.bundle](/zh/config/lib/bundle.md) 配置项会影响 Worker 的构建方式。下面以同一组源码为例，展示 bundle 和 bundleless 模式分别生成的产物：


**src/index.ts**

```ts
export const worker = new Worker(new URL('./worker.ts', import.meta.url));
```


**src/worker.ts**

```ts
import { add } from './helper';

self.onmessage = ({ data }: MessageEvent<[number, number]>) => {
  self.postMessage(add(data[0], data[1]));
};
```


**src/helper.ts**

```ts
export const add = (left: number, right: number) => left + right;
```


#### Bundle 模式

在 bundle 模式下，Rslib 会将 Worker 入口拆分为独立 chunk，并将 Worker 导入的模块打包到该 chunk 中：


**dist/index.js**

```js
const worker = new Worker(new URL('./worker.js', import.meta.url), {
  type: 'module',
});
export { worker };
```


**dist/worker.js**

```js
const add = (left, right) => left + right;
self.onmessage = ({ data }) => {
  self.postMessage(add(data[0], data[1]));
};
export {};
```


#### Bundleless 模式

在 bundleless 模式下，Rslib 会保留源码的模块结构，并将 Worker URL 和 Worker 内部的导入重写为对应的 ESM 产物路径：


**dist/index.js**

```js
const worker = new Worker(new URL('./worker.js', import.meta.url), {
  type: 'module',
});
export { worker };
```


**dist/worker.js**

```js
import { add } from './helper.js';
self.onmessage = ({ data }) => {
  self.postMessage(add(data[0], data[1]));
};
```


**dist/helper.js**

```js
const add = (left, right) => left + right;
export { add };
```


## 使用 query 后缀导入

Rslib 支持在 bundle 模式下通过 query 后缀导入 Web Worker，详情请参考 [Rsbuild - Web Workers](https://rsbuild.rs/zh/guide/basic/web-workers#使用-query-后缀导入)。

### 输出独立 Worker 文件

你可以在导入请求后添加 `?worker` 来导入 Web Worker 脚本，Rslib 会为该 Worker 脚本生成独立的 ESM 文件：

```ts title="index.ts"
import MyWorker from './worker.ts?worker';

export const worker = new MyWorker();
```

### 内联 Worker

你可以在导入请求后添加 `?worker&inline` 来导入 Web Worker 脚本，Rslib 会在导入该 Worker 的 JavaScript 文件中内联 Worker 代码，不再生成独立的 Worker 文件：

```ts title="index.ts"
import InlineWorker from './worker.ts?worker&inline';

export const worker = new InlineWorker();
```

### 类型声明

当你在 TypeScript 代码中使用 query 后缀导入 Worker 时，TypeScript 可能会提示该模块缺少类型定义：

```
TS2307: Cannot find module './worker.ts?worker' or its corresponding type declarations.
```

此时你可以在 `tsconfig.json` 中添加 `@rslib/core` 提供的 [预设类型](/zh/guide/basic/typescript.md#预设类型)：

```json title="tsconfig.json"
{
  "compilerOptions": {
    "types": ["@rslib/core/types"]
  }
}
```

预设类型中已包含 `*?worker`、`*?worker&inline` 和 `*?inline&worker` 的类型声明。
