For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt, and this page is available as Markdown at /zh/plugins/low-level-plugins.md.
close

底层插件

这些插件是 Rspack 对外暴露的底层构件,主要用于实现目标预设、运行时模板、子编译器和上层插件。

使用建议

常规应用构建应优先使用对应的上层配置。直接使用这些插件主要适用于自定义编译器、子编译器和高级集成。

底层插件分为以下类别:

environment

影响编译器环境和运行目标的插件。

ElectronTargetPlugin

new rspack.electron.ElectronTargetPlugin(context);

ElectronTargetPlugin 会将 Electron 内置模块保留为外部依赖,使其在运行时由 Electron 加载。传入 'main''preload''renderer',可以额外外置对应进程中可用的模块。

externalsPresets.electronexternalsPresets.electronMainexternalsPresets.electronRendererexternalsPresets.electronPreload 配置会在内部应用该插件。

对于常规 Electron 应用,推荐使用对应的 target

rspack.config.mjs
export default {
  target: 'electron-main',
  entry: './src/main.js',
};

配置子编译器时,可以直接将插件应用到该编译器:

new compiler.rspack.electron.ElectronTargetPlugin('main').apply(childCompiler);

NodeEnvironmentPlugin

new rspack.node.NodeEnvironmentPlugin(options);

NodeEnvironmentPlugin 会为编译器安装 infrastructure logger、带缓存的 Node.js 输入文件系统、作为输出文件系统的 Node.js fs 模块以及 watch 文件系统。rspack() API 会自动将它应用到根编译器。

当自定义编译器需要独立的 Node.js 文件系统环境时,可以传入该编译器标准化后的 infrastructure logging 选项并直接应用插件:

new compiler.rspack.node.NodeEnvironmentPlugin({
  infrastructureLogging: childCompiler.options.infrastructureLogging,
}).apply(childCompiler);

该插件只配置编译器 I/O 和日志,不会设置 JavaScript 运行目标。需要将 Node.js 内置模块保留为外部依赖时,应使用 NodeTargetPlugin

NodeTargetPlugin

new rspack.node.NodeTargetPlugin();

NodeTargetPlugin 会将 Node.js 内置模块和使用 node: scheme 的请求保留为外部依赖,使其由 Node.js 运行时加载,而不是被 Rspack 打进 bundle。externalsPresets.node 配置会在内部应用该插件。

对于常规 Node.js 应用,推荐使用 node target:

rspack.config.mjs
export default {
  target: 'node',
  entry: './src/index.js',
};

配置子编译器时,可以直接将插件应用到该编译器:

new compiler.rspack.node.NodeTargetPlugin().apply(childCompiler);

entry

向 compilation 添加入口 chunk 的插件。

DynamicEntryPlugin

new rspack.DynamicEntryPlugin(context, entry);

DynamicEntryPlugin 会在每次触发 make 事件时调用入口函数,并将函数返回的入口添加到 compilation 中,因此入口列表可以在 watch 重新构建之间发生变化。

直接调用该 API 时需要传入标准化后的入口描述,因此每个 import 的值都是数组:

rspack.config.mjs
import { rspack } from '@rspack/core';

const context = process.cwd();

export default {
  context,
  entry: {},
  plugins: [
    new rspack.DynamicEntryPlugin(context, async () => ({
      main: {
        import: ['./src/index.js'],
      },
    })),
  ],
};

常规构建应优先使用 entry 函数,Rspack 会自动将它标准化并传给该插件。

EntryOptionPlugin

new rspack.EntryOptionPlugin();

EntryOptionPlugin 用于处理 compiler 的 entryOption hook。对于静态入口,它会为每个入口请求应用 EntryPlugin;对于函数入口,则会应用 DynamicEntryPlugin。Rspack 会自动将它应用到根编译器。

为子编译器添加标准化后的入口时,可以使用静态的 applyEntryOption 方法:

const childOptions = compiler.rspack.config.getNormalizedRspackOptions({
  entry: {
    child: './src/child.js',
  },
});

compiler.rspack.EntryOptionPlugin.applyEntryOption(
  childCompiler,
  compiler.context,
  childOptions.entry,
);

output

影响模块、chunk 和运行时加载代码生成的插件。

EnableChunkLoadingPlugin

new rspack.javascript.EnableChunkLoadingPlugin(type);

EnableChunkLoadingPlugin 会启用指定 chunk loading 类型所需的运行时模块。Rspack 通常会根据 output.enabledChunkLoadingTypes 收集到的类型应用该插件。

支持的内置类型包括 'jsonp''import-scripts''require''async-node''import'

当动态入口选择了 Rspack 在配置标准化阶段无法发现的类型时,可以直接应用该插件:

rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  entry: () => ({
    main: {
      import: './src/index.js',
      chunkLoading: 'jsonp',
    },
  }),
  output: {
    chunkLoading: false,
  },
  plugins: [new rspack.javascript.EnableChunkLoadingPlugin('jsonp')],
};

自定义 chunk loading 实现可以在安装相应运行时钩子后调用 EnableChunkLoadingPlugin.setEnabled(compiler, type)。该方法只注册类型,并不会实现 chunk loading。

EnableLibraryPlugin

new rspack.library.EnableLibraryPlugin(type);

EnableLibraryPlugin 会向编译器注册一种 library 输出类型。Rspack 通常会根据 output.enabledLibraryTypes 收集到的类型应用该插件。

下面的动态入口选择 'var' library 类型。由于 Rspack 无法在配置标准化阶段检查函数入口,因此需要显式启用该类型:

src/index.js
export const add = (a, b) => a + b;
rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  entry: () => ({
    main: {
      import: './src/index.js',
      library: {
        name: 'MathLibrary',
        type: 'var',
      },
    },
  }),
  plugins: [new rspack.library.EnableLibraryPlugin('var')],
};

常规 library 构建应优先使用 output.library,Rspack 会自动启用其中的 library 类型。

EnableWasmLoadingPlugin

new rspack.wasm.EnableWasmLoadingPlugin(type);

EnableWasmLoadingPlugin 会启用指定 WebAssembly 加载类型所需的运行时模块。Rspack 通常会根据 output.enabledWasmLoadingTypes 收集到的类型应用该插件。

支持的类型包括 'fetch''async-node''universal'

下面的示例将 output.wasmLoading 设为 false 以关闭自动配置,然后直接应用 EnableWasmLoadingPlugin 安装 'fetch' 加载运行时:

src/index.js
import { add } from './add.wasm';

console.log(add(1, 2));
rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  target: 'web',
  entry: './src/index.js',
  experiments: {
    asyncWebAssembly: true,
  },
  output: {
    wasmLoading: false,
  },
  plugins: [new rspack.wasm.EnableWasmLoadingPlugin('fetch')],
};

常规构建应优先使用 output.wasmLoading,Rspack 会自动启用所选类型。

EvalDevToolModulePlugin

new rspack.EvalDevToolModulePlugin(options);

EvalDevToolModulePlugin 会使用 eval 包裹每个非 external JavaScript 模块并添加 sourceURL,使浏览器开发者工具可以显示原始模块名称。设置 devtool: 'eval' 时,Rspack 会自动应用该插件。

下面的配置直接应用该插件,并使用 dashboard 作为 source URL 的 namespace:

rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  mode: 'development',
  devtool: false,
  plugins: [
    new rspack.EvalDevToolModulePlugin({
      namespace: 'dashboard',
    }),
  ],
};

可以通过 moduleFilenameTemplatesourceUrlComment 选项自定义生成的模块 URL 和注释格式。

FetchCompileAsyncWasmPlugin

new rspack.web.FetchCompileAsyncWasmPlugin();

FetchCompileAsyncWasmPlugin 会添加在浏览器中获取并编译异步 WebAssembly 模块的运行时代码。EnableWasmLoadingPlugin('fetch') 会在内部应用这个实现。

下面的示例关闭 WebAssembly loading 的自动配置,并直接安装 fetch 实现:

src/index.js
import { add } from './add.wasm';

console.log(add(1, 2));
rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  target: 'web',
  entry: './src/index.js',
  experiments: {
    asyncWebAssembly: true,
  },
  output: {
    wasmLoading: false,
  },
  plugins: [new rspack.web.FetchCompileAsyncWasmPlugin()],
};

常规 web 构建应优先使用 output.wasmLoading: 'fetch',Rspack 会自动启用相同的运行时实现。

JsonpTemplatePlugin

new rspack.web.JsonpTemplatePlugin();

JsonpTemplatePlugin 用于配置子编译器的浏览器产物。它会将 output.chunkLoading 设置为 'jsonp',应用 'array-push' chunk format,并启用 JSONP chunk loading 所需的运行时代码。

下面的浏览器入口会生成一个异步 chunk:

src/browser-child.js
document.querySelector('button').addEventListener('click', async () => {
  const { message } = await import('./message.js');
  console.log(message);
});
src/message.js
export const message = 'Hello from the child compiler';

下面的配置会创建一个子编译器,并直接应用 JsonpTemplatePlugin

rspack.config.mjs
export default {
  target: 'web',
  entry: {},
  plugins: [
    (compiler) => {
      compiler.hooks.make.tapAsync(
        'BrowserChildCompiler',
        (compilation, callback) => {
          const childCompiler = compilation.createChildCompiler(
            'browser-child',
            {
              filename: 'browser-child.js',
              chunkFilename: '[name].browser-child.js',
            },
            [
              new compiler.rspack.web.JsonpTemplatePlugin(),
              new compiler.rspack.EntryPlugin(
                compiler.context,
                './src/browser-child.js',
                { name: 'browser-child' },
              ),
            ],
          );

          childCompiler.runAsChild((error) => callback(error));
        },
      );
    },
  ],
};

JsonpTemplatePlugin 会让子编译器生成 array-push chunk,并在需要加载异步 chunk 时向页面添加 script。

对于常规 web 构建,推荐使用 target: 'web'。Rspack 会通过该 target 的默认配置选择 'array-push' chunk format 和 'jsonp' chunk loading。设置 output.chunkLoading: 'jsonp' 只会选择加载实现,并不会应用 JsonpTemplatePlugin 或选择 chunk format。

NodeTemplatePlugin

new rspack.node.NodeTemplatePlugin(options);

NodeTemplatePlugin 用于配置子编译器的 Node.js 产物。它会应用 'commonjs' chunk format,默认将 output.chunkLoading 设置为 'require',并启用所需的 chunk loading 运行时代码。

asyncChunkLoading

  • 类型:boolean
  • 默认值:false

asyncChunkLoadingtrue 时,该插件会使用 'async-node' chunk loading,而不是 'require'

下面的 Node.js 入口会生成一个异步 chunk:

src/node-child.js
async function main() {
  const { run } = await import('./task.js');
  run();
}

main();
src/task.js
export function run() {
  console.log('Task completed');
}

下面的配置会创建一个子编译器,并直接应用 NodeTemplatePlugin

rspack.config.mjs
export default {
  target: 'node',
  entry: {},
  plugins: [
    (compiler) => {
      compiler.hooks.make.tapAsync(
        'NodeChildCompiler',
        (compilation, callback) => {
          const childCompiler = compilation.createChildCompiler(
            'node-child',
            {
              filename: 'node-child.js',
              chunkFilename: '[name].node-child.js',
            },
            [
              new compiler.rspack.node.NodeTemplatePlugin(),
              new compiler.rspack.EntryPlugin(
                compiler.context,
                './src/node-child.js',
                { name: 'node-child' },
              ),
            ],
          );

          childCompiler.runAsChild((error) => callback(error));
        },
      );
    },
  ],
};

NodeTemplatePlugin 会让子编译器生成 CommonJS chunk,并通过 require 加载其中的异步 chunk。

对于常规 Node.js 构建,推荐使用 target: 'node'。Rspack 会通过该 target 的默认配置选择 'commonjs' chunk format 和 'require' chunk loading。设置 output.chunkLoading: 'require' 只会选择加载实现,并不会应用 NodeTemplatePlugin 或选择 chunk format。

WebWorkerTemplatePlugin

new rspack.webworker.WebWorkerTemplatePlugin();

WebWorkerTemplatePlugin 用于配置子编译器的 Web Worker 产物。它会将 output.chunkLoading 设置为 'import-scripts',应用 'array-push' chunk format,并启用基于 importScripts 的 chunk loading 运行时代码。

下面的 Worker 入口会生成一个异步 chunk:

src/worker-child.js
self.onmessage = async ({ data }) => {
  const { double } = await import('./math.js');
  self.postMessage(double(data));
};
src/math.js
export const double = (value) => value * 2;

下面的配置会创建一个子编译器,并直接应用 WebWorkerTemplatePlugin

rspack.config.mjs
export default {
  target: 'webworker',
  entry: {},
  plugins: [
    (compiler) => {
      compiler.hooks.make.tapAsync(
        'WorkerChildCompiler',
        (compilation, callback) => {
          const childCompiler = compilation.createChildCompiler(
            'worker-child',
            {
              filename: 'worker-child.js',
              chunkFilename: '[name].worker-child.js',
            },
            [
              new compiler.rspack.webworker.WebWorkerTemplatePlugin(),
              new compiler.rspack.EntryPlugin(
                compiler.context,
                './src/worker-child.js',
                { name: 'worker-child' },
              ),
            ],
          );

          childCompiler.runAsChild((error) => callback(error));
        },
      );
    },
  ],
};

WebWorkerTemplatePlugin 会让子编译器生成 array-push chunk,并通过 importScripts 加载其中的异步 chunk。

对于常规 Web Worker 构建,推荐使用 target: 'webworker'。Rspack 会通过该 target 的默认配置选择 'array-push' chunk format 和 'import-scripts' chunk loading。设置 output.chunkLoading: 'import-scripts' 只会选择加载实现,并不会应用 WebWorkerTemplatePlugin 或选择 chunk format。

loader

用于自定义 loader 执行上下文的插件。

LoaderOptionsPlugin

new rspack.LoaderOptionsPlugin(options);

LoaderOptionsPlugin 会将自定义选项字段复制到匹配 testincludeexclude 的资源所对应的 loader context 上。匹配字段本身只用于过滤,不会被复制。

下面的 loader 会从 context 中读取自定义的 message 属性:

loaders/message-loader.cjs
module.exports = function () {
  return `export default ${JSON.stringify(this.message)};`;
};

插件只在处理 .message 文件时提供该属性:

rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  entry: './src/welcome.message',
  module: {
    rules: [
      {
        test: /\.message$/,
        use: './loaders/message-loader.cjs',
      },
    ],
  },
  plugins: [
    new rspack.LoaderOptionsPlugin({
      test: /\.message$/,
      message: 'Hello from the loader',
    }),
  ],
};

该插件主要用于兼容从 this 读取自定义属性的 loader。新编写的 loader 通常应通过自身的 loader options 接收参数。

LoaderTargetPlugin

new rspack.LoaderTargetPlugin(target);

LoaderTargetPlugin 会将 target 赋值给每个 loader context 的 this.target。当自定义编译器需要让 loader 读取到与编译器配置不同的 target 时,可以使用该插件。

下面的 loader 会将输入替换为它读取到的 target:

loaders/target-loader.cjs
module.exports = function () {
  return `console.log(${JSON.stringify(this.target)});`;
};

虽然构建的 target 是 web,下面的插件会让 loader 读取到 'node'

rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  target: 'web',
  entry: './src/index.js',
  module: {
    rules: [
      {
        test: /index\.js$/,
        use: './loaders/target-loader.cjs',
      },
    ],
  },
  plugins: [new rspack.LoaderTargetPlugin('node')],
};

常规构建应优先使用顶层的 target 配置。

module federation

这些插件实现了 Module Federation 的 exposesremotesshared 能力。常规应用构建应优先使用 ModuleFederationPlugin,由它统一配置这些底层插件。

ContainerPlugin

new rspack.container.ContainerPlugin(options);

ContainerPlugin 会创建一个 container 入口,通过 Module Federation 的 getinit 接口暴露本地模块。它是 exposes 配置的底层实现。

下面的配置会生成 remoteEntry.js,并将 src/Button.js 暴露为 ./Button

rspack.config.mjs
import { container } from '@rspack/core';

export default {
  entry: {},
  plugins: [
    new container.ContainerPlugin({
      name: 'catalog',
      filename: 'remoteEntry.js',
      exposes: {
        './Button': './src/Button.js',
      },
    }),
  ],
};

ContainerReferencePlugin

new rspack.container.ContainerReferencePlugin(options);

ContainerReferencePlugin 会将远程 container 注册为 external,并添加从远程加载模块所需的运行时代码。它是 remotes 配置的底层实现。

使用下面的配置后,import('catalog/Button') 这样的导入会从远程 container 加载 ./Button

rspack.config.mjs
import { container } from '@rspack/core';

export default {
  entry: './src/index.js',
  plugins: [
    new container.ContainerReferencePlugin({
      remoteType: 'script',
      remotes: {
        catalog: 'catalog@http://localhost:3001/remoteEntry.js',
      },
    }),
  ],
};

ConsumeSharedPlugin

new rspack.sharing.ConsumeSharedPlugin(options);

ConsumeSharedPlugin 会从 share scope 中解析配置的模块请求。它可以检查版本与 singleton 要求,并在没有合适 provider 时使用本地模块作为 fallback。

下面的示例会从默认 share scope 中消费 singleton react,不检查版本,并在需要时回退到本地安装的 package:

rspack.config.mjs
import { sharing } from '@rspack/core';

export default {
  entry: './src/index.js',
  plugins: [
    new sharing.ConsumeSharedPlugin({
      consumes: {
        react: {
          import: 'react',
          requiredVersion: false,
          singleton: true,
        },
      },
    }),
  ],
};

ProvideSharedPlugin

new rspack.sharing.ProvideSharedPlugin(options);

ProvideSharedPlugin 会将本地模块及其版本注册到 share scope 中,供其他构建消费。它是 shared 配置中 provider 部分的底层实现。

下面的简写形式会使用 react 作为 share key 提供本地安装的 react package,并从 package metadata 中推断版本:

rspack.config.mjs
import { sharing } from '@rspack/core';

export default {
  plugins: [
    new sharing.ProvideSharedPlugin({
      provides: ['react'],
    }),
  ],
};

SharePlugin

new rspack.sharing.SharePlugin(options);

SharePlugin 会根据同一份 shared 配置同时应用 ConsumeSharedPluginProvideSharedPlugin。它等价于 ModuleFederationPluginshared 配置的底层实现。

下面的示例会将本地 react package 作为 fallback 提供,同时从默认 share scope 中消费 singleton 实例:

rspack.config.mjs
import { sharing } from '@rspack/core';

export default {
  plugins: [
    new sharing.SharePlugin({
      enhanced: false,
      shared: {
        react: {
          requiredVersion: false,
          singleton: true,
        },
      },
    }),
  ],
};

TreeShakingSharedPlugin

new rspack.sharing.TreeShakingSharedPlugin(options);
Stability: Experimental

TreeShakingSharedPlugin 会为 Module Federation 共享依赖创建独立构建并优化导出。当至少一个 shared 依赖启用了 treeShaking 时,ModuleFederationPlugin 会自动应用该插件。

选项

  • mfConfig:用于配置共享依赖和产物的 ModuleFederationPluginOptions
  • secondary:是否在独立构建中执行第二次 tree shaking,默认值为 false
  • onBuildAssets:生成共享 fallback 产物后调用的回调函数。

直接应用该插件主要适用于部署平台执行二次构建的场景。它必须配合共享插件使用,以便 TreeShakingSharedPlugin 收集需要构建的共享模块:

src/index.js
import { add } from 'lodash-es';

console.log(add(1, 2));
rspack.config.mjs
import { sharing } from '@rspack/core';

const shared = {
  'lodash-es': { treeShaking: { mode: 'server-calc' } },
};

export default {
  entry: './src/index.js',
  plugins: [
    new sharing.SharePlugin({
      enhanced: true,
      shared,
    }),
    new sharing.TreeShakingSharedPlugin({
      secondary: true,
      mfConfig: {
        name: 'app',
        shared,
        library: { type: 'var', name: 'App' },
      },
    }),
  ],
};

该插件只会为启用了 treeShaking 且保留本地实现的共享依赖创建独立构建。单独使用时,它不会生成 Module Federation stats 或 manifest 文件。当 ModuleFederationPlugin 在启用 manifest 生成的情况下在内部应用该插件时,生成的 fallback 产物信息会被写入这些文件。

experiments

RemoveDuplicateModulesPlugin

new rspack.experiments.RemoveDuplicateModulesPlugin();
Stability: Experimental

RemoveDuplicateModulesPlugin 会查找同时出现在同一组多个 chunk 中的模块,并将它们移动到一个可复用或新创建的共享 chunk 中。Rspack 会在生成 modern-module library 产物时在内部使用该插件。

下面的两个入口都导入了同一个 src/shared.js 模块。关闭 splitChunks 后,将由 RemoveDuplicateModulesPlugin 提取这个重复模块:

rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  entry: {
    admin: './src/admin.js',
    store: './src/store.js',
  },
  optimization: {
    splitChunks: false,
  },
  plugins: [new rspack.experiments.RemoveDuplicateModulesPlugin()],
};

本页改编自 webpack 文档,遵循 CC BY 4.0,且已作修改。