Experiments
该选项赋予用户激活和尝试实验功能的能力。
experiments.asyncWebAssembly
支持基于新规范的 WebAssembly,这使 WebAssembly 模块成为异步模块
当设置 experiments.futureDefaults 为 true 时,默认启用此功能。
experiments.incrementalRebuild
启用增量重新编译。当启用此选项,Rspack 在重新编译时会尝试复用上次构建的结果来提升构建速度,支持对不同阶段进行配置,默认为开启状态。
0.5 版本移除该配置并内置开启该功能。
- 类型: boolean | { make?: boolean, emitAsset?: boolean }
- 默认值: true
experiments.outputModule
开启之后,将尽可能输出符合 ECMAScript 语法的代码。例如,使用 import() 加载 chunk,使用 ESM exports 等等。
module.exports = {
  experiments: {
    outputModule: true,
  },
};
experiments.css
启用原生 CSS 支持和 CSS 相关的 parser 和 generator options:
WARNING
如果你在使用 style-loader 和 css-loader 请关闭该配置,因为 style-loader 和 css-loader 和原生 CSS 功能冲突。
experiments.futureDefaults
使用下一个主版本 Rspack 的默认值,并在任何有问题的地方显示警告。
rspack.config.js
module.exports = {
  experiments: {
    futureDefaults: true,
  },
};
experiments.topLevelAwait
开启打包 top level await 的支持,top level await 仅能在 ModuleType 为 javascript/esm 的模块中使用。
默认开启,可通过该配置关闭。
experiments.lazyCompilation
type LazyCompilationOptions =
  | boolean
  | {
      /**
       * 为 entries 启用 lazy compilation
       */
      entries?: boolean;
      /**
       * 为 dynamic imports 启用 lazy compilation
       */
      imports?: boolean;
      /**
       * 指定哪些导入的模块应该被延迟编译
       */
      test?: RegExp | ((m: Module) => boolean);
    };
开启懒编译,这对提高多入口应用(MPA)或大型单页面应用(SPA)的 dev 启动性能会非常有帮助。例如你有二十个入口,只有访问到的入口才会进行构建,或者如果项目中存在非常多的 import(),每一个 import() 所指向的模块都只有在被真正访问到时,才进行构建。
如果设置为 true,则默认会对入口模块以及 import() 指向的模块进行懒编译。你可以通过配置对象形式,来决定是否只对入口或只对 import() 生效。entries 决定是否对入口生效,import() 决定是否对 import() 生效。
rspack.config.js
const isDev = process.env.NODE_ENV === 'development';
module.exports = {
  experiments: {
    // 仅在 dev 模式下开启
    lazyCompilation: isDev,
  },
};
除此以外你还可以配置 test 来更细粒度控制对哪些模块进行懒编译。test 可以是一个正则表达式,只对该正则匹配到的模块进行懒编译,test 也可以是一个函数,函数的输入是 Module 类型,返回 boolean 类型,表示是否命中懒编译逻辑。
NOTE
当前 lazy compilation 是对齐 webpack 实现的,并且仍处于实验性阶段。在部分场景下,lazy compilation 可能无法按照预期工作,或是性能提升不明显。
排除 HMR client
如果你未使用 Rspack 的 dev server,而是使用自己的 server 作为开发服务器,一般会在 entry 配置中加入另外的 client 代码来开启 HMR 等能力,那么最好通过配置 test 来将该 client 模块从懒编译模块中排除出去。
如果不排除掉,并且开启 entry 的懒编译,该 client 在第一次访问页面时不会被编译,因此需要一次额外的刷新才能让其真正生效。
const rspack = require('@rspack/core');
const options = {
  experiments: {
    lazyCompilation: {
      test(module) {
        const isMyClient = module.nameForCondition().endsWith('dev-client.js');
        // 让 dev-client.js 不被懒编译
        return !isMyClient;
      },
    },
  },
};
const compiler = rspack(options);
new compiler.webpack.EntryPlugin(compiler.context, 'dev-client.js', {
  // name: undefined 代表这是全局 entry,会插入到每一个 entry 前
  name: undefined,
}).apply(compiler);
experiments.rspackFuture
用于控制是否开启 Rspack 未来的默认行为,详情请参考这里。
experiments.rspackFuture.disableTransformByDefault
- 
类型: boolean
 
- 
引入版本: v0.3.5 
- 
默认开启版本: v0.4.0 
- 
移除版本: v0.5.0 
- 
说明: 该功能主要对于三类问题进行处理:builtins 代码转换功能,target,自定义 Rule.type 
- 移除对部分 builtins 功能的支持:
 这部分配置项应当作用于被选中的相应模块,而使用 builtins.(relay|react|emotion|pluginImport|decorator)则等于是全局开启,这种方案不被推崇,因此将被废弃。
 在开启 disableTransformByDefault后,上述配置项将失效,迁移指南可以参考 builtin:swc-loader/options.rspackExperiments。
 例如我们希望 emotion的转换被应用于所有jsx文件:
 rspack.config.js module.exports = {
  module: {
    rules: [
      {
        test: /\.jsx$/,
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            parser: {
              syntax: "ecmascript",
              jsx: true
            }
          },
          rspackExperiments: {
            emotion: true // 配置项和原 builtins 保持一致
          }
        }
        type: 'javascript/auto',
      },
    ],
  },
  experiments: {
    rspackFuture: {
      disableTransformByDefault: true
    }
  }
};
 
对于 decorator 的配置项可以在,swc 代码中找到并替换,如 legacyDecorator,decoratorMetadata。 
- target 将不会对用户侧代码做降级
 在以往的版本中,我们通常会配置 target: ["web", "es5"]来生成适用于 web 和降级后的代码。
 现在,当用户开启了 disableTransformByDefault配置项后,target仅会被用于控制 runtime 代码(除了用户编写、node_modules 内的 Rspack 生成的代码,例如 chunk 加载等等)
 这和 webpack 的插件化设计思维完成了对齐,你可以使用 builtin:swc-loader的env或target进行迁移,
并精确控制需要转译的模块:
 rspack.config.js module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            parser: {
              syntax: "ecmascript"
            },
            target: "es5" // 注意,env 和 jsc.target 不能同时设置
          },
          env: { // 注意,env 和 jsc.target 不能同时设置
            targets: "chrome >= 48"
          }
        }
        type: 'javascript/auto',
      },
    ],
  },
  experiments: {
    rspackFuture: {
      disableTransformByDefault: true
    }
  }
};
 
注意:在未开启 disableTransformByDefault时,rspack 内置的转译器会对node_modules下的所有内容进行转译。
因此在开启了disableTransformByDefault后,builtin:swc-loader配合exclude: /node_modules/需要确保node_modules下代码已经完成了降级,否则可能会存在兼容性问题。
 
- 移除了非 webpack 兼容的 Rule.type
 这些类型被移除: 对于 JS 相关的类型仅会保留: 
- "javascript/auto"
- "javascript/esm"
- "javascript/dynamic"
 在开启 disableTransformByDefault后,Rspack 仅支持符合 web 标准的输入,对齐 webpack 的设计理念。
 在我们完成和 webpack 的讨论后,webpack 和 Rspack 将会提供更加开箱即用的配置,以支持非标准的输入,如 TypeScript 等。 由于目前对于 jsx,tsx,ts后缀名的文件会隐式地开启转译,因此在开启disableTransformByDefault后会提示编译报错,你可以这样完成迁移:
 rspack.config.js module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            parser: {
              syntax: "typescript"
            }
          }
        }
        type: 'javascript/auto',
      },
    ],
    {
      test: /\.tsx$/,
      exclude: /node_modules/,
      loader: 'builtin:swc-loader',
      options: {
        jsc: {
          parser: {
            syntax: "typescript",
            tsx: true
          }
        }
      }
      type: 'javascript/auto',
    },
    {
      test: /\.jsx$/,
      exclude: /node_modules/,
      loader: 'builtin:swc-loader',
      options: {
        jsc: {
          parser: {
            syntax: "ecmascript",
            jsx: true
          }
        }
      }
    }
  },
  experiments: {
    rspackFuture: {
      disableTransformByDefault: true
    }
  }
};
 
experiments.rspackFuture.newResolver
- 
类型: boolean
 
- 
引入版本: v0.3.5 
- 
默认开启版本: v0.4.0 
- 
移除版本: v0.5.0 
该功能将会开启新版 resolver,新的实现比旧版的 resolver 快了 5 倍。
rspack.config.js
module.exports = {
  experiments: {
    rspackFuture: {
      newResolver: true,
    },
  },
};
新的 resolver 同时提供了在 tsconfig-paths-webpack-plugin 中定义的tsconfig project references 功能。
具体请参考 resolve API.
rspack.config.js
module.exports = {
  resolve: {
    tsconfig: {
      configFile: path.resolve(__dirname, './tsconfig.json'),
      references: 'auto'
    },
  }
  experiments: {
    rspackFuture: {
      newResolver: true
    }
  }
}
experiments.rspackFuture.newTreeshaking
- 类型: boolean
- 引入版本: v0.4.2
- 默认开启版本: v0.6.0
- 移除版本: v0.7.0
WARNING
从 0.7.0 版本开始,newTreeshaking 默认开启并且不能切换回已废弃的老 tree shaking 算法。
该功能启用了与 webpack 相同的新摇树优化实现,可以生成更高效和更小的代码。
rspack.config.js
module.exports = {
  experiments: {
    rspackFuture: {
      newTreeshaking: true,
    },
  },
};
experiments.rspackFuture.disableApplyEntryLazily
- 类型: boolean
- 引入版本: v0.4.5
- 默认开启版本: v0.5.0
- 移除版本: v0.6.0
在未开启该功能时,在 compiler.hooks.afterEnvironment 调用之后仍然可以对 options.entry 进行有效的修改。
而在开启该功能后,在 compiler.hooks.afterEnvironment 调用之后不会再进行 options.entry 的有效修改。该行为与 Webpack 一致,所以该配置对于使用 Rspack 开发应用的用户来说基本没有影响,而对于 Rspack 的插件或上层框架开发者需要注意。
一个常见的场景就是在创建 Compiler 之后增加一些入口:
const rspack = require('@rspack/core');
const compiler = rspack(options);
function prependEntry(compiler, additionalEntry) {
  for (const key in compiler.options.entry) {
    compiler.options.entry[key].import = [
      additionalEntry,
      ...(compiler.options.entry[key].import || []),
    ];
  }
}
prependEntry(compiler, 'dev-client.js');
在开启该功能后修改将不生效,需要进行如下修改:
const rspack = require('@rspack/core');
const compiler = rspack(options);
function prependEntry(compiler, additionalEntry) {
  new compiler.webpack.EntryPlugin(compiler.context, additionalEntry, {
    name: undefined,
  }).apply(compiler);
}
prependEntry(compiler, 'dev-client.js');