Output

This section describes some output related configurations in Rsbuild.

output.assetPrefix

  • Type: string
  • Default: '/'

When using CDN in the production environment, you can use this option to set the URL prefix of static assets.

assetPrefix will affect the URLs of most of the static assets, including JavaScript files, CSS files, images, videos, etc. If an incorrect value is specified, you'll receive 404 errors while loading these resources.

This config is only used in the production environment. In the development environment, please use the dev.assetPrefix to set the URL prefix.

After setting, the URLs of JavaScript, CSS and other static files will be prefixed with output.assetPrefix:

Example

export default {
  output: {
    assetPrefix: 'https://cdn.example.com/assets/',
  },
};

After building, you can see that the JS files are loaded from:

<script
  defer
  src="https://cdn.example.com/assets/static/js/main.ebc4ff4f.js"
></script>

Differences from Native Configuration

output.assetPrefix corresponds to the following native configurations:

The differences from the native configuration are as follows:

  • output.assetPrefix only takes effect in the production environment.
  • output.assetPrefix automatically appends a trailing / by default.
  • The value of output.assetPrefix is written to the process.env.ASSET_PREFIX environment variable.

output.charset

  • Type: 'ascii' | 'utf8'
  • Default: 'ascii'

By default, Rsbuild's output is ASCII-only and will escape all non-ASCII characters.

If you want to output the original characters without using escape sequences, you can set output.charset to utf8.

export default {
  output: {
    charset: 'utf8',
  },
};

output.cleanDistPath

  • Type: boolean
  • Default: true

Whether to clean all files in the dist path before starting compilation.

By default, Rsbuild clean up the dist file, you can disable this behavior by setting cleanDistPath to false.

export default {
  output: {
    cleanDistPath: false,
  },
};

output.copy

  • Type: CopyPluginOptions | CopyPluginOptions['patterns']
  • Default: undefined

Copies the specified file or directory to the dist directory.

For example, copy the files under src/assets to the dist directory:

export default {
  output: {
    copy: [{ from: './src/assets', to: '' }],
  },
};

For more detailed configuration, please refer to: copy-webpack-plugin.

output.cssModules

  • Type:
type CssModules = {
  auto?: boolean | RegExp | ((resourcePath: string) => boolean);
  localIdentName?: string;
  exportLocalsConvention?: CssModuleLocalsConvention;
};

For custom CSS Modules configuration.

cssModules.auto

The auto configuration option allows CSS modules to be automatically enabled based on their filenames.

  • Type: boolean | RegExp | ((resourcePath: string) => boolean)
  • Default: true

Type description:

  • true: enable CSS modules for all files matching /\.module\.\w+$/i.test(filename) regexp.
  • false: disables CSS Modules.
  • RegExp: enable CSS modules for all files matching /RegExp/i.test(filename) regexp.
  • function: enable CSS Modules for files based on the filename satisfying your filter function check.
export default {
  output: {
    cssModules: {
      auto: (resource) => {
        return resource.includes('.module.') || resource.includes('shared/');
      },
    },
  },
};

cssModules.exportLocalsConvention

Style of exported class names.

  • Type:
type CssModuleLocalsConvention =
  | 'asIs'
  | 'camelCase'
  | 'camelCaseOnly'
  | 'dashes'
  | 'dashesOnly';
  • Default: 'camelCase'

Type description:

  • asIs Class names will be exported as is.
  • camelCase Class names will be camelized, the original class name will not to be removed from the locals.
  • camelCaseOnly Class names will be camelized, the original class name will be removed from the locals.
  • dashes Only dashes in class names will be camelized.
  • dashesOnly Dashes in class names will be camelized, the original class name will be removed from the locals.
export default {
  output: {
    cssModules: {
      exportLocalsConvention: 'camelCaseOnly',
    },
  },
};

cssModules.localIdentName

  • Type: string
  • Default:
// isProd indicates that the production build
const localIdentName = isProd
  ? '[local]-[hash:base64:6]'
  : '[path][name]__[local]-[hash:base64:6]';

Sets the format of the className generated by CSS Modules after compilation.

Default Value

localIdentName has different default values in development and production.

In a production, Rsbuild will generate shorter class names to reduce the bundle size.

import styles from './index.module.scss';

// In development, the value is `.src-index-module__header-xxxxxx`
// In production, the value is `.header-xxxxxx`
console.log(styles.header);

Template String

You can use the following template strings in localIdentName:

  • [name] - the basename of the asset.
  • [local] - original class.
  • [hash] - the hash of the string.
  • [folder] - the folder relative path.
  • [path] - the relative path.
  • [file] - filename and path.
  • [ext] - extension with leading dot.
  • [hash:<hashDigest>:<hashDigestLength>]: hash with hash settings.
TIP

When using Rspack as the bundler, currently does not support custom <hashDigest>.

Example

Set localIdentName to other value:

export default {
  output: {
    cssModules: {
      localIdentName: '[hash:base64:4]',
    },
  },
};

output.dataUriLimit

  • Type:
type DataUriLimitConfig = {
  svg?: number;
  font?: number;
  image?: number;
  media?: number;
};
  • Default:
const defaultDatUriLimit = {
  svg: 10000,
  font: 10000,
  image: 10000,
  media: 10000,
};

Set the size threshold to inline static assets such as images and fonts.

By default, static assets will be Base64 encoded and inline into the page if the size is less than 10KB.

You can adjust the threshold by setting the dataUriLimit config.

Detail:

  • svg: The threshold of the SVG image.
  • font: The threshold of the font file.
  • image: The threshold of non-SVG images.
  • media: The threshold of media assets such as videos.

Example

Set the threshold of images to 5000 Bytes, and set media assets not to be inlined:

export default {
  output: {
    dataUriLimit: {
      image: 5000,
      media: 0,
    },
  },
};

output.disableCssExtract

  • Type: boolean
  • Default: false

Whether to disable CSS extract and inline CSS files into JS files.

By default, Rsbuild will extract CSS into a separate .css file and output it to the dist directory. When this option is set to true, CSS files will be inlined into JS files and inserted on the page at runtime via <style> tags.

Example

export default {
  output: {
    disableCssExtract: true,
  },
};

Notes

It is recommended to only enable the disableCssExtract option in the development environment.

For production builds, it is recommended to use the default behavior of Rsbuild, which extracts CSS into separate bundles to allow browsers to load CSS and JS assets in parallel.

For example:

export default {
  output: {
    disableCssExtract: process.env.NODE_ENV === 'development',
  },
};

If you need to enable this option in the production environment, please note that the inlined CSS code will not go through Rsbuild's default CSS minimizer. You can manually register the cssnano plugin for PostCSS to compress the inlined code.

  1. Install cssnano:
npm add cssnano -D
  1. Register cssnano using tools.postcss:
export default {
  tools: {
    postcss: (opts) => {
      opts.postcssOptions.plugins.push(require('cssnano'));
    },
  },
};

output.distPath

  • Type:
type DistPathConfig = {
  root?: string;
  html?: string;
  js?: string;
  css?: string;
  svg?: string;
  font?: string;
  wasm?: string;
  image?: string;
  media?: string;
  server?: string;
  worker?: string;
};
  • Default:
const defaultDistPath = {
  root: 'dist',
  html: '/',
  js: 'static/js',
  css: 'static/css',
  svg: 'static/svg',
  font: 'static/font',
  wasm: 'static/wasm',
  image: 'static/image',
  media: 'static/media',
  server: 'bundles',
  worker: 'worker',
};

Set the directory of the dist files. Rsbuild will output files to the corresponding subdirectory according to the file type.

Detail:

  • root: The root directory of all files.
  • html: The output directory of HTML files.
  • js: The output directory of JavaScript files.
  • css: The output directory of CSS style files.
  • svg: The output directory of SVG images.
  • font: The output directory of font files.
  • wasm: The output directory of WebAssembly files.
  • image: The output directory of non-SVG images.
  • media: The output directory of media assets, such as videos.
  • server: The output directory of server bundles when target is node.
  • worker: The output directory of worker bundles when target is service-worker.

Root Directory

The root is the root directory of the build artifacts and can be specified as a relative or absolute path. If the value of root is a relative path, it will be appended to the project's root directory to form an absolute path.

Other directories can only be specified as relative paths and will be output relative to the root directory.

Example

The JavaScript files will be output to the distPath.root + distPath.js directory, which is dist/static/js.

If you need to output JavaScript files to the build/resource/js directory, you can add following config:

export default {
  output: {
    distPath: {
      root: 'build',
      js: 'resource/js',
    },
  },
};

output.disableMinimize

  • Type: boolean
  • Default: false

Whether to disable code minification on production builds.

By default, JS and CSS code is minified during the production build to improve the page performance. If you do not want to the code to be minified, you can set disableMinimize to true.

export default {
  output: {
    disableMinimize: true,
  },
};
TIP

This configuration is usually used for debugging and troubleshooting. It is not recommended to disable code minification in production environments, as it will significantly degrade the page performance.

output.disableSourceMap

  • Type:
type DisableSourceMap =
  | boolean
  | {
      js?: boolean;
      css?: boolean;
    };
  • Default:
const defaultDisableSourceMap = {
  js: false,
  css: process.env.NODE_ENV === 'production',
};

Whether to disable Source Map generation.

What is a Source Map

Source Map is an information file that saves the source code mapping relationship. It records each location of the compiled code and the corresponding pre-compilation location. With Source Map, you can directly view the source code when debugging the compiled code.

By default, Rsbuild's Source Map generation rules are:

  • In development build, SourceMap of JS files and CSS files will be generated, which is convenient for debugging.
  • In production build, the Source Map of JS files will be generated for debugging and troubleshooting online problems; the Source Map of CSS files will not be generated.

If the project does not need Source Map, you can turned off it to speed up the compile speed.

export default {
  output: {
    disableSourceMap: true,
  },
};

If you want to enable Source Map in development and disable it in the production, you can set to:

export default {
  output: {
    disableSourceMap: process.env.NODE_ENV === 'production',
  },
};

If you need to individually control the Source Map of JS files or CSS files, you can refer to the following settings:

export default {
  output: {
    disableSourceMap: {
      js: false,
      css: true,
    },
  },
};

output.disableFilenameHash

  • Type: boolean
  • Default: false

Remove the hash from the name of static files after production build.

After the production build, there will be a hash in the middle of the filename by default. You can disable this behavior through the output.disableFilenameHash config.

Example

By default, the filename is:

File                                     Size         Gzipped
dist/static/css/187.7879e19d.css         126.99 KB    9.17 KB
dist/static/js/main.18a568e5.js          2.24 KB      922 B

Add output.disableFilenameHash config:

export default {
  output: {
    disableFilenameHash: true,
  },
};

After rebuild, the filenames become:

File                            Size         Gzipped
dist/static/css/187.css         126.99 KB    9.17 KB
dist/static/js/main.js          2.24 KB      922 B

output.enableInlineStyles

  • Type:
type EnableInlineStyles =
  | boolean
  | RegExp
  | ((params: { size: number; name: string }) => boolean);
  • Default: false

Whether to inline output style files (.css files) into HTML with <style> tags in production mode.

Note that, with this option on, the style files will no longer be written in dist directory, they will only exist inside the HTML file instead.

Example

By default, we have following output files:

dist/html/main/index.html
dist/static/css/style.css
dist/static/js/main.js

After turn on the output.enableInlineStyles option:

export default {
  output: {
    enableInlineStyles: true,
  },
};

The output files will become:

dist/html/main/index.html
dist/static/js/main.js

And dist/static/css/style.css will be inlined in index.html:

<html>
  <head>
    <style>
      /* content of dist/static/css/style.css */
    </style>
  </head>
  <body></body>
</html>

Using RegExp

If you need to inline part of the CSS files, you can set enableInlineStyles to a regular expression that matches the URL of the CSS file that needs to be inlined.

For example, to inline main.css into HTML, you can add the following configuration:

export default {
  output: {
    enableInlineStyles: /\/main\.\w+\.css$/,
  },
};
TIP

The production filename includes a hash value by default, such as static/css/main.18a568e5.css. Therefore, in regular expressions, \w+ is used to match the hash.

Using Function

You can also set output.enableInlineStyles to a function that accepts the following parameters:

  • name: The filename, such as static/css/main.18a568e5.css.
  • size: The file size in bytes.

For example, if we want to inline assets that are smaller than 10KB, we can add the following configuration:

export default {
  output: {
    enableInlineStyles({ size }) {
      return size < 10 * 1000;
    },
  },
};

output.externals

  • Type: string | object | function | RegExp

  • Default: undefined

At build time, prevent some import dependencies from being packed into bundles in your code, and instead fetch them externally at runtime.

For more information, please see: webpack Externals

Example

Exclude the react-dom dependency from the build product. To get this module at runtime, the value of react-dom will globally retrieve the ReactDOM variable.

export default {
  output: {
    externals: {
      'react-dom': 'ReactDOM',
    },
  },
};
TIP

When the build target is Web Worker, externals will not take effect. This is because the Worker environment can not access global variables.

output.filename

  • Type:
type FilenameConfig = {
  js?: string;
  css?: string;
  svg?: string;
  font?: string;
  image?: string;
  media?: string;
};
  • Default:
// Development
const devDefaultFilename = {
  js: '[name].js',
  css: '[name].css',
  svg: '[name].[contenthash:8].svg',
  font: '[name].[contenthash:8][ext]',
  image: '[name].[contenthash:8][ext]',
  media: '[name].[contenthash:8][ext]',
};

// Production
const prodDefaultFilename = {
  js: '[name].[contenthash:8].js',
  css: '[name].[contenthash:8].css',
  svg: '[name].[contenthash:8].svg',
  font: '[name].[contenthash:8][ext]',
  image: '[name].[contenthash:8][ext]',
  media: '[name].[contenthash:8][ext]',
};

Sets the filename of dist files.

After the production build, there will be a hash in the middle of the filename by default. This behavior can be disabled through the output.disableFilenameHash config.

The following are the details of each filename:

  • js: The name of the JavaScript file.
  • css: The name of the CSS style file.
  • svg: The name of the SVG image.
  • font: The name of the font file.
  • image: The name of a non-SVG image.
  • media: The name of a media asset, such as a video.

Example

To set the name of the JavaScript file to [name]_script.js, use the following configuration:

export default {
  output: {
    filename: {
      js:
        process.env.NODE_ENV === 'production'
          ? '[name]_script.[contenthash:8].js'
          : '[name]_script.js',
    },
  },
};
Filename hash

Usually, we only set the filename hash in the production mode (i.e., when process.env.NODE_ENV === 'production').

If you set the filename hash in the development mode, it may cause HMR to fail (especially for CSS files). This is because every time the file content changes, the hash value changes, preventing tools like mini-css-extract-plugin from reading the latest file content.

Filename of Async Modules

When you import a module via dynamic import, the module will be bundled into a single file, and its default naming rules are as follows:

  • In the development environment, the filename will be generated based on the module path, such as dist/static/js/async/src_add_ts.js.
  • In the production environment, it will be a random numeric id, such as dist/static/js/async/798.27e3083e.js. This is to avoid leaking the source code path in the production environment, and the number of characters is also less.
src/index.ts
const { add } = await import('./add.ts');

If you want to specify a fixed name for the async module, you can use the magic comments provided by the bundler to achieve this, using webpackChunkName to specify the module name:

src/index.ts
const { add } = await import(
  /* webpackChunkName: "my-chunk-name" */ './add.ts'
);

After specifying the module name as above, the generated file will be dist/static/js/async/my-chunk-name.js.

output.legalComments

  • Type: 'linked' | 'inline' | 'none'
  • Default: 'linked'

Configure how to handle the legal comment.

A "legal comment" is considered to be any statement-level comment in JS or rule-level comment in CSS that contains @license or @preserve or that starts with //! or /*!. These comments are preserved in output files by default since that follows the intent of the original authors of the code.

This behavior can be configured by using one of the following options:

  • linked: Extract all legal comments to a .LEGAL.txt file and link to them with a comment.
  • inline: Preserve all legal comments in original position.
  • none: Remove all legal comments.

Example

Remove all legal comments:

export default {
  output: {
    legalComments: 'none',
  },
};

output.overrideBrowserslist

  • Type: string[] | Record<RsbuildTarget, string[]
  • Default: undefined

Specifies the range of target browsers that the project is compatible with. This value will be used by @babel/preset-env and autoprefixer to identify the JavaScript syntax that need to be transformed and the CSS browser prefixes that need to be added.

Priority

The overrideBrowserslist config will override the .browserslistrc config file in the project and the browserslist field in package.json.

In most cases, it is recommended to use the .browserslistrc file rather than the overrideBrowserslist config. Because the .browserslistrc file is the official config file, it is more general and can be recognized by other libraries in the community.

Default Value

If there is no browserslist configs defined in the project, nor overrideBrowserslist defined, then Rsbuild will set the default browserslist to:

['chrome >= 87', 'edge >= 88', 'firefox >= 78', 'safari >= 14'];

Example

An example compatible with mobile scenarios:

export default {
  output: {
    overrideBrowserslist: [
      'iOS >= 9',
      'Android >= 4.4',
      'last 2 versions',
      '> 0.2%',
      'not dead',
    ],
  },
};

Check out the browserslist documentation to learn more about browserslist.

Set according to Targets

When you build multiple targets at the same time, you can set different browser ranges for different targets. At this point, you need to set overrideBrowserslist to an object whose key is the corresponding build target.

For example to set different ranges for web and node:

export default {
  output: {
    overrideBrowserslist: {
      web: [
        'iOS >= 9',
        'Android >= 4.4',
        'last 2 versions',
        '> 0.2%',
        'not dead',
      ],
      node: ['node >= 14'],
    },
  },
};

output.polyfill

  • Type: 'entry' | 'usage' | 'off'
  • Default: 'usage'

Through the output.polyfill option, you can control the injection mode of the polyfills.

Configuration Options

usage

When output.polyfill is configured as 'usage', Rsbuild will inject the polyfills based on the APIs used in each file.

export default {
  output: {
    polyfill: 'usage',
  },
};

entry

When output.polyfill is configured as 'entry', Rsbuild will inject the polyfills in each entry file.

export default {
  output: {
    polyfill: 'entry',
  },
};

off

When output.polyfill is configured as 'off', Rsbuild will not inject the polyfills, and developers need to ensure code compatibility themselves.

export default {
  output: {
    polyfill: 'off',
  },
};

Please refer to the Polyfill Mode for more details.