close
  • 简体中文
  • output

    output.module output.moduleoutput.module

    • 类型: boolean
    • 默认值: true
    • CLI: --output.module

    是否以 ES 模块格式输出 JavaScript 文件。

    Rstest 默认会以 ES 模块格式输出并执行测试代码。如果你希望以 CommonJS 格式输出测试代码,可以通过如下配置项开启:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      output: {
        module: false,
      },
    });

    Commonjs interop

    当你以 ES 模块格式输出 JavaScript 文件时(output.module: true),Rstest 会默认根据依赖的引用方式来判断 external 的类型:

    • 通过 import 语法引用的依赖会被视为 ES 模块类型的 external。
    • 通过 require 语法引用的依赖会被视为 CommonJS 的 external。

    当你通过 import 语法引用 CommonJS 模块时,Rstest 会尝试进行 interop 处理,使得你可以通过 import 语法正常引用 CommonJS 模块的导出。以下代码在 rstest 中可以正常工作:

    cjs-module
    Object.defineProperty(exports, '__esModule', { value: true });
    
    const a = require('./a');
    
    exports.a = a.a;
    
    exports.default = () => {
      return `hello ${a.a}`;
    };
    test/index.test.ts
    import defaultExport, { a } from 'cjs-module'; // ✅

    然而,这种 interop 处理并不总是完美的,具体取决于被引用的 CommonJS 模块的导出方式。目前 Rstest 还不支持将 CommonJS 模块的 default 导出作为命名导出进行 interop。

    function lodash(_value) {}
    
    lodash.VERSION = VERSION;
    
    module.exports = lodash;
    import { VERSION } from 'lodash'; // ❌

    如果你在使用过程中遇到问题,可以通过 指定 external 类型 的方式来指定某个依赖的 external 类型为 CommonJS。

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      output: {
        externals: {
          lodash: 'commonjs lodash', // 将 lodash 作为 CommonJS 模块进行 external
        },
      },
    });

    output.externals output.externalsoutput.externals

    配置代码中的某些 import 的依赖不被打包,而是由 Rstest 在运行时去获取这些依赖。

    • 在 Node.js 测试环境中,默认打包:
      • 任意目录下的 TypeScript 和 JSX 文件,匹配的文件后缀为 .ts.tsx.jsx.mts.cts
      • node_modules 目录下的 JavaScript 文件,匹配的文件后缀为 .js.mjs.cjs
    • 在类浏览器(jsdom 等)测试环境中,默认打包所有依赖。

    如果你想某个依赖不被打包,可以在 output.externals 中进行配置。

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      output: {
        externals: ['react'],
      },
    });

    如果你希望所有依赖都被打包,可以通过如下配置:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      tools: {
        rspack: (config) => {
          config.externals = [];
        },
      },
    });

    指定 external 类型

    你可以通过 ${externalsType} ${libraryName} 语法来指定某个依赖的 external 类型。

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      output: {
        externals: {
          lodash: 'commonjs lodash', // 将 lodash 作为 CommonJS 模块进行 external
        },
      },
    });

    你也可以通过 externalsType 配置项 来指定所有依赖的默认 external 类型。

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      tools: {
        rspack: {
          externalsType: 'commonjs',
        },
      },
    });

    output.bundleDependencies

    • 类型: boolean | (string | RegExp)[]
    • 默认值: 取决于 testEnvironment

    控制是否打包 node_modules 中的第三方依赖。

    • true:无论测试环境如何,始终打包所有第三方依赖。
    • false:无论测试环境如何,始终外部化第三方依赖。
    • ['pkg-name']:仅打包列出的包,其余依赖保持外部化。
    • ['pkg-name/subpath']:仅打包指定的包子路径。
    • ['pkg-name/*']:按类似 glob 的模式匹配并打包包请求。
    • [/^pkg-name\\/subpath/]:按正则表达式匹配并打包包请求。

    当未设置该选项时,Rstest 会在类浏览器测试环境(jsdom、happy-dom 等)中打包依赖,在 node 环境中将其外部化。

    Warning

    此选项仅适用于非浏览器模式。在浏览器模式下,所有依赖始终会被打包,因此不支持 output.bundleDependencies: false

    此选项提供了一种简单的方式来覆盖与 testEnvironment 绑定的默认打包策略。例如,如果你使用 jsdom 但希望与 node 环境相同的外部化行为:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      testEnvironment: 'jsdom',
      output: {
        bundleDependencies: false,
      },
    });

    或者如果你希望在 node 环境中打包所有依赖以获得 lazy barrel 等优化:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      testEnvironment: 'node',
      output: {
        bundleDependencies: true,
      },
    });

    如果你只想打包少量依赖包,而把其他依赖继续外部化,可以直接传入包名列表:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      output: {
        bundleDependencies: ['strip-ansi'],
      },
    });

    你也可以直接匹配子路径或模式:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      output: {
        bundleDependencies: ['strip-ansi/lib/index.js', 'strip-ansi/*'],
      },
    });

    这些模式只会影响 rstest 在当前构建图里仍然能够处理到的依赖请求。如果某个包本身已经被 externalize 了,那么它内部继续引用的子依赖也会保持 external。也就是说,bundleDependencies 不会把仅通过某个已 externalize 父包间接到达的传递依赖重新打包回来。

    与 output.externals 的关系

    这两个配置都能决定「某个依赖是被打包还是被 external」,但它们工作在不同的层面,可以理解为「先定基调,再开例外」:

    • output.bundleDependencies 定整体基调:一次性决定所有 node_modules 依赖默认是打包还是 external。
    • output.externals 做逐包例外:在基调之上,针对个别包精确指定,且优先级更高。

    列出同一个包,效果正好相反

    当你只需要调整少数几个包时,这两个配置表达的意图正好相反:

    • bundleDependencies: ['foo']:默认将所有依赖 external,仅打包 foo
    • externals: ['foo']:默认打包所有依赖,仅将 foo external。

    选择哪一个,取决于大多数依赖应当保持的处理方式:

    • 大多数依赖需保持 external,仅少数需要打包 → 在 bundleDependencies 中列出需要打包的包。
    • 大多数依赖需保持打包,仅少数需要 external → 在 output.externals 中列出需要 external 的包。这里假设基调本身已是「打包」(类浏览器环境,或设置了 bundleDependencies: true),因为 output.externals 只在现有基调之上添加例外,并不会改变基调。

    同时配置时,output.externals 优先级更高

    output.externals 是 Rspack 原生能力,会先于 Rstest 的整体策略生效。因此你可以用 bundleDependencies 定一个宽泛的基调,再用 externals 精确覆盖个别包:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      output: {
        // 基调:打包所有第三方依赖
        bundleDependencies: true,
        // 例外:唯独 lodash 仍然保持 external
        externals: ['lodash'],
      },
    });

    output.cssModules output.cssModulesoutput.cssModules

    用于自定义 CSS Modules 的配置。

    output.emitAssets output.emitAssetsoutput.emitAssets

    • 类型: boolean
    • 默认值: true
    • CLI: --output.emitAssets

    控制在测试构建期间,是否将图片、字体、音频、视频等导入的静态资源作为构建产物输出。

    Rstest 会将该选项透传给底层的 Rsbuild 构建流程,因此它的行为与 Rsbuild 保持一致。当 output.emitAssetstrue 时,导入的 asset module 会被输出到构建产物文件系统中;当它为 false 时,这些静态资源文件不会被输出。

    在 Rstest 中,只有当你开启 dev.writeToDisk 或启用 DEBUG 产物输出时,这些资源才会真正写入磁盘。否则它们会保留在测试构建使用的临时内存文件系统里。

    当你希望 Rstest 与现有的 Rsbuild 配置保持一致,或者在测试中不需要对静态资源进行验证时,这个选项会比较有用。

    如果你已经通过 @rstest/adapter-rsbuild 复用 Rsbuild 配置,output.emitAssets 也会被自动继承。

    output.cleanDistPath output.cleanDistPathoutput.cleanDistPath

    • CLI: --output.cleanDistPath

    是否在测试开始前,清空输出目录下的所有测试临时文件。

    默认情况下,Rstest 不会将测试临时文件写入磁盘,当你开启 Rstest 产物调试时可能需要此配置项。

    output.distPath output.distPathoutput.distPath

    • 类型: string | { root?: string }
    • 默认值: { root: 'dist/.rstest-temp' }

    控制 Rstest 临时构建产物的全局输出根目录。

    默认情况下,Rstest 不会将测试临时文件写入磁盘,当你开启 dev.writeToDisk 选项或在 DEBUG 模式下运行时,Rstest 会把临时产物写入磁盘,输出到 dist/.rstest-temp 目录下。这包括 Node.js 测试运行时使用的编译产物,也包括 browser mode 下生成的 runner 文件、virtual manifest 等临时资源。

    在多 project 场景下,Rstest 仍然只使用一个全局输出根目录。它可能会在这个目录下继续为不同 project 创建子目录,但基础输出根目录本身不会切换到各个 project 的 root

    如果你希望这些文件输出到其他目录,可以通过 output.distPath.root 配置:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      dev: {
        writeToDisk: true,
      },
      output: {
        distPath: {
          root: 'custom/.rstest-temp',
        },
      },
    });

    配置后,Rstest 会把 <root>/custom/.rstest-temp 作为临时输出根目录,而不是 <root>/dist/.rstest-temp