close
logologo
指南
配置
插件
API
社区
版本
更新日志
Rsbuild 0.x 文档
English
简体中文
指南
配置
插件
API
社区
更新日志
Rsbuild 0.x 文档
English
简体中文
logologo

插件列表

总览
React 插件
SVGR 插件
Vue 插件
Preact 插件
Svelte 插件
Solid 插件
Babel 插件
Sass 插件
Less 插件
Stylus 插件

开发

插件开发
插件 API
插件 hooks
📝 在 GitHub 上编辑此页
上一页Solid 插件
下一页Sass 插件

#Babel 插件

Source

Rsbuild 默认使用 SWC 编译,当内置的功能无法满足诉求、需要添加一些 Babel presets 或 plugins 进行额外处理时,你可以使用 Rsbuild 的 Babel 插件。

#快速开始

#安装插件

你可以通过如下的命令安装插件:

npm
yarn
pnpm
bun
npm add @rsbuild/plugin-babel -D

#注册插件

你可以在 rsbuild.config.ts 文件中注册插件:

rsbuild.config.ts
import { pluginBabel } from '@rsbuild/plugin-babel';

export default {
  plugins: [pluginBabel()],
};

#编译缓存

使用 Babel 插件后,Rsbuild 除了执行默认的 SWC 转译,还会执行 Babel 转译,存在额外的编译开销,这可能导致构建速度明显降低。

为了降低 Babel 转译的开销,@rsbuild/plugin-babel 默认开启了 Babel 编译缓存。如果你希望禁用缓存,可以将 performance.buildCache 设置为 false:

rsbuild.config.ts
export default {
  performance: {
    buildCache: false,
  },
};

#选项

#babelLoaderOptions

传递给 babel-loader 的选项,请查阅 babel-loader 文档 来了解具体用法。

  • 类型: Object | Function
  • 默认值:
const defaultOptions = {
  babelrc: false,
  compact: false,
  configFile: false,
  plugins: [
    ['@babel/plugin-proposal-decorators', config.source.decorators],
    ...(isLegacyDecorators ? ['@babel/plugin-transform-class-properties'] : []),
  ],
  presets: [
    [
      '@babel/preset-typescript',
      {
        allExtensions: true,
        allowDeclareFields: true,
        allowNamespaces: true,
        isTSX: true,
        optimizeConstEnums: true,
      },
    ],
  ],
};

#Function 类型

当配置项为 Function 类型时,默认 Babel 配置会作为第一个参数传入,你可以直接修改配置对象,也可以返回一个对象作为最终的 babel-loader 配置。

pluginBabel({
  babelLoaderOptions: (config) => {
    // 添加一个插件,比如配置某个组件库的按需引入
    config.plugins ||= [];
    config.plugins.push([
      'babel-plugin-import',
      {
        libraryName: 'my-components',
        libraryDirectory: 'es',
        style: true,
      },
    ]);
  },
});

函数的第二个参数提供了一些方便的工具函数,请继续阅读下方文档。

TIP

以上示例仅作为参考,通常来说,你不需要手动配置 babel-plugin-import,因为 Rspack SWC 编译已支持 transformImport 能力,Rsbuild 也提供了更通用的 source.transformImport 配置。

#Object 类型

当配置项的值为 Object 类型时,会与默认配置通过 Object.assign 浅合并。

CAUTION

Object.assign 是浅拷贝,会完全覆盖内置的 presets 或 plugins 数组,导致内置的 presets 或 plugins 失效,请在明确影响面的情况下再使用这种方式。

pluginBabel({
  babelLoaderOptions: {
    plugins: [
      [
        'babel-plugin-import',
        {
          libraryName: 'my-components',
          libraryDirectory: 'es',
          style: true,
        },
      ],
    ],
  },
});

#工具函数

配置项为 Function 类型时,第二个参数可用的工具函数如下:

#addPlugins
  • 类型: (plugins: BabelPlugin[]) => void

添加若干个 Babel 插件。

pluginBabel({
  babelLoaderOptions: (config, { addPlugins }) => {
    addPlugins([
      [
        'babel-plugin-import',
        {
          libraryName: 'my-components',
          libraryDirectory: 'es',
          style: true,
        },
      ],
    ]);
  },
});
#addPresets
  • 类型: (presets: BabelPlugin[]) => void

添加若干个 Babel 预设配置 (大多数情况下不需要增加预设)。

pluginBabel({
  babelLoaderOptions: (config, { addPresets }) => {
    addPresets(['@babel/preset-env']);
  },
});
#removePlugins
  • 类型: (plugins: string | string[]) => void

移除 Babel 插件,传入需要移除的插件名称即可,你可以传入单个字符串,也可以传入一个字符串数组。

pluginBabel({
  babelLoaderOptions: (config, { removePlugins }) => {
    removePlugins('babel-plugin-import');
  },
});
#removePresets
  • 类型: (presets: string | string[]) => void

移除 Babel 预设配置,传入需要移除的预设名称即可,你可以传入单个字符串,也可以传入一个字符串数组。

pluginBabel({
  babelLoaderOptions: (config, { removePresets }) => {
    removePresets('@babel/preset-env');
  },
});

#include

  • 类型: string | RegExp | (string | RegExp)[]
  • 默认值: undefined

用于指定需要 Babel 编译的文件。

由于 Babel 编译存在性能开销,通过 include 来匹配部分文件可以减少 Babel 编译的模块数量,从而提升构建性能。

比如,只对 .custom.js 文件进行编译,并忽略 node_modules 下的文件:

pluginBabel({
  include: /\.custom\.js$/,
  // 建议 exclude node_modules 目录以提升构建性能
  exclude: /[\\/]node_modules[\\/]/,
});
TIP

当你配置 include 或 exclude 选项时,Rsbuild 会创建一条单独的 Rspack rule 来应用 babel-loader 和 swc-loader。

这条单独的 rule 与 Rsbuild 内置的 SWC rule 是完全独立的,并且不会受到 source.include 和 source.exclude 的作用。

#exclude

  • 类型: string | RegExp | (string | RegExp)[]
  • 默认值: undefined

用于指定不需要 Babel 编译的文件。

由于 Babel 编译存在性能开销,通过 exclude 来排除部分文件可以减少 Babel 编译的模块数量,从而提升构建性能。

#执行顺序

使用 @rsbuild/plugin-babel 后,Rsbuild 会使用 babel-loader 和 builtin:swc-loader 分别对 JavaScript 文件进行编译,且 Babel 的执行时机早于 SWC。

这意味着,当代码中使用某些 ECMAScript 新特性时,你可能需要添加 Babel 插件,使 Babel 能够正确编译这些新特性。

例如,添加 @babel/plugin-transform-private-methods 插件,使 Babel 能够正确编译 private properties:

pluginBabel({
  babelLoaderOptions: {
    plugins: ['@babel/plugin-transform-private-methods'],
  },
});

#调试配置

当你通过配置项修改 babel-loader 配置后,可以在 Rsbuild 调试模式 下查看最终生成的配置。

首先通过 DEBUG=rsbuild 参数开启调试模式:

# 调试开发模式
DEBUG=rsbuild pnpm dev

# 调试生产模式
DEBUG=rsbuild pnpm build

然后打开生成的 rspack.config.web.mjs,搜索 babel-loader 关键词,即可看到完整的 babel-loader 配置内容。

#常见问题

#编译卡死

在使用 Babel 插件后,如果编译进度条卡死,但终端无 Error 日志时,通常是因为编译过程中出现了异常。在某些情况下,当 Error 被 webpack 或其他模块捕获后,错误日志不会被正确输出。最为常见的场景是 Babel 配置出现异常,抛出 Error 后被 webpack 捕获,而 webpack 在个别情况下吞掉了 Error。

解决方法:

如果你修改 Babel 配置后出现此问题,建议检查是否有以下错误用法:

  1. 配置了一个不存在的 plugin 或 preset,可能是名称拼写错误,或是未正确安装。
// 错误示例
pluginBabel({
  babelLoaderOptions: (config, { addPlugins }) => {
    // 该插件名称错误,或者未安装
    addPlugins('babel-plugin-not-exists');
  },
});
  1. 是否配置了多个 babel-plugin-import,但是没有在数组的第三项声明每一个 babel-plugin-import 的名称。
// 错误示例
pluginBabel({
  babelLoaderOptions: (config, { addPlugins }) => {
    addPlugins([
      ['babel-plugin-import', { libraryName: 'antd', libraryDirectory: 'es' }],
      [
        'babel-plugin-import',
        { libraryName: 'antd-mobile', libraryDirectory: 'es' },
      ],
    ]);
  },
});
// 正确示例
pluginBabel({
  babelLoaderOptions: (config, { addPlugins }) => {
    addPlugins([
      [
        'babel-plugin-import',
        { libraryName: 'antd', libraryDirectory: 'es' },
        'antd',
      ],
      [
        'babel-plugin-import',
        { libraryName: 'antd-mobile', libraryDirectory: 'es' },
        'antd-mobile',
      ],
    ]);
  },
});