CC 4.0 License

The content of this section is derived from the content of the following links and is subject to the CC BY 4.0 license.

The following contents can be assumed to be the result of modifications and deletions based on the original contents if not specifically stated.

Experiments

Enable and try out some experimental features.

  • Type: object
TIP

In minor releases, Rspack may make changes to the APIs of these experimental features and provide detailed explanations of these changes in the release notes. So if you are using experimental features, please pay attention to the minor release notes.

experiments.asyncWebAssembly

  • Type: boolean
  • Default: false

Support the new WebAssembly according to the updated specification, it makes a WebAssembly module an async module.

rspack.config.js
module.exports = {
  experiments: {
    asyncWebAssembly: true,
  },
};

And it is enabled by default when experiments.futureDefaults is set to true.

experiments.outputModule

  • Type: boolean
  • Default: true

Once enabled, Rspack will output ECMAScript module syntax whenever possible. For instance, import() to load chunks, ESM exports to expose chunk data, among others.

module.exports = {
  experiments: {
    outputModule: true,
  },
};

experiments.css

  • Type: boolean
  • Default: false

Once enabled, Rspack will enable native CSS support, and CSS related parser and generator options.

Basic example:

rspack.config.js
module.exports = {
  experiments: {
    css: true,
  },
};

experiments.futureDefaults

Use defaults of the next major Rspack and show warnings in any problematic places.

rspack.config.js
module.exports = {
  experiments: {
    futureDefaults: true,
  },
};

experiments.topLevelAwait

Enable support for Top-level await, Top-level await can only be used in modules with ModuleType is javascript/esm.

Enabled by default and can be disabled with this configuration:

rspack.config.js
module.exports = {
  experiments: {
    topLevelAwait: false,
  },
};

experiments.lazyCompilation

  • Type: boolean | LazyCompilationOptions
  • Default: false
type LazyCompilationOptions =
  | boolean
  | {
      backend?: {
        /**
         * A custom client.
         */
        client?: string;
        /**
         * Specify where to listen to from the server.
         */
        listen?: number | ListenOptions;
        /**
         * Specify the protocol the client should use to connect to the server.
         */
        protocol?: 'http' | 'https';
      };
      /**
       * Enable lazy compilation for entries.
       */
      entries?: boolean;
      /**
       * Enable lazy compilation for dynamic imports.
       */
      imports?: boolean;
      /**
       * Specify which imported modules should be lazily compiled.
       */
      test?: RegExp | ((m: Module) => boolean);
    };

Enable lazy compilation, which can greatly improve the dev startup performance of multi-page applications (MPA) or large single-page applications (SPA). For example, if you have twenty entry points, only the accessed entry points will be built. Or if there are many import() statements in the project, each module pointed to by import() will only be built when it is actually accessed.

If set to true, lazy compilation will be applied by default to both entry modules and modules pointed to by import(). You can decide whether it applies only to entries or only to import() through a configuration object. The entries option determines whether it applies to entries, while the import() option determines whether it applies to import().

rspack.config.js
const isDev = process.env.NODE_ENV === 'development';

module.exports = {
  experiments: {
    // only enabled in dev mode
    lazyCompilation: isDev,
  },
};

In addition, you can also configure a test parameter for more fine-grained control over which modules are lazily compiled. The test parameter can be a regular expression that matches only those modules that should be lazily compiled. It can also be a function where the input is of type 'Module' and returns a boolean value indicating whether it meets the criteria for lazy compilation logic.

TIP

The current lazy compilation aligns with the webpack implementation, and is still in the experimental stage. In some scenarios, lazy compilation might not work as expected, or the performance improvement may be insignificant.

experiments.lazyCompilation.backend.listen

  • Type: number | ListenOptions
type ListenOptions = {
  port?: number | undefined;
  host?: string | undefined;
  backlog?: number | undefined;
  path?: string | undefined;
  exclusive?: boolean | undefined;
  readableAll?: boolean | undefined;
  writableAll?: boolean | undefined;
  /**
   * @default false
   */
  ipv6Only?: boolean | undefined;
};

Exclude HMR client

If you do not use Rspack's own dev server and instead use your own server as the dev server, you generally need to add another client modules in the entry configuration to enable capabilities such as HMR. It is best to exclude these client module from lazy compilation by configuring test.

If not excluded and lazy compilation of entry is enabled, this client will not be compiled when accessing the page for the first time, so an additional refresh is needed to make it take effect.

For example:

const rspack = require('@rspack/core');

const options = {
  experiments: {
    lazyCompilation: {
      test(module) {
        const isMyClient = module.nameForCondition().endsWith('dev-client.js');
        // make sure that dev-client.js won't be lazy compiled
        return !isMyClient;
      },
    },
  },
};
const compiler = rspack(options);

new compiler.webpack.EntryPlugin(compiler.context, 'dev-client.js', {
  // name: undefined means this is global entry
  name: undefined,
}).apply(compiler);

experiments.layers

  • Type: boolean
  • Default: false

Controls whether to enable the layer feature. Layers can add an identifier prefix to all modules in a subgraph starting from a module in the module graph, to distinguish them from modules in different layers. For example:

The layer of the index.js module is by default null, and its identifier is ./index.js. If we set layer = 'client' for it, its identifier will become (client)/./index.js. At this point, the index.js modules in these two different layers will be treated as distinct modules, because their unique identifiers are different. As a result, the final output will include the artifacts of both modules.

By default, a module's layer is null, and it will inherit its parent module's layer. You can add a layer to an entry module using entryOptions.layer, and you can add a layer to matched modules using module.rule[].layer. Additionally, you can match based on the parent module's layer using module.rule[].issuerLayer.

rspack.config.js
module.exports = {
  experiments: {
    layers: true,
  },
};

experiments.incremental

type Incremental = {
  make?: boolean;
  inferAsyncModules?: boolean;
  providedExports?: boolean;
  dependenciesDiagnostics?: boolean;
  buildChunkGraph?: boolean;
  modulesHashes?: boolean;
  modulesCodegen?: boolean;
  modulesRuntimeRequirements?: boolean;
  chunksRuntimeRequirements?: boolean;
  chunksHashes?: boolean;
  chunksRender?: boolean;
  emitAssets?: boolean;
};

Whether to enable incremental rebuild to speed up the rebuild speed. It is recommended to enable it only during development.

const isDev = process.env.NODE_ENV;
module.exports = {
  mode: isDev ? 'development' : 'production',
  experiments: {
    incremental: isDev,
  },
};

true means enable incremental for all stages. false means disable incremental for all stages. Incremental can also be enabled only for specified partial stages:

module.exports = {
  experiments: {
    // enable incremental for all stages
    incremental: true,
    // disable incremental for all stages
    incremental: false,
    // enable only for specified partial stages
    incremental: {
      make: true,
      emitAssets: true,
    },
  },
};

Currently, incremental for the make and emitAssets stages is enabled by default. This is also the default behavior since Rspack v1.0. As this feature further stabilizes, we will enable incremental for more stages by default.

TIP

This feature is experimental. You can check its relevant progress at rspack#8106. You can also report bugs and any related feedback here.

experiments.rspackFuture

  • Type: object

  • Default: See options down below for details

Used to control whether to enable Rspack future default options, check out the details here.

experiments.rspackFuture.bundlerInfo

  • Type:
    type BundlerInfo = {
      version?: string,
      bundler?: string,
      force?: ('version' | 'uniqueId')[]boolean;
    };

Used to inject the currently used Rspack information into the generated asset:

  • version: Used to specify the Rspack version, defaults to the version field in @rspack/core/package.json.
  • bundler: Used to specify the name of the packaging tool, defaults to rspack.
  • force: Whether to force the injection of Rspack information, which will be added to chunk as a runtime module, and defaults to true to force injection. An array can be used to select the items to be forced injected。

Disable default injection

The default injection can be disabled by setting force to false. Then injection will only occur when __rspack_version__ and __rspack_unique_id__ are detected in the code:

rspack.config.js
module.exports = {
  experiments: {
    rspackFuture: { bundlerInfo: { force: false } },
  },
};