内置 swc-loader

builtin:swc-loaderswc-loader 的 Rust 版本,旨在提供更优的性能,Loader 的配置与 JS 版本的 swc-loader 保持对齐。

示例

如果需要在项目中使用 builtin:swc-loader,需进行如下配置。

比如对 ts 文件进行转译:

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: [/node_modules/],
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            parser: {
              syntax: 'typescript',
            },
          },
        },
        type: 'javascript/auto',
      },
    ],
  },
};

或是对 jsx 文件进行转译:

module.exports = {
  module: {
    rules: [
      {
        test: /\.jsx$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            jsc: {
              parser: {
                syntax: 'ecmascript',
                jsx: true,
              },
              transform: {
                react: {
                  pragma: 'React.createElement',
                  pragmaFrag: 'React.Fragment',
                  throwIfNamespace: true,
                  development: false,
                  useBuiltins: false,
                },
              },
            },
          },
        },
        type: 'javascript/auto',
      },
    ],
  },
};

另外,你也可以直接参考 example-builtin-swc-loader 查看更多使用指南。

类型声明

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

  • rspack.config.js:
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'builtin:swc-loader',
          /** @type {import('@rspack/core').SwcLoaderOptions} */
          options: {
            // some options
          },
        },
      },
    ],
  },
};
  • rspack.config.ts:
import type { SwcLoaderOptions } from '@rspack/core';

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

Options

下面是部分 SWC 配置以及 Rspack 特有配置的介绍,完整选项请参考 SWC 配置

jsc.experimental.plugins

Stability: Experimental
WARNING

Wasm 插件和 SWC 的版本存在一定的绑定关系,需要选择和对应 SWC 版本兼容的 Wasm 插件才能正常执行, selecting-swc-core 里有更多关于如何选择兼容的 Wasm 插件的信息。

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

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

这是 Wasm 插件的一个示例

rspackExperiments

Rspack 内置的实验性功能。

rspackExperiments.import

Stability: Experimental

移植自 babel-plugin-import,配置基本保持一致。

但不能使用函数进行配置,例如 customNamecustomStyleName 等,这是因为这些函数必须由 Rust 调用,这种调用会造成一些性能劣化,受到 modularize_imports 的启发,简单的函数逻辑其实可以通过模版来代替,因此 customNamecustomStyleName ,这些配置可以传入字符串作为模版来代替函数,提高性能。

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

import { MyButton as Btn } from 'foo';

添加以下配置:

rspack.config.js
module.exports = {
  module: {
    rules: [
      {
        use: 'builtin:swc-loader',
        options: {
          ...
          rspackExperiments: {
            import: [{
               libraryName: 'foo',
               customName: 'foo/es/{{ member }}',
            }]
          }
        }
      }
    ]
  }
};

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

import Btn from 'foo/es/MyButton';

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

这里使用到的模版是 handlebars,模版配置中还内置了一些有用的辅助函数,还是以上面的导入语句为例:

配置如下:

rspack.config.js
module.exports = {
  module: {
    rules: [
      {
        use: 'builtin:swc-loader',
        options: {
          ...
          rspackExperiments: {
            import: [{
               libraryName: 'foo',
               customName: 'foo/es/{{ kebabCase member }}',
            }]
          }
        }
      }
    ]
  }
};

会转换成下面的结果:

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

除了 kebabCase 以外还有 camelCasesnakeCaseupperCaselowerCaselegacyKebabCaselegacySnakeCase 可以使用。

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

其他配置可以直接查看 babel-plugin-import

再以经典的 4 版本的 ant-design 为例,我们只需要如下配置:

rspack.config.js
module.exports = {
  module: {
    rules: [
      {
        use: 'builtin:swc-loader',
        options: {
          ...
          rspackExperiments: {
            import: [
              {
                libraryName: 'antd',
                style: '{{member}}/style/index.css',
            },
            ]
          }
        }
      }
    ]
  }
};

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

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

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

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

rspack.config.js
module.exports = {
  module: {
    rules: [
      {
        use: 'builtin:swc-loader',
        options: {
          ...
          rspackExperiments: {
            import: [
              {
                libraryName: 'antd',
                style: true,
            },
            ]
          }
        }
      }
    ]
  }
};

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

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