Loader

Loader 可以对文件内容进行转换,你可以借助 Loader,将 Rspack 中非一等公民支持的文件转换为一等公民类型,以被 Rspack 所正确识别。

TIP

Loader 属于对资源的前处理,而 Rule.type 则属于对资源的后处理,后者定义了 Rspack 支持的一等公民类型。

示例

使用 Less

CSS 为 Rspack 的一等公民,因此对于 CSS 文件的处理是原生支持的。而对于 Less 文件来说,则需要借助外部的 less-loader 对文件的内容做相应的转换:

rspack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          {
            loader: 'less-loader',
          },
        ],
        type: 'css',
      },
    ],
  },
};

less-loader 可以将 Less 文件转换为 Rspack 支持的 CSS 模块类型,因此你可以设置 type 为 'css' 以指示 Rspack 使用原生支持的 CSS 策略进行后处理。

使用多个 Loader

你可以对特定的 Rule 匹配项使用多个 loader 进行链式处理,loader 的执行顺序为从右往左

例如,你可以使用 less-loader 完成 Less 到 CSS 类型之间的转换,并对转换后的源码使用 postcss-loader 进行二次转换,并最终交给 Rspack 的 CSS 后处理器,完成进一步处理:

rspack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          {
            loader: 'postcss-loader',
          },
          {
            loader: 'less-loader',
          },
        ],
        type: 'css',
      },
    ],
  },
};

传递配置项

你可以使用 Rule.use 给 loader 传递相关配置,例如:

rspack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                // ...
              },
            },
          },
        ],
        type: 'css',
      },
    ],
  },
};

使用自定义 Loader

你可以在 Rspack 中使用自定义 loader,下面我们会编写一个简单的 banner-loader 作为示例。

banner-loader 的作用是在每个模块的头部添加一个 banner 注释,例如添加一段 License 信息:

/**
 * MIT Licensed
 * Copyright (c) 2022-present ByteDance, Inc. and its affiliates.
 * https://github.com/web-infra-dev/rspack/blob/main/LICENSE
 */

在项目的根目录新建一个 banner-loader.js 的文件,内容如下:

banner-loader.js
const BANNER = `/**
 * MIT Licensed
 * Copyright (c) 2022-present ByteDance, Inc. and its affiliates.
 * https://github.com/web-infra-dev/rspack/blob/main/LICENSE
 */`;

module.exports = function (content) {
  return `${BANNER}\n${content}`;
};

Loader 的第一个入参为文件的内容,我们可以在这里对文件内容进行处理,然后返回处理后的内容。编写完后,我们需要将这个 loader 使用 CommonJS 风格进行导出。

上述示例中,我们会在所有匹配的文件的头部添加一个 banner 注释,如果我们希望将这个行为匹配所有以 js 结尾的文件,我们可以这样配置:

rspack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: require.resolve('./banner-loader.js'),
      },
    ],
  },
};

更多关于 Loader API 的信息,请参考 loader-api

使用内置 Loader

内置 Loader 在不损失 JS Loader 的可组合性的同时,提供了比 JS Loader 更优的性能。

builtin:swc-loader

Stability: Experimental

builtin:swc-loaderswc-loader 的 Rust 版本,旨在提供更优的性能, Loader 的配置与 JS 版本的 swc-loader 保持对齐(SWC 插件将会在未来版本进行提供,暂不支持)。

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

如对 ts 文件进行转译:

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

或是对 jsx 文件进行转译:

module.exports = {
  module: {
    rules: [
      {
        test: /\.jsx$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            sourceMap: true,
            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 查看更多使用指南。

options

参考 SWC 配置

options.rspackExperiments
Stability: Experimental

这个字段是部分 builtins 替代,在保留了原有功能的基础上提供了模块粒度的精细转译。

如果是 react 应用,可以参考 options.jsc.transform.react 进行配置。

  • Type:
export type RspackExperiments = {
  import?: PluginImportOptions;
  emotion?: EmotionOptions;
  relay?: RelayOptions;
  styledComponents?: StyledComponentsOptions;
};
  • Default: {}

其中部分配置项可以在 builtins 下找到:

Stability: Experimental

此外一些新的特性将仅通过 builtin:swc-loader 提供。

options.rspackExperiments.styledComponents
Stability: Experimental
  • Type:
type StyledComponentsOptions = {
  displayName?: boolean;
  ssr?: boolean;
  fileName?: boolean;
  meaninglessFileNames?: string[];
  namespace?: string;
  topLevelImportPaths?: string[];
  transpileTemplateLiterals?: boolean;
  minify?: boolean;
  pure?: boolean;
  cssProps?: boolean;
};
  • Default: {}

配置对 styled-components 的编译时支持。SWC 对于 styled-components 的支持基本对齐了官方的 babel 插件,所以你可以访问 https://styled-components.com/docs/tooling#babel-plugin 了解更多信息。

通常你还需要启用 builtin:swc-loader 的 JSX 支持用来处理 React 组件,配置项内容可以参考:

/** @type {import('@rspack/core').Configuration}*/
module.exports = {
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            parser: {
              syntax: 'ecmascript',
              jsx: true,
            },
          },
          rspackExperiments: {
            styledComponents: {
              displayName: true,
              ssr: true,
              fileName: true,
              meaninglessFileNames: ['index', 'styles'],
              namespace: 'rspack-test',
              topLevelImportPaths: [
                '@xstyled/styled-components',
                '@xstyled/styled-components/*',
              ],
              transpileTemplateLiterals: true,
              minify: true,
              pure: true,
              cssProps: true,
            },
          },
        },
      },
    ],
  },
};