Tools Config

本章节描述了 Builder 中与底层工具有关的配置。

tools.autoprefixer

  • 类型: Object | Function
  • 默认值:
{
  flexbox: 'no-2009',
  // browserslist 取决于项目中的 browserslist 配置
  // 以及 `output.overrideBrowserslist`(优先级更高) 配置
  overrideBrowserslist: browserslist,
}

通过 tools.autoprefixer 可以修改 autoprefixer 的配置。

Object 类型

tools.autoprefixer 的值为 Object 类型时,会与默认配置通过 Object.assign 合并。比如:

export default {
  tools: {
    autoprefixer: {
      flexbox: 'no-2009',
    },
  },
};

Function 类型

tools.autoprefixer 为 Function 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果。比如:

export default {
  tools: {
    autoprefixer(config) {
      // 修改 flexbox 的配置
      config.flexbox = 'no-2009';
    },
  },
};

tools.babel

  • 类型: Object | Function
  • 默认值: undefined

通过 tools.babel 可以修改 babel-loader 的配置项。

使用场景

请留意 tools.babel 在以下使用场景中的局限性:

  • Rspack 场景:在使用 Rspack 作为打包工具时,使用 tools.babel 配置项将会明显拖慢 Rspack 构建速度。因为 Rspack 默认使用的是 SWC 编译,配置 Babel 会导致代码需要被编译两次,产生了额外的编译开销。
  • webpack + SWC 场景:在使用 webpack 作为打包工具时,如果你使用了 Builder 的 SWC 插件进行代码编译,那么 tools.babel 选项将不会生效。

Function 类型

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

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

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

TIP

以上示例仅作为参考,通常来说,你不需要手动配置 babel-plugin-import,因为 Builder 已经提供了更通用的 source.transformImport 配置。

Object 类型

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

CAUTION

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

export default {
  tools: {
    babel: {
      plugins: [
        [
          'babel-plugin-import',
          {
            libraryName: 'xxx-components',
            libraryDirectory: 'es',
            style: true,
          },
        ],
      ],
    },
  },
};

工具函数

tools.babel 为 Function 类型时,第二个参数可用的工具函数如下:

addPlugins

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

添加若干个 Babel 插件。

export default {
  tools: {
    babel(config, { addPlugins }) {
      addPlugins([
        [
          'babel-plugin-import',
          {
            libraryName: 'xxx-components',
            libraryDirectory: 'es',
            style: true,
          },
        ],
      ]);
    },
  },
};

addPresets

  • 类型: (presets: BabelPlugin[]) => void

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

export default {
  tools: {
    babel(config, { addPresets }) {
      addPresets(['@babel/preset-env']);
    },
  },
};

removePlugins

  • 类型: (plugins: string | string[]) => void

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

export default {
  tools: {
    babel(config, { removePlugins }) {
      removePlugins('babel-plugin-import');
    },
  },
};

removePresets

  • 类型: (presets: string | string[]) => void

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

export default {
  tools: {
    babel(config, { removePresets }) {
      removePresets('@babel/preset-env');
    },
  },
};

modifyPresetEnvOptions

  • 类型: (options: PresetEnvOptions) => void

修改 @babel/preset-env 的配置项,传入的配置会与默认配置进行浅层合并,比如:

export default {
  tools: {
    babel(config, { modifyPresetEnvOptions }) {
      modifyPresetEnvOptions({
        targets: {
          browsers: ['last 2 versions'],
        },
      });
    },
  },
};

modifyPresetReactOptions

  • 类型: (options: PresetReactOptions) => void

修改 @babel/preset-react 的配置项,传入的配置会与默认配置进行浅层合并,比如:

export default {
  tools: {
    babel(config, { modifyPresetReactOptions }) {
      modifyPresetReactOptions({
        pragma: 'React.createElement',
      });
    },
  },
};

addIncludes

已废弃,请使用 source.include 代替,两者功能完全一致。

addExcludes

已废弃,请使用 source.exclude 代替,两者功能完全一致。

调试 Babel 配置

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

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

# 调试开发环境
DEBUG=builder pnpm dev

# 调试生产环境
DEBUG=builder pnpm build

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

tools.bundlerChain

  • 类型: Function | undefined
  • 默认值: undefined

你可以通过 tools.bundlerChain 来修改默认的 webpack 和 Rspack 配置,它的值为 Function 类型,接收两个参数:

  • 第一个参数为 bundler-chain 对象实例,你可以通过这个实例来修改 webpack 和 Rspack 的配置。
  • 第二个参数为一个工具集合,包括envisProdCHAIN_ID 等。
什么是 BundlerChain

Bundler chain 是 webpack chain 的子集,其中包含一部分 webpack chain API,你可以用它来同时修改 webpack 和 Rspack 的配置。

通过 bundler chain 修改的配置,在 webpack 和 Rspack 构建时均可生效。需要注意的是,bundler chain 只支持修改 webpack 和 Rspack 间无差异部分的配置。如,修改 devtool 配置项(webpack 和 Rspack 的 devtool 属性值类型相同),或添加一个Rspack 兼容的 webpack 插件。

tools.bundlerChain 的执行时机早于 tools.webpackChain / tools.webpack / tools.rspack,因此会被其他几个配置中的修改所覆盖。

更多信息可参考 Rsbuild#tools.bundlerChain

tools.cssExtract

  • 类型: Object | Function
  • 默认值:
const defaultOptions = {
  // Loader 配置
  loaderOptions: {},
  // Plugin 配置
  pluginOptions: {
    // cssPath 默认为 static/css, cssFilename 默认为 [name].[contenthash:8].css
    filename: `${cssPath}/${cssFilename}`,
    chunkFilename: `${cssPath}/async/${cssFilename}`,
    ignoreOrder: true,
  },
};
  • 打包工具: 仅支持 webpack

通过 tools.cssExtract 可以更改 mini-css-extract-plugin 的配置。

Object 类型

当此值为 Object 类型时,与默认配置通过 Object.assign 合并。比如:

export default {
  tools: {
    cssExtract: {
      pluginOptions: {
        filename: 'static/css/[name].[contenthash:8].css',
      },
    },
  },
};

Function 类型

当此值为 Function 类型时,默认配置作为第一个参数传入,你可以直接修改配置对象,也可以返回一个对象作为最终配置。比如:

export default {
  tools: {
    cssExtract: config => {
      config.pluginOptions.filename = 'static/css/[name].[contenthash:8].css';
      return config;
    },
  },
};

更多配置细节可参考 mini-css-extract-plugin

tools.cssLoader

  • 类型: Object | Function
  • 默认值: undefined

通过 tools.cssLoader 可以修改 css-loader 的配置项。默认配置如下:

{
  modules: {
    auto: true,
    exportLocalsConvention: 'camelCase',
    localIdentName: config.output.cssModuleLocalIdentName,
    // isServer 表示 node (SSR) 构建
    // isWebWorker 表示 web worker 构建
    exportOnlyLocals: isServer || isWebWorker,
  },
  // 默认在开发环境下启用 CSS 的 Source Map
  sourceMap: isDev,
  // importLoaders 在编译 css 文件时为 `1`,在编译 sass/less 文件时为 `2`
  importLoaders: 1 || 2,
}
TIP

在使用 Rspack 作为打包工具时,仅支持在 disableCssExtract 时使用该配置。

修改 CSS Modules 相关配置,推荐使用 output.cssModules 配置项。

Object 类型

当此值为 Object 类型时,会与默认配置进行深层合并 (deep merge)。比如:

export default {
  tools: {
    cssLoader: {
      modules: {
        exportOnlyLocals: true,
      },
    },
  },
};

Function 类型

当此值为 Function 类型时,默认配置作为第一个参数传入,你可以直接修改配置对象,也可以返回一个对象作为最终配置。比如:

export default {
  tools: {
    cssLoader: config => {
      config.modules.exportOnlyLocals = true;
      return config;
    },
  },
};

tools.devServer

  • 类型: Object
  • 默认值: {}

通过 tools.devServer 可以修改开发环境服务器的配置。

TIP

Modern.js 中并没有直接使用 webpack-dev-server@rspack/dev-server, 而是基于 webpack-dev-middleware 实现 DevServer。

选项

after

  • 类型: Array
  • 默认值: []

添加自定义中间件,在所有开发环境中间件后执行。

export default {
  tools: {
    devServer: {
      after: [
        async (req, res, next) => {
          console.log('after dev middleware');
          next();
        },
      ],
    },
  },
};

webpack-dev-server 使用 Express 作为服务端框架。Modern.js 中没有使用任何框架,上述中间件中 reqres 都是 Node 原生对象,因此 webpack-dev-server 的 Express 中间件不一定能直接在 Modern.js 中使用。

如果要迁移 webpack-dev-server 中使用的 Express 中间件,可以使用以下方式,将 Express app 作为中间件传入:

import expressMiddleware from 'my-express-middleware';
import express from 'express';

// 初始化 Express app
const app = express();
app.use(expressMiddleware);

export default {
  tools: {
    devServer: {
      after: [app],
    },
  },
};

before

  • 类型: Array
  • 默认值: []

添加自定义中间件,在所有开发环境中间件前执行。

export default {
  tools: {
    devServer: {
      before: [
        async (req, res, next) => {
          console.log('before dev middleware');
          next();
        },
      ],
    },
  },
};

client

  • 类型:
{
    /** 指定协议名称 */
    protocol?: string;
    /** 事件流路径 */
    path?: string;
    /** 指定监听请求的端口号 */
    port?: string;
    /** 指定要使用的 host */
    host?: string;
}
  • 默认值:
const defaultConfig = {
  path: '/webpack-hmr',
  // By default it is set to the port number of the dev server
  port: '',
  // By default it is set to "location.hostname"
  host: '',
  // By default it is set to "location.protocol === 'https:' ? 'wss' : 'ws'""
  protocol: '',
};

对应 HMR 客户端的配置,通常用于设置 HMR 对应的 WebSocket URL。

compress

  • 类型: boolean
  • 默认值: true

是否对静态资源启用 gzip 压缩。

如果你需要禁用 gzip 压缩,可以将 compress 设置为 false

export default {
  tools: {
    devServer: {
      compress: false,
    },
  },
};

devMiddleware

  • 类型:
{
  writeToDisk: boolean | ((filename: string) => boolean);
}
  • 默认值:
{
  writeToDisk: (file: string) => !file.includes('.hot-update.'),
}

devMiddleware 配置项。当前配置是 webpack-dev-middleware 配置项的子集.

headers

  • 类型: Record<string, string>
  • 默认值: undefined

设置自定义响应头。

export default {
  tools: {
    devServer: {
      headers: {
        'X-Custom-Foo': 'bar',
      },
    },
  },
};

historyApiFallback

  • 类型: boolean | ConnectHistoryApiFallbackOptions
  • 默认值: false

在需要对一些 404 响应或其他请求提供替代页面的场景,可通过 devServer.historyApiFallback 进行设置:

export default {
  tools: {
    devServer: {
      historyApiFallback: true,
    },
  },
};

更多选项和详细信息可参考 connect-history-api-fallback 文档。

hot

  • 类型: boolean
  • 默认值: true

是否开启 Hot Module Replacement 热更新能力。

https

  • 类型: boolean | { key: string; cert: string }
  • 默认值: false

默认情况下,DevServer 会启用 HTTP 服务器。通过设置 devServer.httpstrue 将开启对 HTTPS 的支持,同时会禁用 HTTP 服务器。

你也可以手动传入 HTTPS 服务器所需要的证书和对应的私钥:

export default {
  tools: {
    devServer: {
      https: {
        key: fs.readFileSync('certificates/private.pem'),
        cert: fs.readFileSync('certificates/public.pem'),
      },
    },
  },
};

liveReload

  • 类型: boolean
  • 默认值: true

默认情况下,当监听到文件变化时,DevServer 将会刷新页面(为使 liveReload 能够生效,devServer.hot 配置项应当禁用)。通过设置 devServer.liveReloadfalse 可以关闭该行为。

setupMiddlewares

  • 类型:
Array<
  (
    middlewares: {
      unshift: (...handlers: RequestHandler[]) => void;
      push: (...handlers: RequestHandler[]) => void;
    },
    server: {
      sockWrite: (
        type: string,
        data?: string | boolean | Record<string, any>,
      ) => void;
    },
  ) => void
>;
  • 默认值: undefined

提供执行自定义函数和应用自定义中间件的能力。

几种不同中间件之间的执行顺序是: devServer.before => unshift => 内置中间件 => push => devServer.after

export default {
  tools: {
    devServer: {
      setupMiddlewares: [
        (middlewares, server) => {
          middlewares.unshift((req, res, next) => {
            next();
          });

          middlewares.push((req, res, next) => {
            next();
          });
        },
      ],
    },
  },
};

一些特殊场景需求可能需要使用服务器 API:

  • sockWrite。允许向 hmr 客户端传递一些消息,hmr 客户端将根据接收到的消息类型进行不同的处理。如果你发送一个 "content-changed " 的消息,页面将会重新加载。
export default {
  tools: {
    devServer: {
      setupMiddlewares: [
        (middlewares, server) => {
          // 添加自定义 watcher 并在文件更新时触发页面刷新
          watcher.on('change', changed => {
            server.sockWrite('content-changed');
          });
        },
      ],
    },
  },
};

proxy

  • 类型: Record<string, string> | Record<string, ProxyDetail>
  • 默认值: undefined

代理请求到指定的服务上。

export default {
  tools: {
    devServer: {
      proxy: {
        '/api': 'http://localhost:3000',
      },
    },
  },
};

此时,/api/users 请求将会代理到 http://localhost:3000/api/users。

如果你不想传递 /api,可以通过 pathRewrite 重写请求路径:

export default {
  tools: {
    devServer: {
      proxy: {
        '/api': {
          target: 'http://localhost:3000',
          pathRewrite: { '^/api': '' },
        },
      },
    },
  },
};

DevServer Proxy 基于 http-proxy-middleware 实现。你可以使用 http-proxy-middleware 的所有配置项,具体可以查看文档。

DevServer Proxy 完整类型定义为:

import type { Options as HttpProxyOptions } from 'http-proxy-middleware';

type Filter = string | string[] | ((pathname: string, req: Request) => boolean);

type ProxyDetail = HttpProxyOptions & {
  bypass?: (
    req: IncomingMessage,
    res: ServerResponse,
    proxyOptions: ProxyOptions,
  ) => string | undefined | null | false;
  context?: Filter;
};

type ProxyOptions =
  | Record<string, string>
  | Record<string, ProxyDetail>
  | ProxyDetail[]
  | ProxyDetail;

除了 http-proxy-middleware 的选项外,还支持 bypass 和 context 两个配置项:

  • bypass:根据函数的返回值绕过代理。
    • 返回 nullundefined 会继续用代理处理请求。
    • 返回 false 会返回 404 错误。
    • 返回一个具体的服务路径,将会使用此路径替代原请求路径。
  • context:如果你想代理多个特定的路径到同一个目标,你可以使用 context 配置项。
// 自定义 bypass 方法
export default {
  tools: {
    devServer: {
      proxy: {
        '/api': {
          target: 'http://localhost:3000',
          bypass: function (req, res, proxyOptions) {
            if (req.headers.accept.indexOf('html') !== -1) {
              console.log('Skipping proxy for browser request.');
              return '/index.html';
            }
          },
        },
      },
    },
  },
};
// 代理多个路径到同一个目标
export default {
  tools: {
    devServer: {
      proxy: [
        {
          context: ['/auth', '/api'],
          target: 'http://localhost:3000',
        },
      ],
    },
  },
};

watch

  • 类型: boolean
  • 默认值: true

是否监听 mock/server/api/ 等目录的文件变化。

tools.htmlPlugin

  • 类型: false | Object | Function
  • 默认值:
const defaultHtmlPluginOptions = {
  inject, // 对应 html.inject 配置项
  favicon, // 对应 html.favicon 配置项
  filename, // 基于 output.distPath 和 entryName 生成
  template, // 默认为内置的 HTML 模板路径
  templateParameters, // 对应 html.templateParameters 配置项
  chunks: [entryName],
  minify: { // 基于 output.disableMinimize 生成
    removeComments: false,
    useShortDoctype: true,
    keepClosingSlash: true,
    collapseWhitespace: true,
    removeRedundantAttributes: true,
    removeScriptTypeAttributes: true,
    removeStyleLinkTypeAttributes: true,
    removeEmptyAttributes: true,
    minifyJS, // 基于 output.charset 和 tools.terser.terserOptions 生成
    minifyCSS: true,
    minifyURLs: true,
  },
};

通过 tools.htmlPlugin 可以修改 html-webpack-plugin@rspack/plugin-html 的配置项。

Object 类型

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

export default {
  tools: {
    htmlPlugin: {
      scriptLoading: 'blocking',
    },
  },
};

Function 类型

tools.htmlPlugin 为 Function 类型时:

  • 第一个参数是默认配置的对象,可以直接修改该对象。
  • 第二个参数是也是一个对象,包含了 entry 的名称和 entry 的值。
  • 函数可以 return 一个新的对象作为最终的配置。
export default {
  tools: {
    htmlPlugin(config, { entryName, entryValue }) {
      if (entryName === 'main') {
        config.scriptLoading = 'blocking';
      }
    },
  },
};

Boolean 类型

tools.htmlPlugin 配置为 false,可以禁用默认的 html-webpack-plugin 插件。

export default {
  tools: {
    htmlPlugin: false,
  },
};

禁用 JS / CSS 压缩

默认情况下,Builder 会在生产环境构建时压缩 HTML 内的 JavaScript / CSS 代码,从而提升页面性能。此能力通常在使用自定义模版或插入自定义脚本时会有帮助。然而,当开启 output.enableInlineScriptsoutput.enableInlineStyles 时,会出现对 inline JavaScript / CSS 代码重复压缩的情况,对构建性能会有一定影响。你可以通过修改 tools.htmlPlugin.minify 配置项来修改默认的压缩行为。

export default {
  tools: {
    htmlPlugin: config => {
      if (typeof config.minify === 'object') {
        config.minify.minifyJS = false;
        config.minify.minifyCSS = false;
      }
    },
  },
};

tools.less

  • 类型: Object | Function
  • 默认值:
const defaultOptions = {
  lessOptions: {
    javascriptEnabled: true,
  },
  // 默认在开发环境下启用 CSS 的 Source Map
  sourceMap: isDev,
};

你可以通过 tools.less 修改 less-loader 的配置。

Object 类型

tools.less 的值为 Object 类型时,会与默认配置通过 Object.assign 进行浅层合并,值得注意的是,lessOptions 会通过 deepMerge 进行深层合并。

export default {
  tools: {
    less: {
      lessOptions: {
        javascriptEnabled: false,
      },
    },
  },
};

Function 类型

tools.less 为 Function 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果,第二个参数提供了一些可以直接调用的工具函数:

export default {
  tools: {
    less(config) {
      // 修改 lessOptions 配置
      config.lessOptions = {
        javascriptEnabled: false,
      };
    },
  },
};

修改 Less 版本

在某些场景下,如果你需要使用特定的 Less 版本,而不是使用 Builder 内置的 Less v4,可以在项目中安装需要使用的 Less 版本,并通过 less-loaderimplementation 选项设置。

export default {
  tools: {
    less: {
      implementation: require('less'),
    },
  },
};

工具函数

addExcludes

  • 类型: (excludes: RegExp | RegExp[]) => void

用来指定 less-loader 不编译哪些文件,你可以传入一个或多个正则表达式来匹配 less 文件的路径。例如:

export default {
  tools: {
    less(config, { addExcludes }) {
      addExcludes(/node_modules/);
    },
  },
};

tools.minifyCss

  • 类型: Object | Function | undefined
  • 默认值:
const defaultOptions = {
  minimizerOptions: {
    preset: [
      'default',
      {
        mergeLonghand: false,
      },
    ],
  },
};

在生产环境构建时,Builder 会通过 css-minimizer-webpack-plugin 对 CSS 代码进行压缩优化。可以通过 tools.minifyCss 修改 css-minimizer-webpack-plugin 的配置。

Object 类型

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

例如下面修改 cssnanopreset 配置:

export default {
  tools: {
    minifyCss: {
      minimizerOptions: {
        preset: require.resolve('cssnano-preset-simple'),
      },
    },
  },
};

Function 类型

tools.minifyCss 配置为 Function 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果。

export default {
   tools: {
    minifyCss: options => {
      options.minimizerOptions = {
        preset: require.resolve('cssnano-preset-simple'),
      },
    }
  }
};

tools.postcss

  • 类型: Object | Function
  • 默认值:
const defaultOptions = {
  postcssOptions: {
    plugins: [
      // 以下插件默认启用
      require('postcss-nesting'),
      require('postcss-media-minmax'),
      require('postcss-flexbugs-fixes'),
      require('autoprefixer')({
        flexbox: 'no-2009',
      }),
      // 以下插件仅在需要兼容低版本浏览器时启用
      require('postcss-custom-properties'),
      require('postcss-initial'),
      require('postcss-page-break'),
      require('postcss-font-variant'),
    ],
    // 默认在开发环境下启用 CSS 的 Source Map
    sourceMap: isDev,
  },
};

Builder 默认集成 PostCSS,你可以通过 tools.postcsspostcss-loader 进行配置。

Function 类型

值为 Function 类型时,内部默认配置作为第一参数传入,可以直接修改配置对象不做返回,也可以返回一个对象作为最终结果;第二个参数为修改 postcss-loader 配置的工具函数集合。

例如,需要在原有插件的基础上新增一个 PostCSS 插件,在 postcssOptions.plugins 数组中 push 一个新的插件即可:

export default {
  tools: {
    postcss: opts => {
      opts.postcssOptions.plugins.push(require('postcss-px-to-viewport'));
    },
  },
};

需要给 PostCSS 插件传递参数时,可以通过函数参数的形式进行传入:

export default {
  tools: {
    postcss: opts => {
      const viewportPlugin = require('postcss-px-to-viewport')({
        viewportWidth: 375,
      });
      opts.postcssOptions.plugins.push(viewportPlugin);
    },
  },
};

tools.postcss 可以返回一个配置对象,并完全替换默认配置:

export default {
  tools: {
    postcss: () => {
      return {
        postcssOptions: {
          plugins: [require('postcss-px-to-viewport')],
        },
      };
    },
  },
};

Object 类型

当此值为 Object 类型时,与默认配置通过 Object.assign 合并。注意 Object.assign 是浅拷贝,会完全覆盖内置的 plugins 数组,请谨慎使用。

export default {
  tools: {
    postcss: {
      // 由于使用 `Object.assign` 合并,因此默认的 postcssOptions 会被覆盖。
      postcssOptions: {
        plugins: [require('postcss-px-to-viewport')],
      },
    },
  },
};

工具函数

addPlugins

  • 类型: (plugins: PostCSSPlugin | PostCSSPlugin[]) => void

用于添加额外的 PostCSS 插件,你可以传入单个 PostCSS 插件,也可以传入 PostCSS 插件数组。

export default {
  tools: {
    postcss: (config, { addPlugins }) => {
      // 添加一个插件
      addPlugins(require('postcss-preset-env'));
      // 批量添加插件
      addPlugins([require('postcss-preset-env'), require('postcss-import')]);
    },
  },
};
TIP

Builder 中使用的 PostCSS 版本为 v8,当你引入社区中的 PostCSS 插件时,请注意版本是否适配,部分旧版本插件可能无法在 PostCSS v8 下运行。

tools.pug

  • 类型: true | Object | Function | undefined
  • 默认值: false

配置 Pug 模板引擎。

Boolean 类型

Builder 默认不启用 Pug 模板引擎,你可以将 tools.pug 设置为 true 来启用它。

export default {
  tools: {
    pug: true,
  },
};

启用后,你可以在 html.template 中指定使用 index.pug 作为模板文件。

Object 类型

tools.terser 的值为 Object 类型时,可以配置 Pug 模板引擎的选项:

export default {
  tools: {
    pug: {
      doctype: 'xml',
    },
  },
};

详细参数请查看 Pug API Reference

Function 类型

tools.pug 配置为 Function 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果。

export default {
  tools: {
    pug(config) {
      config.doctype = 'xml';
    },
  },
};

tools.sass

  • 类型: Object | Function
  • 默认值:
const defaultOptions = {
  // 默认在开发环境下启用 CSS 的 Source Map
  sourceMap: isDev,
};

你可以通过 tools.sass 修改 sass-loader 的配置。

Object 类型

tools.sass 的值为 Object 类型时,会与默认配置通过 Object.assign 进行浅层合并,值得注意的是,sassOptions 会通过 deepMerge 进行深层合并。

export default {
  tools: {
    sass: {
      sourceMap: true,
    },
  },
};

Function 类型

tools.sass 为 Function 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果,第二个参数提供了一些可以直接调用的工具函数:

export default {
  tools: {
    sass(config) {
      // 修改 sourceMap 配置
      config.additionalData = async (content, loaderContext) => {
        // ...
      };
    },
  },
};

修改 Sass 版本

在某些场景下,如果你需要使用特定的 Sass 版本,而不是使用 Builder 内置的 Dart Sass v1,可以在项目中安装需要使用的 Sass 版本,并通过 sass-loaderimplementation 选项设置。

export default {
  tools: {
    sass: {
      implementation: require('sass'),
    },
  },
};

工具函数

addExcludes

  • 类型: (excludes: RegExp | RegExp[]) => void

用来指定 sass-loader 不编译哪些文件,你可以传入一个或多个正则表达式来匹配 sass 文件的路径。例如:

export default {
  tools: {
    sass(config, { addExcludes }) {
      addExcludes(/node_modules/);
    },
  },
};

tools.styleLoader

  • 类型: Object | Function
  • 默认值: {}

通过 tools.styleLoader 可以设置 style-loader 的配置项。

值得注意的是,Builder 默认不会开启 style-loader,你可以通过 output.disableCssExtract 配置项来开启它。

Object 类型

当此值为 Object 类型时,与默认配置通过 Object.assign 合并。比如:

export default {
  tools: {
    styleLoader: {
      insert: 'head',
    },
  },
};

Function 类型

当此值为 Function 类型时,默认配置作为第一个参数传入,你可以直接修改配置对象,也可以返回一个对象作为最终配置。比如:

export default {
  tools: {
    styleLoader: config => {
      config.insert = 'head';
      return config;
    },
  },
};

tools.styledComponents

  • 类型: Object | Function | false
  • 默认值:
{
  displayName: true,
  // 在 SSR 构建中 isSSR 为 true
  ssr: isSSR,
  // 在生产环境构建时启用 `pure` 来优化包体积
  pure: isProd,
  transpileTemplateLiterals: true,
}

对应 babel-plugin-styled-components 或使用 SWC 时 @swc/plugin-styled-components 的配置。 值为 Object 类型时,利用 Object.assign 函数与默认配置合并。比如:

export default {
  tools: {
    styledComponents: {
      pure: false,
    },
  },
};

值为 Function 类型时,第一个参数为默认配置,第二个参数提供了一些可以直接调用的工具函数:

export default {
  tools: {
    styledComponents(config) {
      // 修改 pure 配置
      config.pure = false;
    },
  },
};

该特性默认启用,你可以配置 tools.styledComponentsfalse 来关闭该行为,关闭后可以提升编译性能:

export default {
  tools: {
    styledComponents: false,
  },
};

tools.terser

  • 类型: Object | Function | undefined
  • 默认值:
const defaultTerserOptions = {
  terserOptions: {
    mangle: {
      safari10: true,
    },
  },
};
  • 打包工具: 仅支持 webpack

在生产环境构建时,Builder 会通过 terser-webpack-plugin 对 JavaScript 代码进行压缩优化。可以通过 tools.terser 修改 terser-webpack-plugin 的配置。

Object 类型

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

例如通过 exclude 排除部分文件的压缩:

export default {
  tools: {
    terser: {
      exclude: /\/excludes/,
    },
  },
};

Function 类型

tools.terser 配置为 Function 类型时,默认配置作为第一个参数传入,可以直接修改配置对象,也可以返回一个值作为最终结果。

export default {
  tools: {
    terser: opts => {
      opts.exclude = /\/excludes/;
    },
  },
};
禁用代码压缩

如果你需要禁用代码压缩,可以使用 output.disableMinimize 配置项。

tools.tsLoader

  • 类型: Object | Function | undefined
  • 默认值: undefined
  • 打包工具: 仅支持 webpack
不再推荐使用 ts-loader

使用 babel-loaderRspack 转译 TypeScript 代码的性能明显优于 ts-loader 且能够使用更多拓展能力。

启用 ts-loader 时将无法使用 source.transformImporttools.styledComponents 等由 Babel 和 SWC 提供支持的能力。

项目中默认不开启 ts-loader,当 tools.tsLoader 不为 undefined 则表示开启 ts-loader,同时禁用 babel-loader 对 TypeScript 的编译。

Object 类型

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

默认配置如下:

{
  "compilerOptions": {
    "target": "es5",
    "module": "ESNext"
  },
  "transpileOnly": true,
  "allowTsInNodeModules": true
}

你可以通过 tools.tsLoader 配置项来覆盖默认配置:

export default {
  tools: {
    tsLoader: {
      allowTsInNodeModules: false,
    },
  },
};

Function 类型

当此值为 Function 类型时,默认配置作为第一参数传入,可以直接修改配置对象,也可以返回一个对象作为最终配置;第二个参数为修改 ts-loader 配置工具函数集合:

export default {
  tools: {
    tsLoader: opts => {
      opts.allowTsInNodeModules = false;
    },
  },
};

工具函数

addIncludes

已废弃,请使用 source.include 代替,两者功能完全一致。

addExcludes

已废弃,请使用 source.exclude 代替,两者功能完全一致。

tools.tsChecker

  • 类型: Object | Function
  • 默认值:
const defaultOptions = {
  typescript: {
    // avoid OOM issue
    memoryLimit: 8192,
    // use tsconfig of user project
    configFile: tsconfigPath,
    // use typescript of user project
    typescriptPath: require.resolve('typescript'),
  },
  issue: {
    exclude: [
      { file: '**/*.(spec|test).ts' },
      { file: '**/node_modules/**/*' },
    ],
  },
  logger: {
    log() {
      // do nothing
      // we only want to display error messages
    },
    error(message: string) {
      console.error(message.replace(/ERROR/g, 'Type Error'));
    },
  },
},

默认情况下,Builder 会开启 fork-ts-checker-webpack-plugin 进行类型检查。你可以通过 output.disableTsChecker 配置项来关闭类型检查。

Object 类型

tsChecker 的值为 Object 类型时,会与默认配置进行深层合并。

export default {
  tools: {
    tsChecker: {
      issue: {
        exclude: [{ file: '**/some-folder/**/*.ts' }],
      },
    },
  },
};

Function 类型

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

export default {
  tools: {
    tsChecker(options) {
      (options?.issue?.exclude as unknown[]).push({
        file: '**/some-folder/**/*.ts',
      });
    },
  },
};

tools.webpack

  • 类型: Object | Function | undefined
  • 默认值: undefined
  • 打包工具: 仅支持 webpack

tools.webpack 选项用于配置原生的 webpack

tools.bundlerChain 同样可以修改 webpack 配置,并且功能更加强大,建议优先使用 tools.bundlerChain

Object 类型

tools.webpack 可以配置为一个对象,这个对象将会和内置的 webpack 配置通过 webpack-merge 进行深层合并。

比如添加 resolve.alias 配置:

export default {
  tools: {
    webpack: {
      resolve: {
        alias: {
          '@util': 'src/util',
        },
      },
    },
  },
};

Function 类型

tools.webpack 也可以配置为一个函数,这个函数的第一个入参为内置的 webpack 配置对象,你可以对这个对象进行修改,然后返回一份新的配置。比如:

export default {
  tools: {
    webpack: config => {
      config.resolve.alias['@util'] = 'src/util';
      return config;
    },
  },
};
TIP

tools.webpack 函数返回的对象会直接作为最终使用的 webpack 配置,不会再与内置的 webpack 配置进行合并。

工具集合

这个函数的第二个参数是一个对象,包含了一些工具函数和属性,详情如下:

env

  • 类型: 'development' | 'production' | 'test'

通过 env 参数可以判断当前环境为 development、production 还是 test。比如:

export default {
  tools: {
    webpack: (config, { env }) => {
      if (env === 'development') {
        config.devtool = 'cheap-module-eval-source-map';
      }
      return config;
    },
  },
};

isProd

  • 类型: boolean

通过 isProd 参数可以判断当前环境是否为 production。比如:

export default {
  tools: {
    webpack: (config, { isProd }) => {
      if (isProd) {
        config.devtool = 'source-map';
      }
      return config;
    },
  },
};

target

  • 类型: 'web' | 'node' | 'modern-web' | 'web-worker'

通过 target 参数可以判断当前构建的目标运行时环境。比如:

export default {
  tools: {
    webpack: (config, { target }) => {
      if (target === 'node') {
        // ...
      }
      return config;
    },
  },
};

isServer

  • 类型: boolean

判断当前构建的目标运行时环境是否为 node,等价于 target === 'node'

export default {
  tools: {
    webpack: (config, { isServer }) => {
      if (isServer) {
        // ...
      }
      return config;
    },
  },
};

isWebWorker

  • 类型: boolean

判断当前构建的目标运行时环境是否为 web-worker,等价于 target === 'web-worker'

export default {
  tools: {
    webpack: (config, { isWebWorker }) => {
      if (isWebWorker) {
        // ...
      }
      return config;
    },
  },
};

webpack

  • 类型: typeof import('webpack')

通过这个参数你可以拿到 webpack 实例。比如:

export default {
  tools: {
    webpack: (config, { webpack }) => {
      config.plugins.push(new webpack.ProgressPlugin());
      return config;
    },
  },
};

HtmlWebpackPlugin

  • 类型: typeof import('html-webpack-plugin')

通过这个参数你可以拿到 HtmlWebpackPlugin 实例。

export default {
  tools: {
    webpack: (chain, { HtmlWebpackPlugin }) => {
      console.log(HtmlWebpackPlugin);
    },
  },
};

addRules

  • 类型: (rules: RuleSetRule | RuleSetRule[]) => void

添加额外的 webpack rules

示例:

export default {
  tools: {
    webpack: (config, { addRules }) => {
      // 添加单条规则
      addRules({
        test: /\.foo/,
        loader: require.resolve('foo-loader'),
      });

      // 以数组形式添加多条规则
      addRules([
        {
          test: /\.foo/,
          loader: require.resolve('foo-loader'),
        },
        {
          test: /\.bar/,
          loader: require.resolve('bar-loader'),
        },
      ]);
    },
  },
};

prependPlugins

  • 类型: (plugins: WebpackPluginInstance | WebpackPluginInstance[]) => void

在内部 webpack 插件数组头部添加额外的插件,数组头部的插件会优先执行。

export default {
  tools: {
    webpack: (config, { prependPlugins, webpack }) => {
      // 添加单个插件
      prependPlugins(
        new webpack.BannerPlugin({
          banner: 'hello world!',
        }),
      );

      // 以数组形式添加多个插件
      prependPlugins([new PluginA(), new PluginB()]);
    },
  },
};

appendPlugins

  • 类型: (plugins: WebpackPluginInstance | WebpackPluginInstance[]) => void

在内部 webpack 插件数组尾部添加额外的插件,数组尾部的插件会在最后执行。

export default {
  tools: {
    webpack: (config, { appendPlugins, webpack }) => {
      // 添加单个插件
      appendPlugins([
        new webpack.BannerPlugin({
          banner: 'hello world!',
        }),
      ]);

      // 以数组形式添加多个插件
      appendPlugins([new PluginA(), new PluginB()]);
    },
  },
};

removePlugin

  • 类型: (name: string) => void

删除内部的 webpack 插件,参数为该插件的 constructor.name

例如,删除内部的 fork-ts-checker-webpack-plugin

export default {
  tools: {
    webpack: (config, { removePlugin }) => {
      removePlugin('ForkTsCheckerWebpackPlugin');
    },
  },
};

mergeConfig

  • 类型: (...configs: WebpackConfig[]) => WebpackConfig

用于合并多份 webpack 配置,等价于 webpack-merge

export default {
  tools: {
    webpack: (config, { mergeConfig }) => {
      return mergeConfig(config, {
        devtool: 'eval',
      });
    },
  },
};

getCompiledPath

  • 类型: (name: string) => string

获取 builder 内置依赖的所在路径,等价于 webpackChain#getCompiledPath

tools.webpackChain

  • 类型: Function | undefined
  • 默认值: undefined
  • 打包工具: 仅支持 webpack

你可以通过 tools.webpackChain 来修改默认的 webpack 配置,它的值为 Function 类型,接收两个参数:

  • 第一个参数为 webpack-chain 对象实例,你可以通过这个实例来修改默认的 webpack 配置。
  • 第二个参数为一个工具集合,包括envisProdCHAIN_ID 等。

相比于 tools.webpackwebpack-chain 不仅支持链式调用,而且能够基于别名来定位到内置的 Rule 或 Plugin,从而实现精准的配置修改。我们推荐使用 tools.webpackChain 来代替 tools.webpack

tools.webpackChain 的执行时机早于 tools.webpack,因此会被 tools.webpack 中的修改所覆盖。

工具集合

env

  • 类型: 'development' | 'production' | 'test'

通过 env 参数可以判断当前环境为 development、production 还是 test。比如:

export default {
  tools: {
    webpackChain: (chain, { env }) => {
      if (env === 'development') {
        chain.devtool('cheap-module-eval-source-map');
      }
    },
  },
};

isProd

  • 类型: boolean

通过 isProd 参数可以判断当前环境是否为 production。比如:

export default {
  tools: {
    webpackChain: (chain, { isProd }) => {
      if (isProd) {
        chain.devtool('source-map');
      }
    },
  },
};

target

  • 类型: 'web' | 'node' | 'modern-web' | 'web-worker'

通过 target 参数可以判断当前构建的目标运行时环境。比如:

export default {
  tools: {
    webpackChain: (chain, { target }) => {
      if (target === 'node') {
        // ...
      }
    },
  },
};

isServer

  • 类型: boolean

判断当前构建的目标运行时环境是否为 node,等价于 target === 'node'

export default {
  tools: {
    webpackChain: (chain, { isServer }) => {
      if (isServer) {
        // ...
      }
    },
  },
};

isWebWorker

  • 类型: boolean

判断当前构建的目标运行时环境是否为 web-worker,等价于 target === 'web-worker'

export default {
  tools: {
    webpackChain: (chain, { isWebWorker }) => {
      if (isWebWorker) {
        // ...
      }
    },
  },
};

webpack

  • 类型: typeof import('webpack')

通过这个参数你可以拿到 webpack 实例。比如:

export default {
  tools: {
    webpackChain: (chain, { webpack }) => {
      chain.plugin('my-progress').use(webpack.ProgressPlugin);
    },
  },
};

HtmlWebpackPlugin

  • 类型: typeof import('html-webpack-plugin')

通过这个参数你可以拿到 HtmlWebpackPlugin 实例。

export default {
  tools: {
    webpackChain: (chain, { HtmlWebpackPlugin }) => {
      console.log(HtmlWebpackPlugin);
    },
  },
};

getCompiledPath

  • 类型: (name: string) => string

获取 builder 内置依赖的所在路径,例如:

  • sass
  • sass-loader
  • less
  • less-loader
  • css-loader
  • ...

该方法通常在需要与 builder 复用同一份依赖时会被用到。

TIP

Builder 内部依赖会随着版本迭代而发生变化,例如产生大版本变更。在非必要的情况下,请避免使用此 API。

export default {
  tools: {
    webpackChain: (chain, { getCompiledPath }) => {
      const loaderPath = getCompiledPath('less-loader');
      // ...
    },
  },
};

CHAIN_ID

Builder 中预先定义了一些常用的 Chain ID,你可以通过这些 ID 来定位到内置的 Rule 或 Plugin。

TIP

请留意,下列的一部分 Rule 或 Plugin 并不是默认存在的,当你开启特定配置项、或是注册某些插件后,它们才会被包含在 webpack 配置中。

比如,RULE.STYLUS 仅在注册了 Stylus 插件后才会存在。

CHAIN_ID.RULE

ID 描述
RULE.MJS 处理 mjs 的规则
RULE.JS 处理 js 的规则
RULE.TS 处理 ts 的规则
RULE.CSS 处理 css 的规则
RULE.LESS 处理 less 的规则
RULE.SASS 处理 sass 的规则
RULE.STYLUS 处理 stylus 的规则(依赖 Stylus 插件
RULE.SVG Rule for svg
RULE.PUG 处理 pug 的规则
RULE.TOML 处理 toml 的规则
RULE.YAML 处理 yaml 的规则
RULE.WASM 处理 wasm 的规则
RULE.NODE 处理 node 的规则
RULE.FONT 处理字体的规则
RULE.IMAGE 处理图片的规则
RULE.MEDIA 处理媒体资源的规则

CHAIN_ID.ONE_OF

通过 ONE_OF.XXX 可以匹配到规则数组中的某一类规则。

ID 描述
ONE_OF.SVG 处理 SVG 的规则,在 data URI 和单独文件之间自动选择
ONE_OF.SVG_URL 处理 SVG 的规则,输出为单独文件
ONE_OF.SVG_INLINE 处理 SVG 的规则,作为 data URI 内联到 bundle 中
ONE_OF.SVG_ASSETS 处理 SVG 的规则,在 data URI 和单独文件之间自动选择

CHAIN_ID.USE

通过 USE.XXX 可以匹配到对应的 loader。

ID 描述
USE.TS 对应 ts-loader
USE.CSS 对应 css-loader
USE.LESS 对应 less-loader
USE.SASS 对应 sass-loader
USE.STYLUS 对应 stylus-loader
USE.PUG 对应 pug-loader
USE.VUE 对应 vue-loader
USE.TOML 对应 toml-loader
USE.YAML 对应 yaml-loader
USE.NODE 对应 node-loader
USE.URL 对应 url-loader
USE.SVGR 对应 @svgr/webpack
USE.BABEL 对应 babel-loader
USE.STYLE 对应 style-loader
USE.POSTCSS 对应 postcss-loader
USE.CSS_MODULES_TS 对应 css-modules-typescript-loader
USE.MINI_CSS_EXTRACT 对应 mini-css-extract-plugin.loader
USE.RESOLVE_URL_LOADER_FOR_SASS 对应 resolve-url-loader

CHAIN_ID.PLUGIN

通过 PLUGIN.XXX 可以匹配到对应的 plugin。

ID 描述
PLUGIN.HMR 对应 HotModuleReplacementPlugin
PLUGIN.COPY 对应 CopyWebpackPlugin
PLUGIN.HTML 对应 HtmlWebpackPlugin,使用时需要拼接 entry 名称:${PLUGIN.HTML}-${entryName}
PLUGIN.DEFINE 对应 DefinePlugin
PLUGIN.IGNORE 对应 IgnorePlugin
PLUGIN.BANNER 对应 BannerPlugin
PLUGIN.PROGRESS 对应 Webpackbar
PLUGIN.APP_ICON 对应 AppIconPlugin
PLUGIN.MANIFEST 对应 WebpackManifestPlugin
PLUGIN.TS_CHECKER 对应 ForkTsCheckerWebpackPlugin
PLUGIN.INLINE_HTML 对应 InlineChunkHtmlPlugin
PLUGIN.BUNDLE_ANALYZER 对应 WebpackBundleAnalyzer
PLUGIN.MINI_CSS_EXTRACT 对应 MiniCssExtractPlugin
PLUGIN.VUE_LOADER_PLUGIN 对应 VueLoaderPlugin
PLUGIN.REACT_FAST_REFRESH 对应 ReactFastRefreshPlugin
PLUGIN.NODE_POLYFILL_PROVIDE 对应处理 node polyfill 的 ProvidePlugin
PLUGIN.SUBRESOURCE_INTEGRITY 对应 webpack-subresource-integrity
PLUGIN.ASSETS_RETRY 对应 Builder 中的 webpack 静态资源重试插件 WebpackAssetsRetryPlugin
PLUGIN.AUTO_SET_ROOT_SIZE 对应 Builder 中的自动设置根字体大小插件 AutoSetRootSizePlugin

CHAIN_ID.MINIMIZER

通过 MINIMIZER.XXX 可以匹配到对应的压缩工具。

ID 描述
MINIMIZER.JS 对应 TerserWebpackPlugin
MINIMIZER.CSS 对应 CssMinimizerWebpackPlugin
MINIMIZER.ESBUILD 对应 ESBuildPlugin
MINIMIZER.SWC 对应 SwcWebpackPlugin

使用示例

使用示例可参考:WebpackChain 使用示例

tools.rspack

  • 类型: Object | Function | undefined
  • 默认值: undefined
  • 打包工具: 仅支持 Rspack

tools.rspack 选项用于配置原生的 Rspack

Object 类型

tools.rspack 可以配置为一个对象,这个对象将会和内置的 Rspack 配置通过 webpack-merge 进行深层合并。

比如添加 resolve.alias 配置:

export default {
  tools: {
    rspack: {
      resolve: {
        alias: {
          '@util': 'src/util',
        },
      },
    },
  },
};

Function 类型

tools.rspack 也可以配置为一个函数,这个函数接收一个参数,即内置的 Rspack 配置对象,你可以对这个对象进行修改,然后返回一份新的配置。比如:

export default {
  tools: {
    rspack: config => {
      config.resolve.alias['@util'] = 'src/util';
      return config;
    },
  },
};
TIP

tools.rspack 函数返回的对象会直接作为最终使用的 Rspack 配置,不会再与内置的 Rspack 配置进行合并。

工具集合

这个函数的第二个参数是一个对象,包含了一些工具函数和属性,详情如下:

env

  • 类型: 'development' | 'production' | 'test'

通过 env 参数可以判断当前环境为 development、production 还是 test。比如:

export default {
  tools: {
    rspack: (config, { env }) => {
      if (env === 'development') {
        config.devtool = 'cheap-module-eval-source-map';
      }
      return config;
    },
  },
};

isProd

  • 类型: boolean

通过 isProd 参数可以判断当前环境是否为 production。比如:

export default {
  tools: {
    rspack: (config, { isProd }) => {
      if (isProd) {
        config.devtool = 'source-map';
      }
      return config;
    },
  },
};

target

  • 类型: 'web' | 'node' | 'modern-web' | 'web-worker'

通过 target 参数可以判断当前构建的目标运行时环境。比如:

export default {
  tools: {
    rspack: (config, { target }) => {
      if (target === 'node') {
        // ...
      }
      return config;
    },
  },
};

isServer

  • 类型: boolean

判断当前构建的目标运行时环境是否为 node,等价于 target === 'node'

export default {
  tools: {
    rspack: (config, { isServer }) => {
      if (isServer) {
        // ...
      }
      return config;
    },
  },
};

isWebWorker

  • 类型: boolean

判断当前构建的目标运行时环境是否为 web-worker,等价于 target === 'web-worker'

export default {
  tools: {
    rspack: (config, { isWebWorker }) => {
      if (isWebWorker) {
        // ...
      }
      return config;
    },
  },
};

rspack

  • 类型: typeof import('@rspack/core')

通过这个参数你可以拿到 Rspack 实例。比如:

export default {
  tools: {
    rspack: (config, { rspack }) => {
      config.plugins.push(new rspack.BannerPlugin());
      return config;
    },
  },
};

addRules

  • 类型: (rules: RuleSetRule | RuleSetRule[]) => void

添加额外的 Rspack rules

示例:

export default {
  tools: {
    rspack: (config, { addRules }) => {
      // 添加单条规则
      addRules({
        test: /\.foo/,
        loader: require.resolve('foo-loader'),
      });

      // 以数组形式添加多条规则
      addRules([
        {
          test: /\.foo/,
          loader: require.resolve('foo-loader'),
        },
        {
          test: /\.bar/,
          loader: require.resolve('bar-loader'),
        },
      ]);
    },
  },
};

prependPlugins

  • 类型: (plugins: RspackPluginInstance | RspackPluginInstance[]) => void

在内部 Rspack 插件数组头部添加额外的插件,数组头部的插件会优先执行。

export default {
  tools: {
    rspack: (config, { prependPlugins }) => {
      // 添加单个插件
      prependPlugins(new PluginA());

      // 以数组形式添加多个插件
      prependPlugins([new PluginA(), new PluginB()]);
    },
  },
};

appendPlugins

  • 类型: (plugins: RspackPluginInstance | RspackPluginInstance[]) => void

在内部 Rspack 插件数组尾部添加额外的插件,数组尾部的插件会在最后执行。

export default {
  tools: {
    rspack: (config, { appendPlugins }) => {
      // 添加单个插件
      appendPlugins([new PluginA()]);

      // 以数组形式添加多个插件
      appendPlugins([new PluginA(), new PluginB()]);
    },
  },
};

removePlugin

  • 类型: (name: string) => void

删除内部的 Rspack 插件,参数为该插件的 constructor.name

例如,删除内部的 webpack-bundle-analyzer

export default {
  tools: {
    rspack: (config, { removePlugin }) => {
      removePlugin('BundleAnalyzerPlugin');
    },
  },
};

mergeConfig

  • 类型: (...configs: RspackConfig[]) => RspackConfig

用于合并多份 Rspack 配置,等价于 webpack-merge

export default {
  tools: {
    rspack: (config, { mergeConfig }) => {
      return mergeConfig(config, {
        devtool: 'eval',
      });
    },
  },
};

getCompiledPath

  • 类型: (name: string) => string

获取 builder 内置依赖的所在路径,例如:

  • sass
  • sass-loader
  • less
  • less-loader
  • ...

该方法通常在需要与 builder 复用同一份依赖时会被用到。

TIP

Builder 内部依赖会随着版本迭代而发生变化,例如产生大版本变更。在非必要的情况下,请避免使用此 API。

export default {
  tools: {
    rspack: (config, { getCompiledPath }) => {
      const loaderPath = getCompiledPath('less-loader');
      // ...
    },
  },
};
目录