# Rsbuild > * **Type:**`'prefer-tsconfig' | 'prefer-alias'` --- # Source: https://rsbuild.dev/config/resolve/alias-strategy.md # resolve.aliasStrategy * **Type:** `'prefer-tsconfig' | 'prefer-alias'` * **Default:** `'prefer-tsconfig'` * **Version:** `>=1.1.7` Set the strategy for path alias resolution, to control the priority relationship between the `paths` option in `tsconfig.json` and the [resolve.alias](/config/resolve/alias.md) option of Rsbuild. :::tip See [Path aliases](/guide/advanced/alias.md) for the differences between the `paths` option in `tsconfig.json` and the `resolve.alias` option of Rsbuild. ::: ## prefer-tsconfig By default, `resolve.aliasStrategy` is set to `'prefer-tsconfig'`. In this case, both the `paths` option in `tsconfig.json` and the `alias` option in the bundler will take effect, but the `paths` option in tsconfig has a higher priority. For example, if the following configurations are set at the same time: * tsconfig paths: ```json title="tsconfig.json" { "compilerOptions": { "paths": { "@common/*": ["./src/common-1/*"] } } } ``` * `resolve.alias`: ```ts title="rsbuild.config.ts" export default { resolve: { alias: { '@common': './src/common-2', '@utils': './src/utils', }, }, }; ``` Since the tsconfig paths have a higher priority, the following will happen: * `@common` will use the value defined in tsconfig paths, pointing to `./src/common-1` * `@utils` will use the value defined in `resolve.alias`, pointing to `./src/utils` ## prefer-alias If the value of `resolve.aliasStrategy` is set to `prefer-alias`, the `paths` option in `tsconfig.json` will only be used to provide TypeScript type definitions and will not affect the bundling result. In this case, the bundler will only read the `alias` option as the path alias. ```ts title="rsbuild.config.ts" export default { resolve: { aliasStrategy: 'prefer-alias', }, }; ``` For example, if the following configurations are set at the same time: * tsconfig paths: ```json title="tsconfig.json" { "compilerOptions": { "paths": { "@common/*": ["./src/common-1/*"], "@utils/*": ["./src/utils/*"] } } } ``` * `resolve.alias`: ```ts title="rsbuild.config.ts" export default { resolve: { alias: { '@common': './src/common-2', }, }, }; ``` Since the tsconfig paths are only used to provide types, only the `@common` alias will be effective, pointing to the `./src/common-2` directory. In most cases, you do not need to use `prefer-alias`, but you can consider using it if you need to dynamically generate some alias configurations. For example, generating the `alias` option based on environment variables: ```ts title="rsbuild.config.ts" export default { resolve: { alias: { '@common': process.env.NODE_ENV === 'production' ? './src/common-prod' : './src/common-dev', }, }, }; ``` --- # Source: https://rsbuild.dev/config/resolve/alias.md # Source: https://rsbuild.dev/guide/advanced/alias.md # Path aliases Path aliases allow developers to define aliases for modules, making it easier to reference them in code. This can be useful when you want to use a short, easy-to-remember name for a module instead of a long, complex path. For example, if you frequently reference the `src/common/request.ts` module in your project, you can define an alias for it as `@request` and then use `import request from '@request'` in your code instead of writing the full relative path every time. This also allows you to move the module to a different location without needing to update all the import statements in your code. ```ts title="src/index.ts" import request from '@request'; // resolve to `src/common/request.ts` ``` In Rsbuild, there are several ways to set up path aliases: * Use the [`paths` field](#typescript-paths-field) in tsconfig.json or jsconfig.json. * Use the [`imports` field](#nodejs-imports-field) in package.json. * Use Rsbuild's [resolve.alias](#alias-configuration) configuration. ## TypeScript `paths` field You can configure aliases through the `paths` configuration in [tsconfig.json](https://typescriptlang.org/docs/handbook/tsconfig-json.html), which is the recommended approach in TypeScript projects as it also resolves the TS type issues related to path aliases. For example: ```json title="tsconfig.json" { "compilerOptions": { "paths": { "@common/*": ["./src/common/*"] } } } ``` After configuring, if you reference `@common/Foo.tsx` in your code, it will be mapped to the `/src/common/Foo.tsx` path. :::tip You can refer to the [TypeScript - paths](https://typescriptlang.org/tsconfig#paths) documentation for more details. ::: ### jsconfig.json In non-TypeScript projects, if you need to set path aliases through the `paths` field in [jsconfig.json](https://code.visualstudio.com/docs/languages/jsconfig), you can use the [source.tsconfigPath](/config/source/tsconfig-path.md) option to set it. After adding the following configuration, Rsbuild will recognize the `paths` field in `jsconfig.json`. ```js title="rsbuild.config.mjs" export default { source: { tsconfigPath: './jsconfig.json', }, }; ``` ## Node.js `imports` field You can also use the Node.js [`imports` field](https://nodejs.org/api/packages.html#imports) to define aliases with the `#` prefix. This works out of the box and does not require additional Rsbuild configuration. ```json title="package.json" { "type": "module", "imports": { "#app/*": "./src/*" } } ``` ```js title="src/index.js" import { message } from '#app/foo'; ``` For TypeScript projects, enable [`resolvePackageJsonImports`](https://www.typescriptlang.org/tsconfig/#resolvePackageJsonImports) so the TypeScript language service and compiler can understand these aliases. ## Alias configuration Rsbuild provides the [resolve.alias](/config/resolve/alias.md) configuration option, which corresponds to the webpack/Rspack native [resolve.alias](https://rspack.rs/config/resolve#resolvealias) configuration. You can configure this option using an object or a function. ### Use cases Since the `paths` configuration in `tsconfig.json` is written in a static JSON file, it lacks dynamism. The `resolve.alias` configuration can address this limitation by allowing you to dynamically set the `resolve.alias` using JavaScript code, such as based on environment variables. ### Object usage You can configure `resolve.alias` using an object, where the relative paths will be automatically resolved to absolute paths. For example: ```js export default { resolve: { alias: { '@common': './src/common', }, }, }; ``` After configuring, if you reference `@common/Foo.tsx` in your code, it will be mapped to the `/src/common/Foo.tsx` path. ### Function usage You can also configure `resolve.alias` as a function, which receives the built-in `alias` object and allows you to modify it. For example: ```js export default { resolve: { alias: (alias) => { alias['@common'] = './src/common'; return alias; }, }, }; ``` ### Priority The `paths` configuration in `tsconfig.json` takes precedence over the `resolve.alias` configuration. When a path matches the rules defined in both `paths` and `resolve.alias`, the value defined in `paths` will be used. You can adjust the priority of these two options using [resolve.aliasStrategy](/config/resolve/alias-strategy.md). --- # Source: https://rsbuild.dev/config/html/app-icon.md # html.appIcon * **Type:** ```ts type AppIconItem = { src: string; size: number; target?: 'apple-touch-icon' | 'web-app-manifest'; purpose?: 'any' | 'maskable' | 'monochrome' | string; }; type AppIcon = { name?: string; icons: AppIconItem[]; filename?: string; }; ``` * **Default:** `undefined` Set the web application icons to display when added to the home screen of a mobile device: * Generate the web app manifest file and its `icons` field. * Generate the [apple-touch-icon](https://webhint.io/docs/user-guide/hints/hint-apple-touch-icons/) and `manifest` tags in the HTML file. :::tip Refer to the following documents for more information: * [MDN - Web app manifests](https://developer.mozilla.org/en-US/docs/Web/Manifest) * [How to Favicon: Six files that fit most needs](https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs) ::: ## Example For display on different devices, you will need to prepare several icons of different sizes. The most commonly used icon sizes are `192x192` and `512x512`, and you can customize the icon sizes and quantities to suit your needs. ```ts title="rsbuild.config.ts" export default { html: { appIcon: { name: 'My Website', icons: [ { src: './src/assets/icon-192.png', size: 192 }, { src: './src/assets/icon-512.png', size: 512 }, ], }, }, }; ``` After compilation, the following tags will be automatically generated in the HTML: ```html ``` Here, `manifest.webmanifest` is a JSON file that contains information about the application's name, icons, and other details. ```json { "name": "My Website", "icons": [ { "src": "/static/image/icon-192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/static/image/icon-512.png", "sizes": "512x512", "type": "image/png" } ] } ``` :::tip Icon size For Chromium, you must provide at least a 192x192 pixel icon and a 512x512 pixel icon. If only those two icon sizes are provided, Chrome automatically scales the icons to fit the device. If you'd prefer to scale your own icons, and adjust them for pixel-perfection, provide icons in increments of `48dp`. ::: ## name * **Type:** `string` * **Default:** `undefined` The name of the application that will be displayed when it is added to the home screen of the mobile device. If not set, the `manifest.webmanifest` file will not be generated. > For more details, see [Web app manifests - name](https://developer.mozilla.org/en-US/docs/Web/Manifest/name). ## icons * **Type:** `AppIconItem[]` * **Default:** `undefined` The list of icons: * `src` is the path of the icon, which can be a URL, an absolute file path, or a relative path to the project [root](/config/root.md). * `size` is the size of the icon in pixels. * `target` refers to the intended target for the icon, which can be either `apple-touch-icon` or `web-app-manifest`. If `target` is not set, by default, the manifest file will include all icons, while the `apple-touch-icon` tags will only include icons smaller than `200x200`. * `purpose` is a case-sensitive keyword string that specifies one or more contexts in which the icon can be used by the browser or operating system. This field is only effective when the `target` is `'web-app-manifest'`. See [MDN - purpose](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Manifest/Reference/icons#purpose) for more details. ### Example `src` can be set to an absolute path: ```js import path from 'node:path'; export default { html: { appIcon: { name: 'My Website', icons: [ { src: path.resolve(__dirname, './assets/icon-192.png'), size: 192 }, { src: path.resolve(__dirname, './assets/icon-512.png'), size: 512 }, ], }, }, }; ``` Use `target` to specify the target for the icon: ```ts title="rsbuild.config.ts" export default { html: { appIcon: { name: 'My Website', icons: [ { src: './src/assets/icon-180.png', size: 180, target: 'apple-touch-icon', }, { src: './src/assets/icon-192.png', size: 192, target: 'web-app-manifest', }, { src: './src/assets/icon-512.png', size: 512, target: 'web-app-manifest', }, ], }, }, }; ``` ### filename * **Type:** `string` * **Default:** `'manifest.webmanifest'` The filename of the manifest file. ```ts title="rsbuild.config.ts" export default { html: { appIcon: { filename: 'manifest.json', }, }, }; ``` ## Version history | Version | Changes | | ------- | ---------------------------------- | | v1.5.5 | Added support for `purpose` option | --- # Source: https://rsbuild.dev/config/output/asset-prefix.md # Source: https://rsbuild.dev/config/dev/asset-prefix.md # dev.assetPrefix * **Type:** `boolean | string | 'auto'` * **Default:** [server.base](/config/server/base.md) Set the URL prefix of static assets in [development mode](/config/mode.md). `assetPrefix` affects most static asset URLs, including JavaScript files, CSS files, images, videos, etc. If it is set incorrectly, these resources may return 404 errors. This config is only used in `development` mode. In `production` mode or `none` mode, use [output.assetPrefix](/config/output/asset-prefix.md) to configure the URL prefix. ## Default value The default value of `dev.assetPrefix` is the same as [server.base](/config/server/base.md). When `server.base` is `/foo`, `index.html` and other static assets can be accessed through `http://localhost:3000/foo/`. When you customize `dev.assetPrefix`, keep its URL prefix consistent with `server.base` so assets stay accessible through the Rsbuild dev server. For example: ```ts title="rsbuild.config.ts" export default { dev: { assetPrefix: '/foo/bar/', }, server: { base: '/foo', }, }; ``` ## Boolean type If `assetPrefix` is set to `true`, the URL prefix will be `http://localhost:/`: ```ts title="rsbuild.config.ts" export default { dev: { assetPrefix: true, }, }; ``` The resource URL loaded in the browser is as follows: ```html ``` If `assetPrefix` is set to `false` or not set, `/` is used as the default value. ## String type When the value of `assetPrefix` is a `string` type, the string will be used as a prefix and automatically appended to the static resource URL. * For example, set to a path relative to the root directory: ```ts title="rsbuild.config.ts" export default { dev: { assetPrefix: '/example/', }, }; ``` The resource URL loaded in the browser is as follows: ```html ``` * For example, set to a complete URL: ```ts title="rsbuild.config.ts" export default { dev: { assetPrefix: 'https://example.com/assets/', }, }; ``` The resource URL loaded in the browser is as follows: ```html ``` ### Port placeholder The port number that Rsbuild server listens on may change. For example, if the port is in use, Rsbuild will automatically increment the port number until it finds an available port. To avoid `dev.assetPrefix` becoming invalid due to port changes, you can use one of the following methods: * Enable [server.strictPort](/config/server/strict-port.md). * Use the `` placeholder to refer to the current port number. Rsbuild will replace the placeholder with the actual port number it is listening on. ```ts title="rsbuild.config.ts" export default { dev: { assetPrefix: 'http://localhost:/', }, }; ``` ## Path types The `assetPrefix` option accepts the following path types: * **absolute path**: The most common choice, including specific server paths like `/assets/`. * **'auto'**: Rspack will automatically calculate the path and generate relative paths based on file location. :::tip It's not recommended to set assetPrefix as a relative path, such as `'./assets/'`. This is because when assets are at different path depths, using relative paths may cause assets to load incorrectly. ::: ## Compare with `publicPath` The functionality of `dev.assetPrefix` is basically the same as the [output.publicPath](https://rspack.rs/config/output#outputpublicpath) config in Rspack. The differences from the native configuration are as follows: * `dev.assetPrefix` only takes effect in development mode. * `dev.assetPrefix` default value is the same as [server.base](/config/server/base.md). * `dev.assetPrefix` automatically appends a trailing `/` by default. * The value of `dev.assetPrefix` is written to the [process.env.ASSET\_PREFIX](/guide/advanced/env-vars.md#processenvasset_prefix) environment variable (can only be accessed in client code). ## Dynamic asset prefix Use the `__webpack_public_path__` variable provided by Rspack to dynamically set the URL prefix of static assets in JavaScript code. See [Rspack - Dynamically set publicPath](https://rspack.rs/guide/features/asset-base-path#dynamically-set-publicpath). --- # Source: https://rsbuild.dev/config/source/assets-include.md # source.assetsInclude * **Type:** [Rspack.RuleSetCondition](https://rspack.rs/config/module-rules#condition) * **Default:** `undefined` * **Version:** `>= 1.0.18` Include additional files that should be treated as static assets. By default, Rsbuild treats common image, font, audio, and video files as static assets. Through the `source.assetsInclude` config, you can specify additional file types that should be treated as static assets. These added static assets are processed using the same rules as the built-in supported static assets, see [Static Assets](/guide/basic/static-assets.md). The value of `source.assetsInclude` is the same as the `test` option in Rspack loader. It can be a regular expression, string, array, logical condition, etc. For more details, see [Rspack RuleSetCondition](https://rspack.rs/config/module-rules#condition). ## Example * Treating `.json5` files as static assets: ```ts export default defineConfig({ source: { assetsInclude: /\.json5$/, }, }); ``` * Treating multiple file types as static assets: ```ts export default defineConfig({ source: { assetsInclude: [/\.json5$/, /\.pdf$/], }, }); ``` * Treating specific files as static assets: ```ts import path from 'node:path'; export default defineConfig({ source: { assetsInclude: path.resolve(__dirname, 'src/assets/foo.json5'), }, }); ``` --- # Source: https://rsbuild.dev/config/server/base.md # server.base * **Type:** `string` * **Default:** `/` * **Version:** `>= 1.0.10` `server.base` is used to configure the [base path](/guide/basic/server.md#base-path) of the server. ## Example By default, the Rsbuild server's base path is `/`. You can access output files like `index.html` and assets in the [public folder](/guide/basic/static-assets.md#public-folder) through `http://localhost:3000/`. If you want to access `index.html` through `http://localhost:3000/foo/`, you can change `server.base` to `/foo`. ```ts title="rsbuild.config.ts" export default { server: { base: '/foo', }, }; ``` ## URL prefix of assets [dev.assetPrefix](/config/dev/asset-prefix.md) and [output.assetPrefix](/config/output/asset-prefix.md) will read the value of `server.base` as the default value. When `server.base` is `/foo`, the default resource URL loaded in the browser is as follows: ```html ``` Then, `index.html` and static assets can be accessed through `http://localhost:3000/foo/`. If you do not want to use this default behavior, you can override it by explicitly setting `dev.assetPrefix` / `output.assetPrefix` : ```ts title="rsbuild.config.ts" export default { dev: { assetPrefix: '/', }, output: { assetPrefix: 'https://cdn.example.com/assets/', }, server: { base: '/foo', }, }; ``` --- # Source: https://rsbuild.dev/guide/advanced/browser-compatibility.md # Browser compatibility Rsbuild supports [modern browsers](/guide/advanced/browserslist.md#default-browserslist) by default and provides syntax and API downgrade capabilities to ensure compatibility with legacy browsers that support ES5 (such as IE11). This chapter explains how to use Rsbuild's features to handle browser compatibility issues. ## Set browserslist Before addressing compatibility issues, decide which browsers your project needs to support and add the corresponding browserslist config. * If you haven't set browserslist yet, please read the [Browserslist](/guide/advanced/browserslist.md) chapter first. * If you have set a browserslist, Rsbuild automatically compiles code to match that scope, downgrades JavaScript and CSS syntax, and injects required polyfills. In most cases, you can safely use modern ECMAScript features without worrying about compatibility. After setting the browserslist, if you still encounter compatibility issues, continue reading to find solutions. :::tip What is polyfill A polyfill is code that provides newer features to older browsers that don't support them natively. It fills gaps in older implementations of web standards, letting developers use modern features without worrying about whether they'll work in legacy browsers. For example, if a browser doesn't support the `Array.prototype.flat()` method, a polyfill can add that functionality so code using `Array.prototype.flat()` still runs. Polyfills are commonly used to keep web applications working across a wide range of browsers, including older ones. ::: ## Background knowledge Before you tackle compatibility issues, review the following background so you can address them effectively. ### Syntax downgrade and API downgrade When you use higher-version syntax and APIs in your project, you need to downgrade two parts to make the compiled code run reliably in older browsers: syntax and APIs. **Rsbuild downgrades syntax through transpilation and downgrades APIs through polyfill injection.** > Syntax and APIs are not tightly coupled. Browser vendors ship syntax or APIs at different times based on specifications and their own priorities, so browsers released in the same period may not support the same syntax or APIs. In practice, syntax and APIs are handled separately. ### Syntax transpilation **Syntax is a set of rules for how a programming language organizes code**. Code that doesn't follow these rules cannot be correctly recognized by the programming language's engine and therefore cannot run. In JavaScript, the following are examples of syntax rules: * In `const foo = 1`, `const` means to declare an immutable constant. * In `foo?.bar?.baz`, `?.` indicates optional chaining of access properties. * In `async function () {}`, `async` means to declare an asynchronous function. Because different browser parsers support different syntax, and older engines support even less, certain syntax can trigger errors when older browsers try to parse the AST. For example, the following code will cause an error in IE or an older version of Node.js: ```js const foo = {}; foo?.bar(); ``` When this code runs in an older version of Node.js, the following error message appears: ```bash SyntaxError: Unexpected token. at Object.exports.runInThisContext (vm.js:73:16) at Object. ([eval]-wrapper:6:22) at Module._compile (module.js:460:26) at evalScript (node.js:431:25) at startup (node.js:90:7) at node.js:814:3 ``` The error makes it clear that this is a syntax issue, meaning older versions of the engine do not support this syntax. **Syntax cannot be supported by polyfills or shims**. To run syntax that's not originally supported in an older browser, you need to transpile the code into syntax the older engine can support. Transpile the above code into the following to run in older engines: ```js var foo = {}; foo === null || foo === void 0 ? void 0 : foo.bar(); ``` After transpilation, the syntax of the code has changed, and syntax the older engine cannot understand has been replaced with syntax it can understand, **but the meaning of the code itself hasn't changed**. If the engine encounters unrecognized syntax when converting to AST, it will report a syntax error and abort execution. In this case, if your project doesn't use capabilities like SSR or SSG, the page will be blank and unusable. If the code is successfully converted to AST, the engine will convert it into executable code and run it normally. ### API polyfill JavaScript is an interpreted scripting language, unlike compiled languages like Rust. Rust checks function calls during compilation, but JavaScript doesn't know whether a function exists until it runs that line of code, so some errors only appear at runtime. For example: ```js var str = 'Hello world!'; console.log(str.notExistedMethod()); ``` The above code uses valid syntax and can be converted to an AST during the first stage of engine runtime, but when it actually runs, the method `notExistedMethod` does not exist on `String.prototype`, so an error is reported: ```bash Uncaught TypeError: str.notExistedMethod is not a function at :2:17 ``` With ECMAScript iterations, new methods are added to built-in objects. For example, `String.prototype.replaceAll` was introduced in ES2021. The `replaceAll` method doesn't exist in `String.prototype` of most browser engines before 2021, so the following code works in the latest Chrome but not in earlier versions: ```js 'abc'.replaceAll('abc', 'xyz'); ``` To address the lack of `replaceAll` in older browsers, we can extend the `String.prototype` object and add the `replaceAll` method to it. For example: ```js // The implementation of this polyfill does not necessarily conform to the standard, it is only used as an example. if (!String.prototype.replaceAll) { String.prototype.replaceAll = function (str, newStr) { // If a regex pattern if ( Object.prototype.toString.call(str).toLowerCase() === '[object regexp]' ) { return this.replace(str, newStr); } // If a string return this.replace(new RegExp(str, 'g'), newStr); }; } ``` > This technique of providing implementations for legacy environments to align new APIs is called polyfill. ## Compilation scope By default, Rsbuild uses [SWC](/guide/configuration/swc.md) to compile all JavaScript and TypeScript modules, excluding JavaScript modules in the `node_modules` directory. This approach is designed to avoid impacting build performance when downgrading all third-party dependencies while also preventing potential issues from redundantly downgrading pre-compiled third-party dependencies. ### Source code The source code of the current project will be downgraded by default, so you don't need to add additional config, just make sure that the browserslist config is set correctly. ### Third-party dependencies When you find that a third-party dependency causes compatibility issues, you can add this dependency to Rsbuild's [source.include](/config/source/include.md) config. This makes Rsbuild perform extra compilation for that dependency. Taking the npm package `query-string` as an example, you can add the following config: ```ts title="rsbuild.config.ts" import path from 'node:path'; export default { source: { include: [/node_modules[\\/]query-string[\\/]/], }, }; ``` See [source.include](/config/source/include.md) for detailed usage. ## Polyfills Rsbuild compiles JavaScript code using SWC and supports injecting polyfills such as [core-js](https://github.com/zloirock/core-js) and [@swc/helpers](https://npmjs.com/package/@swc/helpers). In different usage scenarios, you may need different polyfill solutions. Rsbuild provides [output.polyfill](/config/output/polyfill.md) config to switch between different polyfill modes. ### Default behavior Rsbuild does not inject any polyfills by default: ```ts export default { output: { polyfill: 'off', }, }; ``` ### Usage mode When you enable usage mode, Rsbuild will analyze the source code in the project and determine which polyfills need to be injected. For example, the code uses the `Map` object: ```js var b = new Map(); ``` After compilation, only the polyfills for `Map` will be injected into this file: ```js import 'core-js/modules/es.map'; var b = new Map(); ``` The advantage of this method is smaller injected polyfill size, which is suitable for projects with higher requirements on bundle size. The disadvantage is that polyfills may not be fully injected because third-party dependencies won't be compiled and downgraded by default, so the polyfills required by third-party dependencies won't be analyzed. If you need to analyze a third-party dependency, you also need to add it to [source.include](/config/source/include.md) config. The config of usage mode is: ```ts export default { output: { polyfill: 'usage', }, }; ``` ### Entry mode When using entry mode, Rsbuild will analyze which `core-js` methods need to be injected according to the browserslist set for the current project and inject them into the entry file of each page. Polyfills injected this way are more comprehensive, eliminating concerns about polyfill issues in project source code and third-party dependencies. However, because some unused polyfill code is included, the bundle size may increase. The config of entry mode is: ```ts export default { output: { polyfill: 'entry', }, }; ``` ### UA polyfill Cloudflare provides a [polyfill service](https://cdnjs.cloudflare.com/polyfill/) that automatically generates polyfill bundles based on the user's browser User-Agent. You can use the [html.tags](/config/html/tags.md) config of Rsbuild to inject scripts. For example, to inject a ` ``` The ` ``` > You can also refer to [Vue - RFC 0023](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0023-scoped-styles-changes.md) for more details. --- # Source: https://rsbuild.dev/config/plugins.md # plugins Registers Rsbuild plugins. * **Type:** ```ts type Falsy = false | null | undefined; type RsbuildPlugins = ( | RsbuildPlugin | Falsy | Promise | RsbuildPlugins )[]; ``` * **Default:** `undefined` > Please check out the [Plugin List](/plugins/list/index.md) page to discover all available plugins. ## Example For example, to register the [Sass plugin](/plugins/list/plugin-sass.md) in Rsbuild: * Installing the plugin: import { PackageManagerTabs } from '@theme'; * Registering the plugin: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginSass } from '@rsbuild/plugin-sass'; export default defineConfig({ plugins: [pluginSass()], }); ``` ## Execution order By default, plugins run in the order they appear in the `plugins` array. Built-in Rsbuild plugins always execute before user-defined plugins. If a plugin specifies ordering controls such as the `enforce` property, the final execution sequence will be adjusted accordingly. See the [`enforce` property](/plugins/dev/core.md#enforce-property) for details. ## Conditional registration Falsy values in the `plugins` array are ignored, which lets you register plugins conditionally: ```ts title="rsbuild.config.ts" const isProd = process.env.NODE_ENV === 'production'; export default defineConfig({ plugins: [isProd && somePlugin()], }); ``` ## Async plugins If the plugin is async, you can return a `Promise` object or use an `async` function, and Rsbuild will automatically wait for the `Promise` to be resolved: ```ts title="rsbuild.config.ts" async function myPlugin() { await someAsyncOperation(); return { name: 'my-plugin', setup(api) { // ... }, }; } export default { plugins: [myPlugin()], }; ``` ## Nested plugins Rsbuild also supports nested plugins. You can pass an array that contains multiple plugins, similar to a plugin preset. This is useful for complex features that combine several plugins, such as framework integrations. ```ts title="rsbuild.config.ts" function myPlugin() { return [fooPlugin(), barPlugin()]; } export default { plugins: [myPlugin()], }; ``` ## Local plugins If your local code repository contains Rsbuild plugins, you can import them using relative paths. ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginCustom } from './plugins/pluginCustom'; export default defineConfig({ plugins: [pluginCustom()], }); ``` ## Plugin options If a plugin provides custom options, you can pass the configurations through the plugin function's parameters. ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginStylus } from '@rsbuild/plugin-stylus'; export default defineConfig({ plugins: [ pluginStylus({ stylusOptions: { lineNumbers: false, }, }), ], }); ``` ## Plugin registration phase Plugin registration only runs during the Rsbuild initialization phase. You cannot dynamically add other plugins within a plugin through the plugin API: ```ts title="rsbuild.config.ts" // Wrong function myPlugin() { return { setup(api) { api.modifyRsbuildConfig((config, { mergeRsbuildConfig }) => { return mergeRsbuildConfig(config, { plugins: [fooPlugin(), barPlugin()], // <- this will not work }); }); }, }; } // Correct function myPlugin() { return [fooPlugin(), barPlugin()]; } export default { plugins: [myPlugin()], }; ``` ## Rspack plugins The `plugins` option is used to register Rsbuild plugins. If you need to register Rspack or webpack plugins, please use [tools.rspack](/config/tools/rspack.md). ```ts title="rsbuild.config.ts" export default { // Rsbuild Plugins plugins: [pluginStylus()], tools: { rspack: { // Rspack or webpack Plugins plugins: [new SomeWebpackPlugin()], }, }, }; ``` ## Unplugin [unplugin](https://github.com/unjs/unplugin) is a unified plugin system for various build tools. You can use plugins implemented based on unplugin in Rsbuild, just import the `/rspack` subpath of the plugin and register it via [tools.rspack](/config/tools/rspack.md). Here is an example of using [unplugin-vue-components](https://npmjs.com/package/unplugin-vue-components): ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginVue } from '@rsbuild/plugin-vue'; import Components from 'unplugin-vue-components/rspack'; export default defineConfig({ plugins: [pluginVue()], tools: { rspack: { plugins: [ Components({ // options }), ], }, }, }); ``` :::tip When you use the transform hook in unplugin, also use the `transformInclude` hook to target specific modules. If the transform hook matches an `.html` module, it replaces the default EJS transform from the [html-rspack-plugin](https://github.com/rstackjs/html-rspack-plugin). ::: > Please ensure that the version of `unplugin` package is >= v1.6.0. --- # Source: https://rsbuild.dev/config/output/polyfill.md # output.polyfill * **Type:** `'entry' | 'usage' | 'off'` * **Default:** `'off'` Controls the polyfill injection mode. > See [Polyfill Mode](/guide/advanced/browser-compatibility.md#polyfill-mode) for more details. ## Optional value ### usage With `output.polyfill` set to `'usage'`, Rsbuild injects polyfills based on the APIs used in each file. This provides optimal bundle size by including only needed polyfills. ```ts title="rsbuild.config.ts" export default { output: { polyfill: 'usage', }, }; ``` ### entry With `output.polyfill` set to `'entry'`, Rsbuild injects polyfills in each entry file. This ensures all polyfills are available but may increase bundle size. ```ts title="rsbuild.config.ts" export default { output: { polyfill: 'entry', }, }; ``` :::tip It should be noted that when you bundle page with [Web Workers](/guide/basic/web-workers.md), the `entry` mode is not applicable to Web Workers because the Web Workers thread is isolated from the main thread (page), and the `usage` mode can be used at this time. ::: ### off With `output.polyfill` set to `'off'`, Rsbuild doesn't inject polyfills. You need to handle code compatibility yourself. ```ts title="rsbuild.config.ts" export default { output: { polyfill: 'off', }, }; ``` --- # Source: https://rsbuild.dev/config/server/port.md # server.port * **Type:** `number` * **Default:** `3000` Sets the port number for the Rsbuild server. By default, the Rsbuild server listens on port `3000` and automatically increments the port when it's occupied. Enable [server.strictPort](/config/server/strict-port.md) to throw an error instead of incrementing the port when it's occupied. The Rsbuild CLI provides a [--port](/guide/basic/cli.md#rsbuild-dev) option to set the port number. The `--port` option takes priority over the `server.port` config. ```bash npx rsbuild dev --port 8080 ``` ## Example Set the port to `8080`: ```ts title="rsbuild.config.ts" export default { server: { port: 8080, }, }; ``` Set different port numbers for development and preview servers: ```ts title="rsbuild.config.ts" export default { server: { port: process.env.NODE_ENV === 'development' ? 3000 : 8080, }, }; ``` --- # Source: https://rsbuild.dev/config/tools/postcss.md # tools.postcss * **Type:** `Object | Function` * **Default:** ```js const defaultOptions = { postcssOptions: { config: false, sourceMap: rsbuildConfig.output.sourceMap.css, }, }; ``` Rsbuild integrates PostCSS by default. You can configure [postcss-loader](https://github.com/webpack/postcss-loader) through `tools.postcss`. ## Function type When `tools.postcss` is a function, the default options will be passed in as the first parameter. You can directly modify this object or return a new object as the final options. For example: For example, to add a PostCSS plugin, you can call the [addPlugins](#addplugins) utility function: ```ts title="rsbuild.config.ts" export default { tools: { postcss: (opts, { addPlugins }) => { addPlugins(require('postcss-px-to-viewport')); }, }, }; ``` To pass parameters to the PostCSS plugin, call the PostCSS plugin as a function: ```ts title="rsbuild.config.ts" export default { tools: { postcss: (opts, { addPlugins }) => { const viewportPlugin = require('postcss-px-to-viewport')({ viewportWidth: 375, }); addPlugins(viewportPlugin); }, }, }; ``` You can also modify the default `postcss-loader` options: ```ts title="rsbuild.config.ts" export default { tools: { postcss: (opts) => { opts.sourceMap = false; }, }, }; ``` `tools.postcss` can return a config object and completely replace the default config: ```ts title="rsbuild.config.ts" export default { tools: { postcss: () => { return { postcssOptions: { plugins: [require('postcss-px-to-viewport')], }, }; }, }, }; ``` ## Object type When `tools.postcss` is an object, it will be merged with the default configuration using `Object.assign`. Note that `Object.assign` is a shallow copy and will completely overwrite the built-in `presets` or `plugins` array, please use it with caution. ```ts title="rsbuild.config.ts" export default { tools: { postcss: { // As `Object.assign` is used, the default postcssOptions will be overwritten. postcssOptions: { plugins: [require('postcss-px-to-viewport')], }, }, }, }; ``` ## Utils ### addPlugins * **Type:** ```ts type AddPlugins = ( plugins: PostCSSPlugin | PostCSSPlugin[], options?: { /** * Controls where the plugin is placed relative to the existing PostCSS plugins. * @default 'post' */ order?: 'pre' | 'post'; }, ) => void; ``` For adding additional PostCSS plugins, You can pass in a single PostCSS plugin, or an array of PostCSS plugins. ```ts title="rsbuild.config.ts" export default { tools: { postcss: (config, { addPlugins }) => { // Add a PostCSS Plugin addPlugins(require('postcss-preset-env')); // Add multiple PostCSS Plugins addPlugins([require('postcss-preset-env'), require('postcss-import')]); }, }, }; ``` To add plugins before the existing plugins, set `order` option to `pre`: ```ts title="rsbuild.config.ts" export default { tools: { postcss: (config, { addPlugins }) => { addPlugins(require('postcss-preset-env'), { order: 'pre' }); }, }, }; ``` ## Practice ### Multiple PostCSS options `tools.postcss.postcssOptions` can be set to a function, which receives the Rspack's `loaderContext` as a parameter. This allows you to use different PostCSS options for different file paths. For example, use `postcss-plugin-a` for file paths containing `foo`, and use `postcss-plugin-b` for other file paths: ```ts title="rsbuild.config.ts" export default { tools: { postcss: { postcssOptions: (loaderContext) => { if (/foo/.test(loaderContext.resourcePath)) { return { plugins: [require('postcss-plugin-a')], }; } return { plugins: [require('postcss-plugin-b')], }; }, }, }, }; ``` :::tip If the project contains a `postcss.config.*` config file, its content will be merged with `tools.postcss.postcssOptions`, and the latter's priority is higher. The `plugins` array will be merged into a single array. ::: ## Notes ### PostCSS version Rsbuild uses the PostCSS v8. When you use third-party PostCSS plugins, please pay attention to whether the PostCSS version is compatible. Some legacy plugins may not work in PostCSS v8. ### PostCSS config loading Rsbuild uses [postcss-load-config](https://github.com/postcss/postcss-load-config) to load PostCSS config files and merge them with the default config. Rsbuild internally sets the `postcss-loader`'s `postcssOptions.config` option to `false` to avoid loading config files repeatedly. ## Version history | Version | Changes | | ------- | ----------------------------------------------- | | v1.6.8 | Added `order` option to the `addPlugins` method | --- # Source: https://rsbuild.dev/config/source/pre-entry.md # source.preEntry * **Type:** `string | string[]` * **Default:** `undefined` Add a script before the entry file of each page. This script will be executed before the page code. Use this to execute global logic, such as injecting polyfills, setting global styles, etc. ## Add a single script First create a `src/polyfill.ts` file: ```js console.log('I am a polyfill'); ``` Then configure `src/polyfill.ts` to `source.preEntry`: ```ts title="rsbuild.config.ts" export default { source: { preEntry: './src/polyfill.ts', }, }; ``` Re-run the compilation and visit any page. You can see that the code in `src/polyfill.ts` has been executed, and `I am a polyfill` is logged in the console. ## Add global style You can also configure global styles using `source.preEntry`. This CSS code will be loaded earlier than the page code, such as introducing a `normalize.css` file: ```ts title="rsbuild.config.ts" export default { source: { preEntry: './src/normalize.css', }, }; ``` ## Add multiple scripts You can add multiple scripts by setting `preEntry` to an array, and they will be executed in array order: ```ts title="rsbuild.config.ts" export default { source: { preEntry: ['./src/polyfill-a.ts', './src/polyfill-b.ts'], }, }; ``` --- # Source: https://rsbuild.dev/guide/framework/preact.md # Preact In this document, you will learn how to build a Preact application using Rsbuild. ## Create a Preact application Use [create-rsbuild](/guide/start/quick-start.md#create-an-rsbuild-application) to create a Preact application with Rsbuild. Run the following command: import { PackageManagerTabs } from '@theme'; Then select `Preact` when prompted to "Select framework". ## Use Preact in an existing project To compile Preact, you need to register the Rsbuild [Preact Plugin](/plugins/list/plugin-preact.md). The plugin will automatically add the necessary configuration for Preact builds. For example, register in `rsbuild.config.ts`: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginPreact } from '@rsbuild/plugin-preact'; export default defineConfig({ plugins: [pluginPreact()], }); ``` ## Preact Fast Refresh Preact plugin uses [@preact/prefresh](https://github.com/preactjs/prefresh) and [@rspack/plugin-preact-refresh](https://github.com/rstackjs/rspack-plugin-preact-refresh) to hot reload Preact components. ### Component recognition Prefresh needs to be able to recognize your components. This means that components should start with a capital letter and hooks should start with `use` followed by a capital letter. This allows the plugin to effectively recognize these. Do note that a component as seen below is not named: ```jsx export default () => { return

Want to refresh

; }; ``` Instead do: ```jsx const MyComponent = () => { return

Want to refresh

; }; export default MyComponent; ``` When you are working with HOC's be sure to lift up the `displayName` so the plugin can recognize it as a component. --- # Source: https://rsbuild.dev/config/performance/preconnect.md # performance.preconnect * **Type:** ```ts type Preconnect = | Array< | string | { href: string; crossorigin?: boolean; } > | undefined; ``` * **Default:** `undefined` Injects [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preconnect) tags into the HTML file. ## When to use The `preconnect` keyword for the rel attribute of the `` element is a hint to browsers that the user is likely to need resources from the target resource's origin, and therefore the browser can likely improve the user experience by preemptively initiating a connection to that origin. Preconnecting speeds up future loads from a given origin by preemptively performing part or all of the handshake (DNS+TCP for HTTP, and DNS+TCP+TLS for HTTPS origins). `` will provide a benefit to any future cross-origin HTTP request, navigation or subresource. It has no benefit on same-origin requests because the connection is already open. If a page needs to make connections to many third-party domains, preconnecting them all can be counterproductive. The `` hint is best used for only the most critical connections. For the others, just use [``](/config/performance/dns-prefetch.md) to save time on the first step — the DNS lookup. ## Example ```ts title="rsbuild.config.ts" export default { performance: { preconnect: ['https://example.com/'], }, }; ``` The generated HTML tag is: ```html ``` ## Options ### href * **Type:** `string` * **Default:** `undefined` Specify the URL to preconnect to. ```ts title="rsbuild.config.ts" export default { performance: { // Equivalent to `preconnect: ['https://example.com/'],` preconnect: [ { href: 'https://example.com/', }, ], }, }; ``` ### crossorigin * **Type:** `boolean` * **Default:** `false` Specify whether to add the `crossorigin` attribute. ```ts title="rsbuild.config.ts" export default { performance: { preconnect: [ { href: 'https://example.com/', crossorigin: true, }, ], }, }; ``` The generated HTML tag is: ```html ``` :::tip Refer to this [link](https://webmasters.stackexchange.com/questions/89466/when-should-i-use-the-crossorigin-attribute-on-a-preconnect-link) to understand the use cases of the `crossorigin` attribute. ::: --- # Source: https://rsbuild.dev/config/performance/print-file-size.md # performance.printFileSize * **Type:** ```ts type PrintFileSizeOptions = | boolean | { total?: boolean | Function; detail?: boolean; compressed?: boolean; include?: (asset: PrintFileSizeAsset) => boolean; exclude?: (asset: PrintFileSizeAsset) => boolean; diff?: boolean; }; ``` * **Default:** `true` Whether to print the file sizes after production build. ## Default outputs The default output log is as follows: ``` File (web) Size Gzip dist/static/js/lib-react.b0714b60.js 140.4 kB 45.0 kB dist/static/js/index.f3fde9c7.js 1.9 kB 0.97 kB dist/index.html 0.39 kB 0.25 kB dist/static/css/index.2960ac62.css 0.35 kB 0.26 kB Total: 143.0 kB 46.3 kB ``` ## Disable outputs If you do not want to print any information, you can disable it by setting `printFileSize` to `false`: ```ts title="rsbuild.config.ts" export default { performance: { printFileSize: false, }, }; ``` ## Options You can customize the output format through the options. ### total * **Type:** ```ts type Total = | boolean | ((params: { environmentName: string; distPath: string; assets: PrintFileSizeAsset[]; totalSize: number; totalGzipSize: number; }) => string); ``` * **Default:** `true` Whether to output the total size of all static assets, or provide a function to customize the output format of the total size. When set to `false`, the total size will not be output: ```ts title="rsbuild.config.ts" export default { performance: { printFileSize: { total: false, }, }, }; ``` :::tip If the current build only generates one static asset, the total size will not be printed. ::: When set to a function, you can customize the total size output format: ```ts title="rsbuild.config.ts" export default { performance: { printFileSize: { total: ({ distPath, assets, totalSize }) => { return `Generated ${assets.length} files in ${distPath}, the total size is ${(totalSize / 1000).toFixed(1)} kB.`; }, }, }, }; ``` Function parameters: * `environmentName`: The unique name of the current environment, used to distinguish and locate the environment * `distPath`: The output directory relative to the project root * `assets`: Array of static assets, each containing `name` and `size` properties * `totalSize`: Total size of all static assets in bytes * `totalGzipSize`: Total gzip-compressed size of all static assets in bytes ### detail * **Type:** `boolean` * **Default:** `true` Whether to output the size of each static asset. If you do not need to view the size of each static asset, you can set `detail` to false. In this case, only the total size will be output: ```ts title="rsbuild.config.ts" export default { performance: { printFileSize: { detail: false, }, }, }; ``` ### compressed * **Type:** `boolean` * **Default:** `false` when [output.target](/config/output/target.md) is `node`, otherwise `true` Whether to output the gzip-compressed size of each static asset. If you do not need to view the gzipped size, you can set `compressed` to false. This can save some gzip computation time for large projects: ```ts title="rsbuild.config.ts" export default { performance: { printFileSize: { compressed: false, }, }, }; ``` :::tip * This data is only for reference to the size after gzip compression. Rsbuild does not enable gzip compression for static assets. Usually, you need to enable gzip compression on the server side, for example, using the [gzip module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) of nginx. * For non-compressible assets (such as images), the gzip size will not be shown in the detailed list, but their original size will be included in the total gzip size calculation. ::: ### include * **Type:** ```ts type PrintFileSizeAsset = { /** * The name of the static asset. * @example 'index.html', 'static/js/index.[hash].js' */ name: string; /** * The size of the static asset in bytes. */ size: number; }; type Include = (asset: PrintFileSizeAsset) => boolean; ``` * **Default:** `undefined` A filter function to determine which static assets to print. If returned `false`, the static asset will be excluded and not included in the total size or detailed size. For example, only output static assets larger than 10 kB: ```ts title="rsbuild.config.ts" export default { performance: { printFileSize: { include: (asset) => asset.size > 10 * 1000, }, }, }; ``` Or only output `.js` files larger than 10 kB: ```ts title="rsbuild.config.ts" export default { performance: { printFileSize: { include: (asset) => /\.js$/.test(asset.name) && asset.size > 10 * 1000, }, }, }; ``` ### exclude * **Type:** ```ts type Exclude = (asset: PrintFileSizeAsset) => boolean; ``` * **Default:** `(asset) => /\.(?:map|LICENSE\.txt|d\.ts)$/.test(asset.name)` A filter function to determine which static assets to exclude. If both `include` and `exclude` are set, `exclude` will take precedence. Rsbuild defaults to excluding source map, license files, and `.d.ts` type files, as these files do not affect page load performance. For example, exclude `.html` files in addition to the default: ```ts title="rsbuild.config.ts" export default { performance: { printFileSize: { exclude: (asset) => /\.(?:map|LICENSE\.txt|d\.ts)$/.test(asset.name) || /\.html$/.test(asset.name), }, }, }; ``` ### diff * **Type:** `boolean` * **Default:** `false` Controls whether file size differences are displayed relative to the previous build. When this option is enabled, Rsbuild records a snapshot of all output file sizes after each build. On subsequent builds, Rsbuild compares the current sizes against the previous snapshot and shows the change inline in parentheses. To enable diff output: ```ts title="rsbuild.config.ts" export default { performance: { printFileSize: { diff: true, }, }, }; ``` On the second build, the output begins to include inline size deltas: ``` File (web) Size Gzip dist/static/js/lib-react.b0714b60.js 140.4 kB (+2.1 kB) 45.0 kB (+0.5 kB) dist/static/js/index.f3fde9c7.js 1.9 kB (-0.3 kB) 0.97 kB (-0.1 kB) dist/static/css/index.2960ac62.css 0.35 kB (+0.35 kB) 0.26 kB (+0.26 kB) Total: 143.0 kB (+2.15 kB) 46.3 kB (+0.66 kB) ``` * Increases are highlighted in red with a `+` prefix * Decreases are highlighted in green with a `-` prefix * Files with no change omit the diff indicator :::tip Snapshots are stored at `/node_modules/.cache/rsbuild/file-sizes-[hash].json`, where \[hash] is derived from the Rsbuild configuration file path. ::: ## Version history | Version | Changes | | ------- | ------------------- | | v1.6.13 | Added `diff` option | --- # Source: https://rsbuild.dev/config/server/print-urls.md # server.printUrls * **Type:** ```ts type Routes = Array<{ entryName: string; pathname: string; }>; type PrintUrls = | boolean | ((params: { urls: string[]; port: number; routes: Routes; protocol: string; }) => (string | { url: string; label?: string })[] | void); ``` * **Default:** `true` Controls whether and how server URLs are printed when the server starts. By default, when you start the dev server or preview server, Rsbuild will print the following logs: ``` ➜ Local: http://localhost:3000 ➜ Network: http://192.168.0.1:3000 ``` ## Custom logging `server.printUrls` can be set to a function, with parameters including `port`, `protocol`, `urls` and `routes`. ### Modify URL If the `printUrls` function returns a URLs array, Rsbuild prints these URLs to the terminal in the default format: ```ts title="rsbuild.config.ts" export default { server: { printUrls({ urls }) { return urls.map((url) => `${url}/base/`); }, }, }; ``` Output: ``` ➜ Local: http://localhost:3000/base/ ➜ Network: http://192.168.0.1:3000/base/ ``` You may also return an array containing both strings and objects. Each object may include an optional `label` that overrides the default `Local:` or `Network:` label; if omitted, the default label is used: ```ts title="rsbuild.config.ts" export default { server: { printUrls({ urls }) { return urls.concat({ url: 'https://example.com/', label: 'Custom:' }); }, }, }; ``` Output: ``` ➜ Local: http://localhost:3000/ ➜ Network: http://192.168.0.1:3000/ ➜ Custom: https://example.com/ ``` ### Fully customizable If the `printUrls` function does not return a value, Rsbuild will not print the server's URL addresses. You can customize the log content based on the parameters and output it to the terminal yourself. ```ts title="rsbuild.config.ts" export default { server: { printUrls({ urls, port, protocol }) { console.log(urls); // ['http://localhost:3000', 'http://192.168.0.1:3000'] console.log(port); // 3000 console.log(protocol); // 'http' or 'https' }, }, }; ``` ### MPA output If the current project contains multiple pages, you can generate a separate URL for each page based on the `routes` parameter. For example, when the project contains two pages, `index` and `detail`, the content of the `routes` would be: ```ts title="rsbuild.config.ts" export default { server: { printUrls({ routes }) { /** * [ * { entryName: 'index', pathname: '/' }, * { entryName: 'detail', pathname: '/detail' } * ] */ console.log(routes); }, }, }; ``` ## Disable output Setting `server.printUrls` to `false` will prevent Rsbuild from printing the server URLs. ```ts title="rsbuild.config.ts" export default { server: { printUrls: false, }, }; ``` ### HTML disabled If [tools.htmlPlugin](/config/tools/html-plugin.md) is set to `false`, Rsbuild will not generate HTML files or output the server URL. However, you can still print the server URLs using the `server.printUrls` function, which has a higher priority. ```ts title="rsbuild.config.ts" export default { tools: { htmlPlugin: false, }, server: { printUrls: ({ port }) => [`http://localhost:${port}`], }, }; ``` Output: ``` ➜ Local: http://localhost:3000 ``` ## Version history | Version | Changes | | ------- | -------------------------- | | v1.5.17 | Support for custom `label` | --- # Source: https://rsbuild.dev/config/performance/profile.md # performance.profile * **Type:** `boolean` * **Default:** `false` Whether to capture timing information for each module, the same as the [profile](https://rspack.rs/config/other-options#profile) config of Rspack. When enabled: * Rsbuild will automatically generate a `dist/stats.json` file through [bundle analyzer](https://github.com/webpack/webpack-bundle-analyzer). * Rspack will include build-time information when generating stats.json or other statistics files. ## Example ```ts title="rsbuild.config.ts" export default { performance: { profile: true, }, }; ``` When enabled, Rspack generates a JSON file with statistics about modules, including timing information for each module. ## Guide Please refer to the [Build profiling](/guide/debug/build-profiling.md) page for more methods to analyze build performance. --- # Source: https://rsbuild.dev/config/dev/progress-bar.md # dev.progressBar * **Type:** ```ts type ProgressBar = | boolean | { id?: string; }; ``` * **Default:** `false` Whether to render progress bars to display the build progress. :::tip In `@rsbuild/core < 1.4.0`, the progress bar is enabled by default in production mode. ::: ## Example Enable the progress bar: ```ts title="rsbuild.config.ts" export default { dev: { progressBar: true, }, }; ``` Disable the progress bar: ```ts title="rsbuild.config.ts" export default { dev: { progressBar: false, }, }; ``` Only enable the progress bar in development mode: ```ts title="rsbuild.config.ts" const isDev = process.env.NODE_ENV === 'development'; export default { dev: { progressBar: isDev, }, }; ``` ## Customize the progress bar `id` To modify the text displayed on the left side of the progress bar, set the `id` option: ```ts title="rsbuild.config.ts" export default { dev: { progressBar: { id: 'Some Text', }, }, }; ``` When using [environments](/guide/advanced/environments.md), you can set different progress bar `id` for different environments: ```ts title="rsbuild.config.ts" export default { environments: { web: { dev: { progressBar: { id: 'Web', }, }, }, node: { output: { target: 'node', }, dev: { progressBar: { id: 'Node', }, }, }, }, }; ``` --- # Source: https://rsbuild.dev/config/server/proxy.md # server.proxy * **Type:** ```ts type ProxyConfig = | Record | ProxyOptions[] | ProxyOptions; ``` * **Default:** `undefined` Configure proxy rules for the dev server or preview server to proxy requests to the specified service. ## Example ### Basic usage ```ts title="rsbuild.config.ts" export default { server: { proxy: { // http://localhost:3000/api -> http://localhost:3000/api // http://localhost:3000/api/foo -> http://localhost:3000/api/foo '/api': 'http://localhost:3000', }, }, }; ``` A request to `/api/users` will now proxy the request to `http://localhost:3000/api/users`. You can also proxy to an online domain name, such as: ```ts title="rsbuild.config.ts" export default { server: { proxy: { // http://localhost:3000/api -> https://nodejs.org/api // http://localhost:3000/api/foo -> https://nodejs.org/api/foo '/api': 'https://nodejs.org', }, }, }; ``` ### Path rewrite If you do not want `/api` to be passed along, we need to rewrite the path: ```ts title="rsbuild.config.ts" export default { server: { proxy: { // http://localhost:3000/api -> http://localhost:3000 // http://localhost:3000/api/foo -> http://localhost:3000/foo '/api': { target: 'http://localhost:3000', pathRewrite: { '^/api': '' }, }, }, }, }; ``` ### Proxy WebSocket To proxy WebSocket requests, set `ws` to `true`: ```ts title="rsbuild.config.ts" export default { server: { proxy: { '/rsbuild-hmr': { target: 'http://localhost:3000', // will proxy to ws://localhost:3000/rsbuild-hmr ws: true, }, }, }, }; ``` ## Options The Rsbuild server proxy uses the [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware/tree/2.x) package. Check out its documentation for more advanced usage. The full type definition of Rsbuild server proxy is: ```ts import type { Options as HttpProxyOptions } from 'http-proxy-middleware'; type Filter = string | string[] | ((pathname: string, req: Request) => boolean); type ProxyOptions = HttpProxyOptions & { bypass?: ( req: IncomingMessage, res: ServerResponse, proxyOptions: ProxyOptions, ) => MaybePromise; context?: Filter; }; type ProxyConfig = | ProxyOptions | ProxyOptions[] | Record | Record; ``` In addition to the `http-proxy-middleware` options, Rsbuild also supports the `bypass` and `context` options. ### bypass Sometimes you don't want to proxy everything. You can bypass the proxy based on the return value of a `bypass` function. In the function, you have access to the request, response, and proxy options. * Return `null` or `undefined` to continue processing the request with proxy. * Return `true` to continue processing the request without proxy. * Return `false` to produce a 404 error for the request. * Return a path to serve from, instead of continuing to proxy the request. * Return a Promise to handle the request asynchronously. For example, for a browser request, you want to serve an HTML page, but for an API request, you want to proxy it. You could configure it like this: ```ts title="rsbuild.config.ts" export default { server: { proxy: { '/api': { target: 'http://localhost:3000', bypass(req, res, proxyOptions) { if (req.headers.accept.indexOf('html') !== -1) { console.log('Skipping proxy for browser request.'); return '/index.html'; } }, }, }, }, }; ``` ### context Used to proxy multiple specified paths to the same target. ```ts title="rsbuild.config.ts" export default { server: { proxy: [ { context: ['/auth', '/api'], target: 'http://localhost:3000', }, ], }, }; ``` --- # Source: https://rsbuild.dev/config/server/public-dir.md # server.publicDir * **Type:** ```ts type PublicDirOptions = { name?: string; copyOnBuild?: boolean | 'auto'; watch?: boolean; }; type PublicDir = false | PublicDirOptions | PublicDirOptions[]; ``` * **Default:** ```js const defaultValue = { name: 'public', copyOnBuild: 'auto', watch: false, }; ``` By default, Rsbuild uses the `public` directory for serving public assets. Files in this directory are served at [server.base](/config/server/base.md) path (default `/`). > Related document: [Public Folder](/guide/basic/static-assets.md#public-folder). ## Options ### name * **Type:** `string` * **Default:** `'public'` The name of the public directory. The value of `name` can be set to a relative path or an absolute path. Relative path will be resolved relative to the project root directory. * Relative path example: ```ts title="rsbuild.config.ts" export default { server: { publicDir: { name: '../some-public', }, }, }; ``` * Absolute path example: ```ts import path from 'node:path'; export default { server: { publicDir: { name: path.join(__dirname, '../some-public'), }, }, }; ``` ### copyOnBuild * **Type:** `boolean | 'auto'` * **Default:** `'auto'` Whether to copy files from the public directory to the dist directory on production build. * `true`: copy files. * `false`: do not copy files. * `'auto'`: if [output.target](/config/output/target.md) is not `'node'`, copy files, otherwise do not copy. :::tip During dev builds, if you need to copy some static assets to the output directory, you can use the [output.copy](/config/output/copy.md) option instead. ::: #### Disable For example, disable `copyOnBuild`: ```ts title="rsbuild.config.ts" export default { server: { publicDir: { copyOnBuild: false, }, }, }; ``` Note that setting the value of `copyOnBuild` to false means that when you run `rsbuild preview` for a production preview, you will not be able to access the corresponding static resources. #### Node target By default, when [output.target](/config/output/target.md) is `'node'`, Rsbuild will not copy files from the public directory. You can set `copyOnBuild` to `true` to copy files for the `node` target: ```ts title="rsbuild.config.ts" export default { output: { target: 'node', }, server: { publicDir: { copyOnBuild: true, }, }, }; ``` #### Multiple environments When performing [multi-environment builds](/guide/advanced/environments.md), Rsbuild copies files from the public directory to the output directory of each environment. If there are nested output directories, files will only be copied to the root of the output directory. For example: * The distDir of the `web` environment is `dist`, and the distDir of the `web1` environment is `dist/web1`. Due to the nested relationship between `dist` and `dist/web1`, the public directory files are only copied to the `dist` directory. * The distDir of the `esm` environment is `dist/esm`, and the distDir of the `cjs` environment is `dist/cjs`. Since there is no nesting relationship between `dist/esm` and `dist/cjs`, the public directory files will be copied to both the `dist/esm` and `dist/cjs` directories. ### watch * **Type:** `boolean` * **Default:** `false` Whether to watch the public directory and reload the page when the files change. Setting `watch` to `true` allows the dev server to watch changes to files in the specified public directory and reload the page when the files are changed: ```ts title="rsbuild.config.ts" export default { server: { publicDir: { watch: true, }, }, }; ``` Note that the `watch` option is only valid in development mode. If [dev.hmr](/config/dev/hmr.md) and [dev.liveReload](/config/dev/live-reload.md) are both set to false, `watch` will be ignored. ## Multiple directories The `server.publicDir` can be configured as an array, allowing you to serve multiple directories as static assets folders: ```ts title="rsbuild.config.ts" export default { server: { publicDir: [ { name: 'public', }, { name: 'assets', watch: false, }, ], }, }; ``` ## Disabled You can set `publicDir` to `false` to disable the static assets serving: ```ts title="rsbuild.config.ts" export default { server: { publicDir: false, }, }; ``` --- # Source: https://rsbuild.dev/guide/start/quick-start.md # Quick start ## Online examples We provide online Rsbuild examples that showcase Rspack's build performance and Rsbuild's development experience: * [StackBlitz example](https://stackblitz.com/~/github.com/rstackjs/rsbuild-stackblitz-example) * [CodeSandbox example](https://codesandbox.io/p/github/rstackjs/rsbuild-codesandbox-example) ## Environment preparation Rsbuild supports using [Node.js](https://nodejs.org/), [Deno](https://deno.com/), or [Bun](https://bun.sh/) as the JavaScript runtime. Use one of the following installation guides to set up a runtime: * [Install Node.js](https://nodejs.org/en/download) * [Install Bun](https://bun.com/docs/installation) * [Install Deno](https://docs.deno.com/runtime/getting_started/installation/) :::tip Version requirements * Rsbuild >= v1.5.0 requires Node.js 18.12.0 or higher. * Rsbuild \< 1.5.0 requires Node.js 16.10.0 or higher. ::: ## Create an Rsbuild application Use [create-rsbuild](https://www.npmjs.com/package/create-rsbuild) to create a new Rsbuild application. Run the following command: import { PackageManagerTabs } from '@theme'; Follow the prompts to choose options, such as whether to add optional tools like TypeScript and ESLint. After creating the application, do the following: * Run `git init` to initialize a Git repository. * Run `npm install` (or your package manager's install command) to install dependencies. * Run `npm run dev` to start the dev server, which runs on `http://localhost:3000` by default. ### Templates When creating an application, you can choose from the following templates provided by `create-rsbuild`: | Template | Official docs | Rsbuild integration guide | | -------- | ------------------------------- | --------------------------------------- | | vanilla | Native JavaScript | - | | react | [React 19](https://react.dev/) | [Using React](/guide/framework/react.md) | | react18 | [React 18](https://react.dev/) | [Using React](/guide/framework/react.md) | | vue | [Vue 3](https://vuejs.org/) | [Using Vue](/guide/framework/vue.md) | | vue2 | [Vue 2](https://v2.vuejs.org/) | [Using Vue](/guide/framework/vue.md) | | lit | [Lit](https://lit.dev/) | - | | preact | [Preact](https://preactjs.com/) | [Using Preact](/guide/framework/preact.md) | | svelte | [Svelte](https://svelte.dev/) | [Using Svelte](/guide/framework/svelte.md) | | solid | [Solid](https://solidjs.com/) | [Using Solid](/guide/framework/solid.md) | `create-rsbuild` provides basic templates. For more options, see: * Visit [Rspack - Ecosystem](https://rspack.rs/guide/start/quick-start#ecosystem) to learn about higher-level tools built on Rsbuild. * Visit [awesome-rstack - Starter](https://github.com/rstackjs/awesome-rstack?tab=readme-ov-file#starter) for community-maintained templates. ### Optional tools `create-rsbuild` can help you set up commonly used tools, including [Rstest](https://rstest.rs), [Biome](https://github.com/biomejs/biome), [ESLint](https://github.com/eslint/eslint), [Prettier](https://github.com/prettier/prettier), [Tailwind CSS](https://tailwindcss.com) and [Storybook](https://storybook.js.org/). Use the arrow keys to navigate and the space bar to select. Press Enter without selecting anything to skip these tools. ``` ◆ Select additional tools (Use to select, to continue) │ ◻ Rstest - testing │ ◻ Biome - linting & formatting │ ◻ ESLint - linting │ ◻ Prettier - formatting │ ◻ Tailwind CSS - styling │ ◻ Storybook - component development └ ``` :::tip Biome provides similar linting and formatting features to ESLint and Prettier. If you select Biome, you typically won't need to add ESLint or Prettier. ::: ### Current directory To create an application in the current directory, set the target folder to `.`: ``` ◆ Create Rsbuild Project │ ◇ Project name or path │ . │ ◇ "." is not empty, please choose: │ Continue and override files ``` ### Non-interactive mode [create-rsbuild](https://npmjs.com/package/create-rsbuild) supports a non-interactive mode via command-line options. This mode skips prompts and creates the project directly, which is useful for scripts, CI, and automation. For example, the following command creates a React app in the `my-app` directory: ```bash npx -y create-rsbuild@latest my-app --template react # Using abbreviations npx -y create-rsbuild@latest my-app -t react # Specify multiple tools npx -y create-rsbuild@latest my-app -t react --tools eslint,prettier ``` All CLI flags supported by `create-rsbuild`: ``` Usage: create-rsbuild [dir] [options] Options: -h, --help display help for command -d, --dir create project in specified directory -t, --template specify the template to use --tools add additional tools, comma separated --override override files in target directory --packageName specify the package name Templates: react-js, react-ts, vue3-js, vue3-ts, vue2-js, vue2-ts, svelte-js, svelte-ts, solid-js, solid-ts, vanilla-js, vanilla-ts Optional tools: rstest, biome, eslint, prettier, tailwindcss, storybook ``` ## Migrate from existing projects To migrate from an existing project to Rsbuild, refer to the following guides: * [Migrate from webpack](/guide/migration/webpack.md) * [Migrate from Create React App](/guide/migration/cra.md) * [Migrate from Vue CLI](/guide/migration/vue-cli.md) * [Migrate from Vite](/guide/migration/vite.md) * [Migrate from Modern.js Builder](/guide/migration/modern-builder.md) * [Migrate from Tsup to Rslib](https://rslib.rs/guide/migration/tsup) * [Migrate from Storybook to Storybook Rsbuild](https://rspack.rs/guide/migration/storybook) ### Other projects If your project doesn't match the above migration guides, you can manually install the [@rsbuild/core](https://npmjs.com/package/@rsbuild/core) package: After installation, use the following documents to configure your project: * See [CLI](/guide/basic/cli.md) to learn about available CLI commands. * See [Plugin List](/plugins/list/index.md) to select Rsbuild plugins. * See [Configure Rsbuild](/guide/configuration/rsbuild.md) to configure Rsbuild. ## CLI Rsbuild includes a lightweight CLI with commands like `dev` and `build`. ```json title="package.json" { "scripts": { // start the dev server "dev": "rsbuild dev", // build for production "build": "rsbuild build", // preview the production build locally "preview": "rsbuild preview" } } ``` Refer to the [CLI](/guide/basic/cli.md) to learn about all available commands and options. ## Entry module By default, Rsbuild CLI uses `src/index.(js|ts|jsx|tsx)` as the entry module. You can modify the entry module using the [source.entry](/config/source/entry.md) option. ```ts title="rsbuild.config.ts" export default { source: { entry: { foo: './src/pages/foo/index.ts', bar: './src/pages/bar/index.ts', }, }, }; ``` ## Core packages ### @rsbuild/core @rsbuild/core Core Rsbuild package that provides the CLI commands and JavaScript API. ### create-rsbuild create-rsbuild Create a new Rsbuild project. ## Next step You may want: import NextSteps from '@components/NextSteps'; import Step from '@components/Step'; --- # Source: https://rsbuild.dev/guide/framework/react.md # React This document explains how to use Rsbuild to build a React application. ## Create a React application Create a React application with Rsbuild using [create-rsbuild](/guide/start/quick-start.md#create-an-rsbuild-application). Run this command: import { PackageManagerTabs } from '@theme'; Then select `React 19` or `React 18` when prompted to "Select framework". ## Use React in an existing project To compile React's JSX syntax, register the Rsbuild [React Plugin](/plugins/list/plugin-react.md). The plugin automatically adds the necessary configuration for building React applications. For example, register in `rsbuild.config.ts`: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginReact } from '@rsbuild/plugin-react'; export default defineConfig({ plugins: [pluginReact()], }); ``` :::tip For projects using Create React App, you can refer to the [CRA Migration Guide](/guide/migration/cra.md). ::: ## Use SVGR Rsbuild supports converting SVG to React components via [SVGR](https://react-svgr.com/). To use SVGR, register the [SVGR plugin](/plugins/list/plugin-svgr.md). ## React Fast Refresh Rsbuild uses React's official [Fast Refresh](https://npmjs.com/package/react-refresh) capability to perform component hot updates. React Refresh requires components to follow certain standards, or HMR may not work. Use [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh) to validate your code. If React component hot updates don't work, or component state is lost after updates, your React component is likely using an anonymous function. React Fast Refresh requires named functions to preserve component state after hot updates. Here are some examples of wrong usage: ```tsx // bad export default function () { return
Hello World
; } // bad export default () =>
Hello World
; ``` The correct usage is to declare a name for each component function: ```tsx // good export default function MyComponent() { return
Hello World
; } // good const MyComponent = () =>
Hello World
; export default MyComponent; ``` ## React Compiler React Compiler is a build-time tool that automatically optimizes your React app. It works with plain JavaScript, and understands the Rules of React, so you don’t need to rewrite any code to use it. Before using React Compiler, we recommend reading the [React Compiler documentation](https://react.dev/learn/react-compiler) to understand its functionality, current state, and usage. ### How to use Steps to use React Compiler in Rsbuild: 1. Upgrade `react` and `react-dom` to v19. If you can't upgrade, install the [react-compiler-runtime](https://npmjs.com/package/react-compiler-runtime) package to run the compiled code on earlier versions. 2. React Compiler currently only provides a Babel plugin. Install [@rsbuild/plugin-babel](/plugins/list/plugin-babel.md) and [babel-plugin-react-compiler](https://npmjs.com/package/babel-plugin-react-compiler). 3. Register the Babel plugin in your Rsbuild config file: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginBabel } from '@rsbuild/plugin-babel'; import { pluginReact } from '@rsbuild/plugin-react'; export default defineConfig({ plugins: [ pluginReact(), pluginBabel({ include: /\.(?:jsx|tsx)$/, babelLoaderOptions(opts) { opts.plugins?.unshift('babel-plugin-react-compiler'); }, }), ], }); ``` > You can also refer to the [example project](https://github.com/rstackjs/rstack-examples/tree/main/rsbuild/react-compiler-babel). ### Configuration Set the config for React Compiler as follows: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginBabel } from '@rsbuild/plugin-babel'; import { pluginReact } from '@rsbuild/plugin-react'; const ReactCompilerConfig = { /* ... */ }; export default defineConfig({ plugins: [ pluginReact(), pluginBabel({ include: /\.(?:jsx|tsx)$/, babelLoaderOptions(opts) { opts.plugins?.unshift([ 'babel-plugin-react-compiler', ReactCompilerConfig, ]); }, }), ], }); ``` For React 17 and 18 projects, install [react-compiler-runtime](https://npmjs.com/package/react-compiler-runtime) and specify the `target`: ```ts title="rsbuild.config.ts" const ReactCompilerConfig = { target: '18', // '17' | '18' | '19' }; ``` ## Router ### TanStack Router [TanStack Router](https://tanstack.com/router/) is a fully type-safe React router with built-in data fetching, stale-while revalidate caching and first-class search-param APIs. TanStack Router provides `@tanstack/router-plugin` to integrate with Rsbuild, which provides support for file-based routing. See: * [Installation guide](https://tanstack.com/router/latest/docs/framework/react/installation/with-rspack) * [Example project](https://github.com/TanStack/router/tree/main/examples/react/quickstart-rspack-file-based) ### React Router [React Router](https://reactrouter.com/) is a user‑obsessed, standards‑focused, multi‑strategy router for React. * To use React Router as a library, you can just follow the official documentation and no configuration is required. * To use React Router as a framework, the community is working on an experimental Rsbuild plugin, see [rsbuild-plugin-react-router](https://github.com/rstackjs/rsbuild-plugin-react-router). ## CSS-in-JS See [CSS-in-JS](/guide/styling/css-in-js.md) for how to use CSS-in-JS in Rsbuild. ## Customize JSX Rsbuild uses SWC to compile JSX. You can customize the functions used by the compiled JSX code: * If the JSX runtime is `automatic`, use [importSource](/plugins/list/plugin-react.md#swcreactoptionsimportsource) to customize the import path of the JSX runtime, for example, import from Preact or Emotion. * If the JSX runtime is `classic`, use `pragma` and `pragmaFrag` to specify the JSX function and Fragment component. > `@rsbuild/plugin-react` uses `automatic` as the default JSX runtime, see [swcReactOptions.runtime](/plugins/list/plugin-react.md#swcreactoptionsruntime). ### Via configuration Configure through the `@rsbuild/plugin-react`'s [swcReactOptions](/plugins/list/plugin-react.md#swcreactoptions). * If `runtime` is `automatic`: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginReact } from '@rsbuild/plugin-react'; export default defineConfig({ plugins: [ pluginReact({ swcReactOptions: { runtime: 'automatic', importSource: '@emotion/react', }, }), ], }); ``` * If `runtime` is `classic`: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginReact } from '@rsbuild/plugin-react'; export default defineConfig({ plugins: [ pluginReact({ swcReactOptions: { runtime: 'classic', pragma: 'h', pragmaFrag: 'Fragment', }, }), ], }); ``` ### Via comments You can also customize JSX behavior by adding specific comments at the top of individual JSX or TSX files, which will take precedence over the configuration. * If the JSX runtime is `automatic`: ```tsx title="App.tsx" /** @jsxImportSource custom-jsx-library */ const App = () => { return
Hello World
; }; ``` * If the JSX runtime is `classic`: ```tsx title="App.tsx" /** @jsx Preact.h */ /** @jsxFrag Preact.Fragment */ const App = () => { return
Hello World
; }; ``` ## Performance profiling ### React Scan React Scan can automatically detect performance issues in your React app. See [React Scan - Rsbuild Guide](https://github.com/aidenybai/react-scan/blob/main/docs/installation/rsbuild.md) to learn how to use React Scan with Rsbuild. --- # Source: https://rsbuild.dev/config/performance/remove-console.md # performance.removeConsole * **Type:** `boolean | ConsoleType[]` * **Default:** `false` Whether to remove `console.[methodName]` in production build. ## Remove all When `removeConsole` is set to `true`, all types of `console.[methodName]` are removed: ```ts title="rsbuild.config.ts" export default { performance: { removeConsole: true, }, }; ``` ## Specific type You can also specify to remove only certain types of `console.[methodName]`, such as `console.log` and `console.warn`: ```ts title="rsbuild.config.ts" export default { performance: { removeConsole: ['log', 'warn'], }, }; ``` The following types of console are currently supported: ```ts type ConsoleType = 'log' | 'info' | 'warn' | 'error' | 'table' | 'group'; ``` --- # Source: https://rsbuild.dev/config/performance/remove-moment-locale.md # performance.removeMomentLocale * **Type:** `boolean` * **Default:** `false` Whether to remove the locales of [moment.js](https://momentjs.com/). `moment.js` contains a lot of locales by default, which will increase the bundle size. When `moment.js` is used in the project, it is recommended to enable this option to automatically exclude all locales: ```ts title="rsbuild.config.ts" export default { performance: { removeMomentLocale: true, }, }; ``` Once enabled, you can load a specific locale via: ```js import moment from 'moment'; import 'moment/locale/zh-cn'; moment.locale('zh-cn'); ``` --- # Source: https://rsbuild.dev/config/root.md # root * **Type:** `string` * **Default:** [process.cwd()](https://nodejs.org/api/process.html#processcwd) * **Version:** `>= 1.0.0` Specify the project root directory. Can be an absolute path, or a path relative to `process.cwd()`. The value of Rsbuild `root` is also passed to the [context](https://rspack.rs/config/context) configuration of Rspack. :::tip The value of `root` does not affect the path of the `.env` file, as the `.env` file is resolved before the Rsbuild configuration file. Rsbuild CLI supports using the `--root` option to specify the root directory, which can affect the path of the `.env` file. See ["CLI"](/guide/basic/cli.md) for more details. ::: ## Example * Relative path: ```ts title="rsbuild.config.ts" export default { root: './foo', }; ``` * Absolute path: ```ts title="rsbuild.config.ts" import { join } from 'node:path'; export default { root: join(__dirname, 'foo'), }; ``` --- # Source: https://rsbuild.dev/guide/migration/rsbuild-0-x.md # Migrating from Rsbuild 0.x This document lists all breaking changes from Rsbuild 0.7 to 1.0. Use it as a migration reference. > See [Breaking changes in Rsbuild v1.0.0](https://github.com/web-infra-dev/rsbuild/discussions/2508) for details. ## \[Important] Lightning CSS loader Rsbuild now enables [lightningcss-loader](https://rspack.rs/guide/features/builtin-lightningcss-loader) by default to transform CSS files. It replaces `autoprefixer` for adding vendor prefixes and delivers better performance. * `@rsbuild/plugin-lightningcss` is deprecated and no longer needed. * `tools.autoprefixer` config has been removed. Since Lightning CSS has some uncovered edge cases, you can still enable autoprefixer through a postcss config file: ```js title="postcss.config.cjs" module.exports = { plugins: { autoprefixer: {}, }, }; ``` ## \[Important] output.polyfill Rsbuild v1 sets [output.polyfill](/config/output/polyfill.md) to `'off'` by default. This reduces polyfill code and generates smaller bundles. If your application needs polyfills, set `output.polyfill` to `'usage'` or `'entry'`: ```ts title="rsbuild.config.ts" export default { output: { polyfill: 'usage', }, }; ``` ## \[Important] source.decorators Rsbuild now uses `2022-11` decorators version by default. This aligns Rsbuild's default behavior with TypeScript >= 5.0 and esbuild >= 0.21.0. For legacy decorators, add this config: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; export default defineConfig({ source: { decorators: { version: 'legacy', }, }, }); ``` ## \[Important] output.targets :::tip Rsbuild v1 removes the `output.targets` option and target parameters from `source.alias`, `source.entry`, and other configs. Instead, use `environments` for more flexible multi-environment configuration. The `environments` option provides broader coverage and enables differentiated config across multiple environments. For details, see [Multiple-Environment Builds](/guide/advanced/environments.md). ::: The `output.targets` config has been removed. Use [output.target](/config/output/target.md) and [environments](/config/environments.md) instead. * before: ```js export default { output: { targets: ['web', 'node'], }, }; ``` * after: ```js export default { environments: { web: { output: { target: 'web', }, }, node: { output: { target: 'node', }, }, }, }; ``` ## source.alias Removed `target` param for `source.alias` function, use [environments](/config/environments.md) config instead. * before: ```js export default { source: { alias: (alias, { target }) => { if (target === 'node') { alias['@common'] = './src/node/common'; } else if (target === 'web') { alias['@common'] = './src/web/common'; } }, }, output: { targets: ['web', 'node'], }, }; ``` * after: ```js export default { environments: { web: { source: { alias: { '@common': './src/web/common', }, }, output: { target: 'web', }, }, node: { source: { alias: { '@common': './src/node/common', }, }, output: { target: 'node', }, }, }, }; ``` ## source.entry Removed function usage of `source.entry`, use [environments](/config/environments.md) config instead. * before: ```js export default { source: { entry({ target }) { if (target === 'web') { return { index: './src/index.client.js', }; } if (target === 'node') { return { index: './src/index.server.js', }; } }, }, output: { targets: ['web', 'node'], }, }; ``` * after: ```js export default { environments: { web: { source: { entry: { index: './src/index.client.js', }, }, output: { target: 'web', }, }, node: { source: { entry: { index: './src/index.server.js', }, }, output: { target: 'node', }, }, }, }; ``` ## output.overrideBrowserslist `output.overrideBrowserslist` no longer supports `Record= 9', 'Android >= 4.4'], node: ['node >= 20'], }, }, }; ``` * after: ```js export default defineConfig({ environments: { web: { output: { overrideBrowserslist: ['iOS >= 9', 'Android >= 4.4'], }, }, node: { output: { overrideBrowserslist: ['node >= 20'], }, }, }, }); ``` ## output.emitAssets `output.emitAssets` changed to boolean type, use [environments](/config/environments.md) config instead. * before: ```js export default { output: { targets: ['web', 'node'], emitAssets: ({ target }) => target !== 'node', }, }; ``` * after: ```js export default { environments: { web: { output: { target: 'web', }, }, node: { output: { target: 'node', emitAssets: false, }, }, }, }; ``` ## output.distPath.server Removed `output.distPath.server`, use the [environments](/config/environments.md) config instead. ```js export default { environments: { web: { output: { target: 'web', }, }, node: { output: { target: 'node', distPath: { root: 'dist/server', }, }, }, }, }; ``` ## output.minify.html Rsbuild v1 removed the `output.minify.html` and `output.minify.htmlOptions` options, and no longer minify the HTML files. Previously Rsbuild uses `html-minifier-terser` to minify the HTML files. But the performance of `html-minifier-terser` cannot meet the needs of Rsbuild applications, and in most cases, there is little benefit in compressing HTML. At this stage, Rsbuild will not built-in `html-minifier-terser`, so we provide a standalone [rsbuild-plugin-html-minifier-terser](https://github.com/rstackjs/rsbuild-plugin-html-minifier-terser) to support HTML minification. ```ts title="rsbuild.config.ts" import { pluginHtmlMinifierTerser } from 'rsbuild-plugin-html-minifier-terser'; export default { plugins: [pluginHtmlMinifierTerser()], }; ``` And we plan to use some faster Rust-based HTML minimizer in the future. ## output.charset The default value of [output.charset](/config/output/charset.md) has been changed from `ascii` to `utf8`. To use `ascii`, add the following config: ```ts export default { output: { charset: 'ascii', }, }; ``` ## dev.startUrl `dev.startUrl` has been renamed to [server.open](/config/server/open.md): ```js export default { // [!code --] dev: { startUrl: true, // [!code --] }, // [!code --] // [!code ++] server: { open: true, // [!code ++] }, // [!code ++] }; ``` ## dev.client.port The default value of [dev.client.port](/config/dev/client.md) changed from `` to `''` (use `location.port`). Use the previous value if you want to keep the behavior: ```js export default { dev: { client: { port: '', }, }, }; ``` ## html.appIcon Previously, [html.appIcon](/config/html/app-icon.md) did not support for web app manifests, meaning it was only available on iOS. Now `html.appIcon` supports generating web app manifests, and the type of `html.appIcon` has been changed. * before: ```js export default { html: { appIcon: './src/icon.png', }, }; ``` * after: ```js export default { html: { appIcon: { icons: [{ src: './src/icon.png', size: 180 }], }, }, }; ``` ## Others Rsbuild 1.0 has made some adjustments and optimizations to plugins API and dev server API. Includes: * The `onBeforeBuild` hook supports triggering multiple times in watch mode. * Added `onBeforeEnvironmentCompile` and `onAfterEnvironmentCompile` hooks, which are triggered before/after executing the build of a single environment respectively. * Removed `api.getHtmlPaths` and replaced it with `environment.htmlPaths`. * Removed `api.context.entry` and replaced it with `environment.entry`. * Removed `api.context.targets` and replaced it with `environment.target`. * Removed `rsbuildServer.onHTTPUpgrade` and replaced it with `rsbuildServer.connectWebSocket`. --- # Source: https://rsbuild.dev/guide/configuration/rsbuild.md # Configure Rsbuild Rsbuild provides a wide range of configuration options with sensible defaults for most use cases. In most scenarios, you can use Rsbuild out of the box without any configuration. When you need to customize build behavior, use the options below. ## Configuration structure The Rsbuild configuration structure looks like this: ```js title="rsbuild.config.mjs" export default { plugins: [ // configure Rsbuild plugins ], dev: { // options for local development }, html: { // options for HTML generation }, tools: { // options for the low-level tools }, output: { // options for build outputs }, resolve: { // options for module resolution }, source: { // options for input source code }, server: { // options for the Rsbuild server, // will take effect during local development and preview }, security: { // options for Web security }, performance: { // options for build performance and runtime performance }, moduleFederation: { // options for module federation }, environments: { // define different Rsbuild configurations for each environment }, }; ``` You can find detailed descriptions of every option on the [Configure Overview](/config/index.md) page. ## Configuration file When you use the Rsbuild CLI, it looks for a configuration file in the project root in the following order: * rsbuild.config.mjs * rsbuild.config.ts * rsbuild.config.js * rsbuild.config.cjs * rsbuild.config.mts * rsbuild.config.cts We recommend using `rsbuild.config.ts` and importing the `defineConfig` utility from `@rsbuild/core`. It provides TypeScript hints and autocompletion to help you avoid configuration mistakes. For example, in `rsbuild.config.ts`, you can define the Rsbuild [resolve.alias](/config/resolve/alias.md) configuration: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; export default defineConfig({ resolve: { alias: { '@common': './src/common', }, }, }); ``` If you are developing a non-TypeScript project, you can use the `.mjs` format for the configuration file: ```js title="rsbuild.config.mjs" import { defineConfig } from '@rsbuild/core'; export default defineConfig({ resolve: { alias: (opts) => { opts['@common'] = './src/common'; }, }, }); ``` ## Specify config file The Rsbuild CLI uses the `--config` option to specify the config file. It can be set to a relative or absolute path. For example, if you need to use the `rsbuild.prod.config.mjs` file when running `build`, add the following scripts to `package.json`: ```json title="package.json" { "scripts": { "build": "rsbuild build --config rsbuild.prod.config.mjs" } } ``` You can also abbreviate the `--config` option to `-c`: ```bash rsbuild build -c rsbuild.prod.config.mjs ``` ## Specify config loader Rsbuild provides three ways to load configuration files: * `auto` (Default): Use Node.js's native loader to load configuration files first, falling back to jiti if it fails. * `jiti`: Use [jiti](https://github.com/unjs/jiti) to load the configuration file, providing interoperability between ESM and CommonJS. The module resolution behavior differs slightly from Node.js native behavior. * `native`: Use Node.js native loader to load the configuration file. This ensures that module resolution behavior is consistent with Node.js native behavior and has better performance. This requires your JavaScript runtime to natively support TypeScript. For example, Node.js v22.6.0+ natively supports TypeScript. You can use the following command with the Node.js native loader to load the configuration file: ```bash # Node.js >= v22.18.0 # No need to set --experimental-strip-types npx rsbuild build --config-loader native # Node.js v22.6.0 - v22.17.1 # Need to set --experimental-strip-types NODE_OPTIONS="--experimental-strip-types" npx rsbuild build --config-loader native ``` ### About Node.js native loader When using Node.js's native loader, note the following limitations: 1. When importing JSON files, you need to use import attributes: ```ts import pkgJson from './package.json' with { type: 'json' }; // ✅ Correct import pkgJson from './package.json'; // ❌ Incorrect ``` 2. When importing TypeScript files, you need to include the `.ts` extension: ```ts import baseConfig from './rsbuild.base.config.ts'; // ✅ Correct import baseConfig from './rsbuild.base.config'; // ❌ Incorrect ``` > See [Node.js - Running TypeScript Natively](https://nodejs.org/en/learn/typescript/run-natively#running-typescript-natively) for more details. ## Using environment variables In the configuration file, you can use Node.js environment variables such as `process.env.NODE_ENV` to dynamically set different configurations: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; export default defineConfig({ resolve: { alias: { '@request': process.env.NODE_ENV === 'development' ? './src/request.dev.js' : './src/request.prod.js', }, }, }); ``` ## Export function Rsbuild supports exporting a function in the config file, which allows you to dynamically compute the config and return it to Rsbuild. ```js title="rsbuild.config.js" import { defineConfig } from '@rsbuild/core'; export default defineConfig(({ env, command, envMode }) => ({ resolve: { alias: { '@foo': env === 'development' ? './src/foo.dev.ts' : './src/foo.prod.ts', }, }, })); ``` :::tip The exported config function must provide a return value. If you do not need to return any config, you can return an empty object. ::: The function accepts the following parameters: ### env * **Type:** `string` * **Default:** `process.env.NODE_ENV` The current runtime environment. * When running `rsbuild dev`, the default value of env is `development`. * When running `rsbuild build` or `rsbuild preview`, the default value of env is `production`. ### envMode * **Type:** `string` * **Default:** `process.env.NODE_ENV` The current value of the CLI parameter `--env-mode`. For example, when running `rsbuild build --env-mode test`, the value of `envMode` is `test`. ### command * **Type:** `string` The current CLI command, such as `dev`, `build`, `preview`. ## Export async function Rsbuild also supports exporting an async function in the config file, which lets you perform async work: ```js title="rsbuild.config.js" import { defineConfig } from '@rsbuild/core'; export default defineConfig(async ({ env, command }) => { const result = await someAsyncFunction(); return { html: { title: result, }, }; }); ``` ## Merge configurations You can use the [mergeRsbuildConfig](/api/javascript-api/core.md#mergersbuildconfig) function exported by `@rsbuild/core` to merge multiple configurations. ```ts title="rsbuild.config.ts" import { defineConfig, mergeRsbuildConfig } from '@rsbuild/core'; const config1 = defineConfig({ dev: { port: '3000' }, }); const config2 = defineConfig({ dev: { port: '3001' }, }); // { dev: { port: '3001' } export default mergeRsbuildConfig(config1, config2); ``` ## Debug the config You can enable Rsbuild's debug mode by setting `DEBUG=rsbuild` when running a build. ```bash DEBUG=rsbuild pnpm dev ``` In debug mode, Rsbuild writes the config to the dist directory, making it easier to inspect and debug. ``` config inspection completed, open the following files to view the content: - Rsbuild config: /Project/demo/dist/.rsbuild/rsbuild.config.mjs - Rspack config (web): /Project/demo/dist/.rsbuild/rspack.config.web.mjs ``` Open the generated `/dist/.rsbuild/rsbuild.config.mjs` file to see the complete content of the Rsbuild config. For a complete introduction to debug mode, see the [Debug Mode](/guide/debug/debug-mode.md) chapter. --- # Source: https://rsbuild.dev/guide/debug/rsdoctor.md # Use Rsdoctor [Rsdoctor](https://rsdoctor.rs/) is a build analyzer tailored for the Rspack ecosystem. Rsdoctor aims to be a one-stop, intelligent build analyzer that makes the build process transparent, predictable, and optimizable through visualization and smart analysis, helping teams pinpoint bottlenecks, improve performance, and raise engineering quality. Use Rsdoctor to debug build outputs or the build process. ## Quick start In an Rsbuild project, enable Rsdoctor as follows: 1. Install the Rsdoctor plugin: import { PackageManagerTabs } from '@theme'; 2. Set the `RSDOCTOR=true` environment variable before running the CLI command: ```json title="package.json" { "scripts": { "dev:rsdoctor": "RSDOCTOR=true rsbuild dev", "build:rsdoctor": "RSDOCTOR=true rsbuild build" } } ``` Because Windows does not support this syntax, you can use [cross-env](https://npmjs.com/package/cross-env) to set environment variables across different systems: ```json title="package.json" { "scripts": { "dev:rsdoctor": "cross-env RSDOCTOR=true rsbuild dev", "build:rsdoctor": "cross-env RSDOCTOR=true rsbuild build" }, "devDependencies": { "cross-env": "^7.0.0" } } ``` After running these scripts, Rsbuild automatically registers the Rsdoctor plugin and opens the build analysis page when the build finishes. See the [Rsdoctor documentation](https://rsdoctor.rs/) for all features. ## Options To configure the [options](https://rsdoctor.rs/config/options/options) exposed by the Rsdoctor plugin, manually register the plugin: ```ts title="rsbuild.config.ts" import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin'; export default { tools: { rspack: { plugins: [ process.env.RSDOCTOR === 'true' && new RsdoctorRspackPlugin({ // plugin options }), ], }, }, }; ``` --- # Source: https://rsbuild.dev/config/tools/rspack.md # Source: https://rsbuild.dev/guide/configuration/rspack.md # Configure Rspack Rsbuild supports directly modifying the Rspack configuration object, and supports modifying the built-in Rspack configuration of Rsbuild through `rspack-chain`. :::tip The built-in Rspack config in Rsbuild may change with iterations, and these changes will not be reflected in semver. Therefore, your custom config may become invalid when you upgrade Rsbuild. ::: ## View Rspack config Rsbuild provides the [rsbuild inspect](/guide/basic/cli.md#rsbuild-inspect) command to view the final Rspack config generated by Rsbuild. You can also view it through [debug mode](/guide/debug/debug-mode.md). ## Modify config object You can use the [tools.rspack](/config/tools/rspack.md) option of Rsbuild to modify the Rspack config object. For example, registering a built-in Rspack plugin: ```ts title="rsbuild.config.ts" import { rspack } from '@rsbuild/core'; export default { tools: { rspack: { plugins: [ new rspack.CircularDependencyRspackPlugin({ // options }), ], }, }, }; ``` Or registering a community webpack plugin: ```ts title="rsbuild.config.ts" import { sentryWebpackPlugin } from '@sentry/webpack-plugin'; export default { tools: { rspack: { plugins: [ sentryWebpackPlugin({ // options }), ], }, }, }; ``` Or modify the built-in Rspack config with a function: ```ts title="rsbuild.config.ts" export default { tools: { rspack: (config, { env }) => { if (env === 'development') { config.devtool = 'cheap-module-eval-source-map'; } return config; }, }, }; ``` > Please refer to the [tools.rspack documentation](/config/tools/rspack.md) for detailed usage. ## Access Rspack API If you need to access the API or plugins exported by [@rspack/core](https://npmjs.com/package/@rspack/core), you can directly import the [rspack](/api/javascript-api/core.md#rspack) object from `@rsbuild/core` without installing the `@rspack/core` package separately. ```ts title="rsbuild.config.ts" import { rspack } from '@rsbuild/core'; export default { tools: { rspack: { plugins: [ new rspack.BannerPlugin({ // ... }), ], }, }, }; ``` :::tip * Refer to [Rspack plugins](https://rspack.rs/plugins/) and [Rspack JavaScript API](https://rspack.rs/api/javascript-api/) to learn more about the available Rspack APIs. * It's not recommended to manually install the `@rspack/core` package, as it may conflict with the version that Rsbuild depends on. ::: ## Use bundler chain import RspackChain from '@en/shared/rspackChain.mdx'; ### tools.bundlerChain Rsbuild provides the [tools.bundlerChain](/config/tools/bundler-chain.md) config to modify the rspack-chain. Its value is a function that takes two arguments: * The first argument is an `rspack-chain` instance, which you can use to modify the Rspack config. * The second argument is an utils object, including `env`, `isProd`, `CHAIN_ID`, etc. Here is a basic example: ```ts title="rsbuild.config.ts" export default { tools: { bundlerChain: (chain, { env }) => { if (env === 'development') { chain.devtool('cheap-module-eval-source-map'); } }, }, }; ``` `tools.bundlerChain` can also be an async function: ```ts title="rsbuild.config.ts" export default { tools: { bundlerChain: (chain, { env }) => { const value = await fetchValue(); chain.devtool(value); }, }, }; ``` ### Basics Before using the rspack-chain to modify the Rspack configuration, it is recommended to familiarize yourself with some basics. #### About ID In short, the rspack-chain requires users to set a unique ID for each rule, loader, plugin, and minimizer. With this ID, you can easily find the desired object from deeply nested objects. Rsbuild exports all internally defined IDs through the `CHAIN_ID` object, so you can quickly locate the loader or plugin you want to modify using these exported IDs, without the need for complex traversal in the Rspack configuration object. For example, you can remove the built-in CSS rule using `CHAIN_ID.RULE.CSS`: ```ts title="rsbuild.config.ts" export default { tools: { bundlerChain: (chain, { CHAIN_ID }) => { chain.module.rules.delete(CHAIN_ID.RULE.CSS); }, }, }; ``` #### ID types The `CHAIN_ID` object contains various IDs, which correspond to the following configurations: | CHAIN\_ID Field | Corresponding Configuration | Description | | -------------------- | --------------------------- | ------------------------------------------------------ | | `CHAIN_ID.PLUGIN` | `plugins[i]` | Corresponds to a plugin in the Rspack configuration | | `CHAIN_ID.RULE` | `module.rules[i]` | Corresponds to a rule in the Rspack configuration | | `CHAIN_ID.USE` | `module.rules[i].loader` | Corresponds to a loader in the Rspack configuration | | `CHAIN_ID.MINIMIZER` | `optimization.minimizer` | Corresponds to a minimizer in the Rspack configuration | ### Examples #### Custom loader Here are examples of adding, modifying, and removing Rspack loaders. * Add a loader to handle `.md` files: ```js title="rsbuild.config.mjs" export default { tools: { bundlerChain: (chain) => { chain.module .rule('md') .test(/\.md$/) .use('md-loader') // The package name or module path of the loader .loader('md-loader'); }, }, }; ``` * Modify options of the built-in SWC loader: ```js title="rsbuild.config.mjs" export default { tools: { bundlerChain: (chain, { CHAIN_ID }) => { chain.module .rule(CHAIN_ID.RULE.JS) .use(CHAIN_ID.USE.SWC) .tap((options) => { console.log(options); return options; }); }, }, }; ``` * Remove the built-in SWC loader: ```js title="rsbuild.config.mjs" export default { tools: { bundlerChain: (chain, { CHAIN_ID }) => { chain.module.rule(CHAIN_ID.RULE.JS).uses.delete(CHAIN_ID.USE.SWC); }, }, }; ``` * Insert a loader after the built-in SWC loader that executes earlier: ```js title="rsbuild.config.mjs" export default { tools: { bundlerChain: (chain, { CHAIN_ID }) => { chain.module .rule(CHAIN_ID.RULE.JS) .use('my-loader') .after(CHAIN_ID.USE.SWC) // The package name or module path of the loader .loader('my-loader') .options({ // some options }); }, }, }; ``` > Note: Rspack loaders are executed in reverse order. * Insert a loader before the built-in SWC loader that executes later: ```js title="rsbuild.config.mjs" export default { tools: { bundlerChain: (chain, { CHAIN_ID }) => { chain.module .rule(CHAIN_ID.RULE.JS) // Loader ID, not actually meaningful, just for locating .use('my-loader') .before(CHAIN_ID.USE.SWC) // The package name or module path of the loader .loader('my-loader') .options({ // some options }); }, }, }; ``` * Remove the built-in CSS handling rule: ```js title="rsbuild.config.mjs" export default { tools: { bundlerChain: (chain, { CHAIN_ID }) => { chain.module.rules.delete(CHAIN_ID.RULE.CSS); }, }, }; ``` #### Custom plugin Here are examples of adding, modifying, and deleting Rspack plugins. ```js title="rsbuild.config.mjs" export default { tools: { bundlerChain: (chain, { bundler, CHAIN_ID }) => { // Add plugin chain.plugin('custom-define').use(bundler.DefinePlugin, [ { 'process.env': { NODE_ENV: JSON.stringify(process.env.NODE_ENV), }, }, ]); // Modify plugin chain.plugin(CHAIN_ID.PLUGIN.HMR).tap((options) => { options[0].fullBuildTimeout = 200; return options; }); // Delete plugin chain.plugins.delete(CHAIN_ID.PLUGIN.HMR); }, }, }; ``` :::tip In most cases, you should change the plugin options using the configurations provided by Rsbuild, rather than using `CHAIN_ID.PLUGIN`, as this may lead to unexpected behavior. For example, use [tools.htmlPlugin](/config/tools/html-plugin.md) to change the options of HtmlPlugin. ::: #### Modify based on environment In the `tools.bundlerChain` function, you can access various environment identifiers in the second parameter, such as development/production build, SSR build, Web Worker build, to achieve configuration modifications for different environments. ```js title="rsbuild.config.mjs" export default { tools: { bundlerChain: (chain, { env, isProd, target, isServer, isWebWorker }) => { if (env === 'development' || env === 'test') { // ... } if (isProd) { // ... } if (target === 'node') { // ... } if (isServer) { // ... } if (isWebWorker) { // ... } }, }; ``` The above are some common configuration examples. For the complete rspack-chain API, please refer to the [rspack-chain documentation](https://github.com/rstackjs/rspack-chain). ## Configuration modification order Rsbuild supports modifying the Rspack configuration object through `tools.rspack`, `tools.bundlerChain`, `modifyBundlerChain`, etc. The order of execution between them is: * [modifyBundlerChain](/plugins/dev/hooks.md#modifybundlerchain) * [tools.bundleChain](/config/tools/bundler-chain.md) * [modifyRspackConfig](/plugins/dev/hooks.md#modifyrspackconfig) * [tools.rspack](/config/tools/rspack.md) --- # Source: https://rsbuild.dev/guide/basic/server.md # Dev server Rsbuild includes a built-in dev server that enhances the development experience. When you run `rsbuild dev` or `rsbuild preview`, the server starts and provides features like page preview, routing, and hot module replacement. ## Base path By default, the Rsbuild server's base path is `/`. You can access output files like `index.html` and [public folder](/guide/basic/static-assets.md#public-folder) assets at `http://localhost:3000/`. To change the server's base path, use [server.base](/config/server/base.md). For example, to access files at `http://localhost:3000/foo/`: ```ts title="rsbuild.config.ts" export default { server: { base: '/foo', }, }; ``` ## View static assets After starting the dev server, visit `/rsbuild-dev-server` to view all static assets generated during the current build. For example, open `http://localhost:3000/rsbuild-dev-server` in your browser: rsbuild-dev-server ## Page routing The Rsbuild server provides default routing conventions and allows customization through configuration. ### Default behavior The Rsbuild server generates page routes based on the [server.base](/config/server/base.md) and [source.entry](/config/source/entry.md) configurations. When the entry is `index`, access the page at `/`. When the entry is `foo`, access the page at `/foo`. When `server.base` is `/base`, access the index page at `/base`, and the foo page at `/base/foo`. ```ts title="rsbuild.config.ts" export default { source: { entry: { index: './src/index.ts', foo: './src/pages/foo/index.ts', }, }, }; ``` ### Fallback behavior If a request meets the following conditions but no corresponding static asset exists, [server.htmlFallback](/config/server/html-fallback.md) triggers and falls back to `index.html` by default: * The request method is `GET` or `HEAD` * The `Accept` header contains `text/html` (for example, `text/html` or `*/*`) ### Custom fallback behavior If Rsbuild's default [server.htmlFallback](/config/server/html-fallback.md) configuration doesn't meet your needs (for example, serving `main.html` when accessing `/`), use [server.historyApiFallback](/config/server/history-api-fallback.md) instead. ```ts title="rsbuild.config.ts" export default { source: { entry: { main: './src/index.ts', }, }, server: { historyApiFallback: { index: '/main.html', }, }, }; ``` ### HTML output path Normally, `/` points to the dist root directory, and HTML files are output there. In this case, access HTML pages at `/some-path`. If you output HTML files to other subdirectories using [output.distPath.html](/config/output/dist-path.md), access HTML pages at `/[htmlPath]/some-path` instead. For example, if you set HTML files to output to the `HTML` directory, access index.html at `/html/`, and foo.html at `/html/foo`. ```ts export default { source: { entry: { index: './src/index.ts', foo: './src/pages/foo/index.ts', }, }, output: { distPath: { html: 'html', }, }, }; ``` ## Rspack dev server Rsbuild includes its own lightweight dev server, which differs from the servers in Rspack CLI and webpack CLI and offers its own configuration options. ### Comparison Compared to the dev server in Rspack CLI, Rsbuild's dev server has the following differences: * **Configuration**: Rsbuild provides richer server configuration options. * **Log Format**: The log format of Rspack CLI is largely consistent with webpack CLI, while Rsbuild's logs are clearer and more readable. * **Dependencies**: Rsbuild is built on lightweight libraries like `connect`, which has fewer dependencies and faster startup than `express` used by `@rspack/dev-server`. ### Configuration Rsbuild doesn't support Rspack's [devServer](https://rspack.rs/config/dev-server) config. Use Rsbuild's `dev` and `server` configs instead. In Rsbuild, the `dev` config contains settings that only apply in development mode, while the `server` config applies to both dev and preview servers. Below are the Rsbuild configuration options that correspond to Rspack CLI's `devServer` config: | Rspack CLI | Rsbuild | | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | [devServer.client](https://rspack.rs/config/dev-server#devserverclient) | [dev.client](/config/dev/client.md) | | [devServer.compress](https://rspack.rs/config/dev-server#devservercompress) | [server.compress](/config/server/compress.md) | | [devServer.devMiddleware.writeToDisk](https://rspack.rs/config/dev-server#devserverdevmiddleware) | [dev.writeToDisk](/config/dev/write-to-disk.md) | | [devServer.headers](https://rspack.rs/config/dev-server#devserverheaders) | [server.headers](/config/server/headers.md) | | [devServer.historyApiFallback](https://rspack.rs/config/dev-server#devserverhistoryapifallback) | [server.historyApiFallback](/config/server/history-api-fallback.md) | | [devServer.host](https://rspack.rs/config/dev-server#devserverhost) | [server.host](/config/server/host.md) | | [devServer.hot](https://rspack.rs/config/dev-server#devserverhot) | [dev.hmr](/config/dev/hmr.md) | | [devServer.liveReload](https://rspack.rs/config/dev-server#devserverlivereload) | [dev.liveReload](/config/dev/live-reload.md) | | [devServer.open](https://rspack.rs/config/dev-server#devserveropen) | [server.open](/config/server/open.md) | | [devServer.port](https://rspack.rs/config/dev-server#devserverport) | [server.port](/config/server/port.md) | | [devServer.proxy](https://rspack.rs/config/dev-server#devserverproxy) | [server.proxy](/config/server/proxy.md) | | [devServer.setupMiddlewares](https://rspack.rs/config/dev-server#devserversetupmiddlewares) | [dev.setupMiddlewares](/config/dev/setup-middlewares.md) | | [devServer.static](https://rspack.rs/config/dev-server#devserverstatic) | [server.publicDir](/config/server/public-dir.md) | | [devServer.watchFiles](https://rspack.rs/config/dev-server#devserverwatchfiles) | [dev.watchFiles](/config/dev/watch-files.md) | > For more configurations, refer to [Config Overview](/config/index.md). ## Middleware Rsbuild's middleware implementation is built on [connect](https://github.com/senchalabs/connect), a lightweight HTTP server framework, and uses the standard Node.js `request` and `response` objects for handling HTTP interactions. ### Register middleware Rsbuild provides three ways to register middleware: 1. Use the [dev.setupMiddlewares](/config/dev/setup-middlewares.md) configuration. ```ts title="rsbuild.config.ts" export default { dev: { setupMiddlewares: (middlewares) => { middlewares.push((req, res, next) => { next(); }); }, }, }; ``` 2. In the Rsbuild plugin, you can register middleware through the [onBeforeStartDevServer](/plugins/dev/hooks.md#onbeforestartdevserver) hook. ```ts const myPlugin = () => ({ setup(api) { api.onBeforeStartDevServer(({ server }) => { server.middlewares.use((req, res, next) => { next(); }); }); }, }); ``` 3. When using the Rsbuild JavaScript API, you can create a dev server instance through the [rsbuild.createDevServer](/api/javascript-api/instance.md#rsbuildcreatedevserver) method and use the `use` method to register middleware. ```ts const server = await rsbuild.createDevServer(); server.middlewares.use((req, res, next) => { next(); }); ``` ### Integrate third-party server frameworks When migrating from other server frameworks like Express, the original middleware may not work directly in Rsbuild. For example, Express-specific properties like `req.params`, `req.path`, `req.search`, and `req.query` aren't available in Rsbuild middleware. To reuse existing middleware in Rsbuild, integrate your entire server application as middleware: ```ts title="rsbuild.config.ts" import express from 'express'; import expressMiddleware from 'my-express-middleware'; // Initialize Express app const app = express(); app.use(expressMiddleware); export default { dev: { setupMiddlewares: (middlewares) => { middlewares.unshift(app); }, }, }; ``` ## Custom server To integrate Rsbuild's dev server into a custom server, use the `createDevServer` method to get the Rsbuild dev server instance and call its methods as needed. For details, refer to [Rsbuild - createDevServer](/api/javascript-api/instance.md#rsbuildcreatedevserver). --- # Source: https://rsbuild.dev/config/dev/setup-middlewares.md # dev.setupMiddlewares * **Type:** ```ts type SetupMiddlewaresContext = { sockWrite: ( type: string, data?: string | boolean | Record, ) => void; environments: EnvironmentAPI; }; type SetupMiddlewaresFn = ( middlewares: { unshift: (...handlers: RequestHandler[]) => void; push: (...handlers: RequestHandler[]) => void; }, context: SetupMiddlewaresContext, ) => void; type SetupMiddlewares = SetupMiddlewaresFn | SetupMiddlewaresFn[]; ``` * **Default:** `undefined` * **Version:** `>= 1.4.0` Used to add custom middleware to the dev server. > See [Dev server - Middleware](/guide/basic/server.md#middleware) for more information. ## Basic usage `setupMiddlewares` function receives a `middlewares` array, you can add custom middleware by `unshift` and `push` methods: * Use `unshift` to prepend middleware to the array, executed earlier than the built-in middleware. * Use `push` to append middleware to the array, executed later than the built-in middleware. ```ts title="rsbuild.config.ts" export default { dev: { setupMiddlewares: (middlewares) => { middlewares.unshift((req, res, next) => { console.log('first'); next(); }); middlewares.push((req, res, next) => { console.log('last'); next(); }); }, }, }; ``` The middleware can be an async function: ```ts title="rsbuild.config.ts" export default { dev: { setupMiddlewares: (middlewares) => { middlewares.unshift(async (req, res, next) => { await someAsyncOperation(); next(); }); }, }, }; ``` `setupMiddlewares` also supports passing an array, each item of which is a function to set up middlewares: ```ts title="rsbuild.config.ts" export default { dev: { setupMiddlewares: [ (middlewares) => { // ... }, (middlewares) => { // ... }, ], }, }; ``` :::tip In versions before Rsbuild 1.4.0, `setupMiddlewares` must pass an array. ::: ## Context object The second parameter of the `setupMiddlewares` function is the `context` object, which provides some server context and APIs. ### environments Provides Rsbuild's [environment API](/api/javascript-api/environment-api.md#environment-api), see [Dev server API - environments](/api/javascript-api/dev-server-api.md#environments) for more details. ```ts title="rsbuild.config.ts" export default { dev: { setupMiddlewares: (middlewares, { environments }) => { middlewares.unshift(async (req, _res, next) => { const webStats = await environments.web.getStats(); console.log(webStats.toJson({ all: false })); next(); }); }, }, }; ``` ### sockWrite Sends some message to HMR client, see [Dev server API - sockWrite](/api/javascript-api/dev-server-api.md#sockwrite) for more details. For example, if you send a `'static-changed'` message, the page will reload. ```ts title="rsbuild.config.ts" export default { dev: { setupMiddlewares: (middlewares, { sockWrite }) => { if (someCondition) { sockWrite('static-changed'); } }, }, }; ``` --- # Source: https://rsbuild.dev/guide/framework/solid.md # Solid In this document, you will learn how to build a Solid application using Rsbuild. ## Create a Solid application Use [create-rsbuild](/guide/start/quick-start.md#create-an-rsbuild-application) to create a Solid application with Rsbuild. Run the following command: import { PackageManagerTabs } from '@theme'; Then select `Solid` when prompted to "Select framework". ## Use Solid in an existing project To compile Solid components, you need to register the Rsbuild [Solid plugin](/plugins/list/plugin-solid.md). The plugin will automatically add the necessary configuration for Solid builds. For example, register in `rsbuild.config.ts`: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginBabel } from '@rsbuild/plugin-babel'; import { pluginSolid } from '@rsbuild/plugin-solid'; export default defineConfig({ plugins: [ pluginBabel({ include: /\.(?:jsx|tsx)$/, }), pluginSolid(), ], }); ``` --- # Source: https://rsbuild.dev/config/output/source-map.md # output.sourceMap * **Type:** ```ts type SourceMap = | boolean | { js?: Rspack.Configuration['devtool']; css?: boolean; }; ``` * **Default:** ```ts const defaultSourceMap = { js: mode === 'development' ? 'cheap-module-source-map' : false, css: false, }; ``` Configures whether to generate source map files and which source map format to generate. :::tip What is a source map A source map is an information file that stores source code mapping relationships. It records each location of the compiled code and its corresponding pre-compilation location. With source maps, you can directly view source code when debugging compiled code. ::: ## Default behavior Rsbuild generates source maps using these rules by default: * In development mode, source maps for JS files are generated for development debugging, while source maps for CSS files are not generated. * In production mode, source maps for JS and CSS files are not generated to improve build performance. ## Boolean value If `output.sourceMap` is `true`, source maps are generated according to the [mode](/config/mode.md), equivalent to: ```ts title="rsbuild.config.ts" export default { output: { sourceMap: { js: mode === 'development' ? 'cheap-module-source-map' : 'source-map', css: true, }, }, }; ``` If `output.sourceMap` is `false`, no source map will be generated, equivalent to: ```ts title="rsbuild.config.ts" export default { output: { sourceMap: { js: false, css: false, }, }, }; ``` ## JS source map The source map for JS files is controlled by `sourceMap.js` and accepts any source map format supported by Rspack's [devtool](https://rspack.rs/config/devtool) option. Setting it to `false` will disable the source map. For example, to generate high-quality source maps in all environments: ```ts title="rsbuild.config.ts" export default { output: { sourceMap: { js: 'source-map', }, }, }; ``` You can also set different source map formats based on the environment. ```ts title="rsbuild.config.ts" export default { output: { sourceMap: { js: process.env.NODE_ENV === 'production' ? // Use a high quality source map format for production 'source-map' : // Use a more performant source map format for development 'cheap-module-source-map', }, }, }; ``` :::warning Do not deploy source maps (`.map` files) to the public web server or CDN when using values such as `source-map` or `hidden-source-map` in production builds. Public source maps will expose your source code and may bring security risks. ::: ## CSS source map The source map for CSS files is controlled by `sourceMap.css`. Setting it to `true` will enable the source map, while setting it to `false` will disable it. To generate a source map for CSS files: ```ts title="rsbuild.config.ts" export default { output: { sourceMap: { css: true, }, }, }; ``` In production builds, it is not recommended to enable both [output.injectStyles](/config/output/inject-styles.md) and `output.sourceMap.css`, as `output.injectStyles` will inject the source map into the JS bundles, which will increase the file size and slow down the page loading speed. You can only enable the CSS file source map in development mode: ```ts title="rsbuild.config.ts" export default { output: { injectStyles: true, sourceMap: { css: process.env.NODE_ENV === 'development', }, }, }; ``` --- # Source: https://rsbuild.dev/config/security/sri.md # security.sri * **Type:** ```ts type SriAlgorithm = 'sha256' | 'sha384' | 'sha512'; type SriOptions = { enable?: 'auto' | boolean; algorithm?: SriAlgorithm | SriAlgorithm[]; }; ``` * **Default:** `undefined` Adds an `integrity` attribute to ` ``` In addition, the [manifest file](/config/output/manifest.md#sri) generated by Rsbuild will also include an `integrity` field. ## Note The `security.sri` in Rsbuild will only apply to the tags generated by Rspack and Rsbuild and will not apply to: * The original tags in the HTML template. * The tags inserted through client JavaScript code. Rsbuild will handle the following `` tags: * `` * `` * `` ## Options ### enable * **Type:** `'auto' | boolean` * **Default:** `false` Whether to enable SRI. `'auto'` means it is enabled in production mode and disabled in development mode. ```ts title="rsbuild.config.ts" export default { security: { sri: { enable: 'auto', }, }, }; ``` > Typically, you do not need to enable SRI in development mode. ### algorithm * **Type:** `SriAlgorithm | SriAlgorithm[]` * **Default:** `'sha384'` Specifies the algorithm used to compute the integrity hash. For example, set to `sha512`: ```ts title="rsbuild.config.ts" export default { security: { sri: { algorithm: 'sha512', }, }, }; ``` The generated value of integrity attribute will be prefixed with `sha512-`: ```html ``` Or configure multiple algorithms: ```ts title="rsbuild.config.ts" export default { security: { sri: { algorithm: ['sha384', 'sha256'], }, }, }; ``` > Reference: [Cryptographic hash functions](https://www.w3.org/TR/SRI/#cryptographic-hash-functions). ## Version history | Version | Changes | | ------- | ----------------------------------- | | v1.6.15 | Add support for multiple algorithms | --- # Source: https://rsbuild.dev/guide/advanced/ssr.md # Server-side rendering (SSR) This chapter introduces how to implement SSR functionality using Rsbuild. Rsbuild does not ship with SSR by default. Instead, it offers low-level APIs and configurations so framework developers can build SSR support. If you need SSR that works out of the box, consider a full-stack framework built on Rsbuild, such as [Modern.js](https://github.com/web-infra-dev/modern.js). ## What is SSR SSR stands for "Server-Side Rendering". It means that the server generates the page's HTML and sends it to the client, rather than sending only an empty HTML shell and relying on JavaScript to generate the page content. In traditional client-side rendering, the server sends an empty HTML shell and some JavaScript scripts to the client, which then fetches data from the server's API and fills the page with dynamic content. This leads to slow initial page loading times and negatively impacts user experience and SEO. With SSR, the server generates HTML that already contains dynamic content and sends it to the client. This makes initial page loading faster and more SEO-friendly, as search engines can crawl the rendered page. ## File structure A typical SSR application will have the following files: ``` - index.html - server.js # main application server - src/ - App.js # exports app code - index.client.js # client entry, mounts the app to a DOM element - index.server.js # server entry, renders the app using the framework's SSR API ``` The `index.html` will need to include a placeholder where the server-rendered content should be injected: ```html
``` ## Create SSR configuration In SSR scenarios, you need to generate web and node outputs at the same time for client-side rendering (CSR) and server-side rendering (SSR). You can then use Rsbuild's [multi-environment builds](/guide/advanced/environments.md) capability to define the following configuration: ```ts title="rsbuild.config.ts" export default { environments: { // Configure the web environment for browsers web: { source: { entry: { index: './src/index.client.js', }, }, output: { // Use 'web' target for the browser outputs target: 'web', }, html: { // Custom HTML template template: './index.html', }, }, // Configure the node environment for SSR node: { source: { entry: { index: './src/index.server.js', }, }, output: { // Use 'node' target for the Node.js outputs target: 'node', }, }, }, }; ``` ## Custom server Rsbuild provides the [Dev server API](/api/javascript-api/dev-server-api.md) and [environment API](/guide/advanced/environments.md#environment-api) to allow you to implement SSR. Here is a basic example: ```ts title="server.mjs" import express from 'express'; import { createRsbuild } from '@rsbuild/core'; async function initRsbuild() { const rsbuild = await createRsbuild({ config: { server: { middlewareMode: true, }, }, }); return rsbuild.createDevServer(); } async function startDevServer() { const app = express(); const rsbuild = await initRsbuild(); const { environments } = rsbuild; // SSR when accessing /index.html app.get('/', async (req, res, next) => { try { // Load server bundle const bundle = await environments.node.loadBundle('index'); const template = await environments.web.getTransformedHtml('index'); const rendered = bundle.render(); // Insert rendered content into HTML template const html = template.replace('', rendered); res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(html); } catch (err) { logger.error('SSR failed.'); logger.error(err); next(); } }); app.use(rsbuild.middlewares); const server = app.listen(rsbuild.port, async () => { await rsbuild.afterListen(); }); rsbuild.connectWebSocket({ server }); } startDevServer(); ``` ## Modify startup script When you use a custom server, change the startup command from `rsbuild dev` to `node ./server.mjs`. To preview the production SSR output, update the preview command as well. For an example of a production SSR server, see [Example](https://github.com/rstackjs/rstack-examples/blob/main/rsbuild/ssr-express/prod-server.mjs). ```json title="package.json" { "scripts": { "build": "rsbuild build", "dev": "node ./server.mjs", "preview": "node ./prod-server.mjs" } } ``` You can now run `npm run dev` to start the dev server with SSR and open `http://localhost:3000/` to see the server-rendered content in the HTML page. ## Get manifest By default, Rsbuild automatically inserts the scripts and links for the current page into the HTML template. You can retrieve the compiled template with [getTransformedHtml](/api/javascript-api/environment-api.md#gettransformedhtml). When you need to dynamically generate HTML on the server side, you will need to inject the URLs of JavaScript and CSS assets into the HTML. By configuring [output.manifest](/config/output/manifest.md), you can easily obtain the manifest information of these assets. Here is an example: ```ts title="rsbuild.config.ts" export default { output: { manifest: true, }, }; ``` ```ts title="server.ts" async function renderHtmlPage(): Promise { const manifest = await fs.promises.readFile('./dist/manifest.json', 'utf-8'); const { entries } = JSON.parse(manifest); const { js, css } = entries['index'].initial; const scriptTags = js .map((url) => ``) .join('\n'); const styleTags = css .map((file) => ``) .join('\n'); return ` ${scriptTags} ${styleTags}
`; } ``` ## Examples * [SSR + Express Example](https://github.com/rstackjs/rstack-examples/blob/main/rsbuild/ssr-express) * [SSR + Express + Manifest Example](https://github.com/rstackjs/rstack-examples/blob/main/rsbuild/ssr-express-with-manifest) ## SSR-specific plugins When developing Rsbuild plugins, if you need to add specific logic for SSR, you can distinguish it by `target`. * Modify Rsbuild configuration for SSR via [modifyEnvironmentConfig](/plugins/dev/hooks.md#modifyenvironmentconfig): ```js export const myPlugin = () => ({ name: 'my-plugin', setup(api) { api.modifyEnvironmentConfig((config) => { if (config.target === 'node') { // SSR-specific Rsbuild config } }); }, }); ``` * Modify Rspack configuration for SSR via [modifyRspackConfig](/plugins/dev/hooks.md#modifyrspackconfig): ```js export const myPlugin = () => ({ name: 'my-plugin', setup(api) { api.modifyRspackConfig((config, { target }) => { if (target === 'node') { // SSR-specific Rspack config } }); }, }); ``` * Transform code for SSR and client separately via [transform](/plugins/dev/core.md#apitransform): ```js export const myPlugin = () => ({ name: 'my-plugin', setup(api) { api.transform({ test: /foo\.js$/, targets: ['web'] }, ({ code }) => { // transform client code }); api.transform({ test: /foo\.js$/, targets: ['node'] }, ({ code }) => { // transform server code }); }, }); ``` --- # Source: https://rsbuild.dev/guide/basic/static-assets.md # Static assets Rsbuild supports importing static assets, including images, fonts, audio, and video. :::tip What are static assets Static assets are files that are part of a web application and don't change during use. Examples include images, fonts, media files, stylesheets, and JavaScript files. These assets are typically stored on a web server or CDN and delivered to the user's browser when they access the application. Because they don't change, static assets can be cached by the browser, improving application performance. ::: ## Asset formats Rsbuild supports these formats by default: * **Images**: png, jpg, jpeg, gif, svg, bmp, webp, ico, apng, avif, tif, tiff, jfif, pjpeg, pjp, cur. * **Fonts**: woff, woff2, eot, ttf, otf, ttc. * **Audio**: mp3, wav, flac, aac, m4a, opus. * **Video**: mp4, webm, ogg, mov. To import assets in other formats, refer to [Extend Asset Types](#extend-asset-types). :::tip SVG images SVG images are a special case. Rsbuild supports converting SVG to React components, so SVG files are processed separately. For details, see [SVGR Plugin](/plugins/list/plugin-svgr.md). ::: ## Importing assets in JavaScript files In JavaScript files, import static assets using relative paths: ```tsx // Import the logo.png image in the static directory import logo from './static/logo.png'; console.log(logo); // "/static/logo.[hash].png" export default () => ; ``` Importing with [alias](/guide/advanced/alias.md) is also supported: ```tsx import logo from '@/static/logo.png'; console.log(logo); // "/static/logo.[hash].png" export default () => ; ``` ### URL assets Rsbuild supports using JavaScript's native [URL](https://developer.mozilla.org/docs/Web/API/URL) and [import.meta.url](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/import.meta) to import static assets. ```tsx const logo = new URL('./static/logo.png', import.meta.url).href; console.log(logo); // "/static/logo.[hash].png" export default () => ; ``` When using `new URL()` to reference `.js` or `.ts` files, they're treated as URL assets and aren't processed by Rsbuild's built-in SWC loader. ```tsx // foo.ts will remain the original content and be output to the dist directory const fooTs = new URL('./foo.ts', import.meta.url).href; console.log(fooTs); // "/static/foo.[hash].ts" ``` Similarly, when using `new URL()` to reference `.css` or `.scss` files, they're treated as URL assets and aren't processed by Rsbuild's built-in CSS loaders. ```tsx // foo.css will remain the original content and be output to the dist directory const fooCss = new URL('./foo.css', import.meta.url).href; console.log(fooCss); // "/static/foo.[hash].css" ``` ## Importing assets in CSS files In CSS files, you can reference static assets using relative paths: ```css .logo { background-image: url('../static/logo.png'); } ``` Importing with [alias](/guide/advanced/alias.md) is also supported: ```css .logo { background-image: url('@/static/logo.png'); } ``` If you want to reference static assets using absolute paths in CSS files: ```css @font-face { font-family: DingTalk; src: url('/image/font/foo.ttf'); } ``` By default, Rsbuild's built-in `css-loader` will resolve absolute paths in `url()` and look for the specified modules. To skip resolving absolute paths, you can configure [`tools.cssLoader`](/config/tools/css-loader.md#toolscssloader) to filter out specific paths. Filtered paths will remain unchanged in the code. ```ts export default { tools: { cssLoader: { url: { filter: (url) => { if (/\/image\/font/.test(url)) { return false; } return true; }, }, }, }, }; ``` ## Inline assets The result of importing static assets depends on the file size: * If the file size is less than 4KiB, it will be converted to a base64 string and inlined in the code. * If the file size is larger than 4KiB, a URL will be returned and the file will be emitted to the output directory. ```js import largeImage from './static/largeImage.png'; import smallImage from './static/smallImage.png'; console.log(largeImage); // "/static/largeImage.[hash].png" console.log(smallImage); // "data:image/png;base64,iVBORw0KGgo..." ``` Adding the `?url` query parameter ensures the asset is always loaded as a separate file and returns a URL: ```js import image from './static/image.png?url'; console.log(image); // "/static/image.[hash].png" ``` Adding the `?inline` query parameter ensures the asset is always inlined in the code, regardless of file size: ```js import image from './static/image.png?inline'; console.log(image); // "data:image/png;base64,iVBORw0KGgo..." ``` For a more detailed introduction to asset inlining, refer to the [Static Asset Inlining](/guide/optimization/inline-assets.md) section. ## Importing as string Rsbuild supports using the `?raw` query parameter to import the raw content of static assets as a string in JavaScript. ```ts import rawSvg from './static/logo.svg?raw'; console.log(rawSvg); // The raw content of the SVG file ``` Rsbuild also supports importing the raw content of JavaScript, TypeScript, and JSX files through the `?raw` query parameter. ```ts import rawJs from './script1.js?raw'; import rawTs from './script2.ts?raw'; import rawJsx from './script3.jsx?raw'; import rawTsx from './script4.tsx?raw'; console.log(rawJs); // The raw content of the JS file console.log(rawTs); // The raw content of the TS file console.log(rawJsx); // The raw content of the JSX file console.log(rawTsx); // The raw content of the TSX file ``` You can also use the `?raw` query parameter to import the raw content of CSS files, see [CSS](/guide/styling/css-usage.md#raw). :::tip Rsbuild >= 1.3.0 supports the `?raw` query parameter, and >= 1.4.0 supports importing the raw content of JS and TS files. ::: ## Output files When static assets are imported, they will be output to the dist directory. You can: * Use [output.filename](/config/output/filename.md) to modify the output filename. * Use [output.distPath](/config/output/dist-path.md) to modify the output path. Read [Output Files](/guide/basic/output-files.md) for details. ## URL prefix The URL returned after importing an asset will automatically include the path prefix: * In development, use [dev.assetPrefix](/config/dev/asset-prefix.md) to set the path prefix. * In production, use [output.assetPrefix](/config/output/asset-prefix.md) to set the path prefix. * When either `dev.assetPrefix` or `output.assetPrefix` is not configured, the value of [server.base](/config/server/base.md) will be automatically used as the default prefix. For example, you can set `output.assetPrefix` to `https://example.com`: ```ts title="rsbuild.config.ts" export default { output: { assetPrefix: 'https://example.com', }, }; ``` ```js import logo from './static/logo.png'; console.log(logo); // "https://example.com/static/logo.[hash].png" ``` ## Public folder The public folder at the project root can be used to place static assets. These assets won't be built by Rsbuild and can be directly referenced via URL. * When you start the dev server, these assets will be served under the [server.base](/config/server/base.md) path (default `/`). * When you perform a production build, these assets will be copied to the [dist directory](/guide/basic/output-files.md). For example, you can place files such as `robots.txt`, `manifest.json`, or `favicon.ico` in the public folder. ### How to reference You can reference files in the `public` directory via URL. For example, in an HTML template, the `./public/favicon.ico` file can be referenced as `/favicon.ico`. [BASE\_URL](/guide/advanced/env-vars.md#processenvpublic_base_path) is the base path of the server. ```html title="index.html" ``` ### Notes Keep these points in mind when using the `public` folder: * When referencing assets in the public folder via URL, use absolute paths instead of relative paths to ensure assets can be accessed correctly after deployment. ```html title="src/index.html" ``` * Avoid importing files from the public directory into your source code. The correct approach is to reference them by URL. You can place static assets that need to be imported into source code in the `/src/assets` directory. ```js title="src/index.js" // Wrong import logo from '../public/logo.png'; // Correct import logo from './assets/logo.png'; ``` * During the production build, files in the public folder are copied to the output folder (default is `dist`). Be careful to avoid name conflicts with output files. When files in the `public` folder have the same name as outputs, the outputs have higher priority and will overwrite the conflicting public folder files. This feature can be disabled by setting [server.publicDir.copyOnBuild](/config/server/public-dir.md) to `false`. ### Custom behavior Rsbuild provides the [server.publicDir](/config/server/public-dir.md) option which can be used to customize the name and behavior of the public folder, as well as to disable it. ```ts title="rsbuild.config.ts" export default { server: { publicDir: false, }, }; ``` ## Type declaration When you import static assets in TypeScript code, TypeScript may prompt that the module is missing a type definition: ``` TS2307: Cannot find module './logo.png' or its corresponding type declarations. ``` To fix this, you need to add a type declaration file for the static assets, please create a `src/env.d.ts` file, and add the corresponding type declaration. * Method 1: If the `@rsbuild/core` package is installed, you can reference the [preset types](/guide/basic/typescript.md#preset-types) provided by `@rsbuild/core`: ```ts /// ``` * Method 2: Manually add the required type declarations: ```ts title="src/env.d.ts" // Taking png images as an example declare module '*.png' { const content: string; export default content; } ``` After adding the type declaration, if the type error still exists, you can try to restart the current IDE, or adjust the directory where `env.d.ts` is located, making sure that TypeScript can correctly identify the type definition. ## Extend asset types If the built-in asset types in Rsbuild cannot meet your requirements, you can extend additional static asset types in the following ways. ### Use `source.assetsInclude` By using the [source.assetsInclude](/config/source/assets-include.md) config, you can specify additional file types to be treated as static assets. ```ts title="rsbuild.config.ts" export default { source: { assetsInclude: /\.pdf$/, }, }; ``` After adding the above configuration, you can import `*.pdf` files in your code, for example: ```js import myFile from './static/myFile.pdf'; console.log(myFile); // "/static/myFile.[hash].pdf" ``` ### Use `tools.rspack` You can modify the built-in Rspack configuration and add custom static assets handling rules via [tools.rspack](/config/tools/rspack.md). For example, to treat `*.pdf` files as assets and output them to the dist directory, you can add the following configuration: ```ts title="rsbuild.config.ts" export default { tools: { rspack(config, { addRules }) { addRules([ { test: /\.pdf$/, // converts asset to a separate file and exports the URL address. type: 'asset/resource', }, ]); }, }, }; ``` For more information about asset modules, please refer to [Rspack - Asset modules](https://rspack.rs/guide/features/asset-module). ### Related configurations Extended static asset types will be affected by the following configurations: * [output.filename.assets](/config/output/filename.md): Set the name of extended static assets. * [output.distPath.assets](/config/output/dist-path.md): Set the output directory of extended static assets. * [output.dataUriLimit.assets](/config/output/data-uri-limit.md): Set the threshold of inlining for extended static assets. ## Custom rules In some scenarios, you may need to bypass the built-in assets processing rules of Rsbuild and add some custom rules. Taking PNG image as an example, you need to: 1. Modify the built-in Rspack config via [tools.bundlerChain](/config/tools/bundler-chain.md) to exclude `.png` files using the `exclude` method. 2. Add custom asset processing rules via [tools.rspack](/config/tools/rspack.md). ```ts title="rsbuild.config.ts" export default { tools: { bundlerChain(chain, { CHAIN_ID }) { chain.module // Use `CHAIN_ID.RULE.IMAGE` to locate the built-in image rule .rule(CHAIN_ID.RULE.IMAGE) .exclude.add(/\.png$/); }, rspack(config, { addRules }) { addRules([ { test: /\.png$/, // Add a custom loader to handle png images loader: 'custom-png-loader', }, ]); }, }, }; ``` ## Image format When using image assets, you can choose an appropriate image format according to the pros and cons in the table below. | Format | Pros | Cons | Scenarios | | ------ | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | PNG | Lossless compression, no loss of picture details, no distortion, support for translucency | Not suitable for pictures with complex color tables | Suitable for pictures with few colors and well-defined borders, suitable for logos, icons, transparent images and other scenes | | JPG | Rich colors | Lossy compression, which will cause image distortion, does not support transparency | Suitable for pictures with a large number of colors, gradients, and overly complex pictures, suitable for portrait photos, landscapes and other scenes | | WebP | Supports both lossy and lossless compression, supports transparency, and is much smaller than PNG and JPG | iOS compatibility is not good | Pixel images of almost any scene, and the hosting environment that supports WebP, should prefer WebP image format | | SVG | Lossless format, no distortion, supports transparency | Not suitable for complex graphics | Suitable for vector graphics, suitable for icons | --- # Source: https://rsbuild.dev/guide/basic/static-deploy.md # Deploy static site This section explains how to deploy Rsbuild build outputs as a static site. ## Background information Before starting the deployment, you should understand the following: * The CLI commands used for building and previewing outputs. * The directory structure of the build outputs. * The URL prefix of static assets. ### Build commands The build commands provided by Rsbuild are: * [build command](/guide/basic/cli.md#rsbuild-build), used to generate the build outputs for production deployment. * [preview command](/guide/basic/cli.md#rsbuild-preview), used to preview the production build outputs locally. Note that you must first execute the `rsbuild build` command to generate the build outputs. ```json title="package.json" { "scripts": { "build": "rsbuild build", "preview": "rsbuild preview" } } ``` :::tip The preview command is only used for local preview. Do not use it for production servers, as it is not designed for that. ::: ### Output directory Rsbuild's build outputs typically include HTML, JS, CSS, and other assets, and are output to the `dist` directory by default. You can change the name and structure of the dist directory with configuration options. See the [Output Files](/guide/basic/output-files.md) section for more information. ```bash dist ├── static │ ├── image │ ├── css │ └── js └── [name].html ``` ### Asset prefix We can divide the build output into two parts: **HTML files** and **static assets**: * HTML files refer to files with the `.html` suffix in the output directory, which usually need to be deployed on the server. * Static assets are located in the `static` directory of the output folder, which contains assets such as JavaScript, CSS, and images. They can be deployed either on the server or on a CDN. If you deploy static assets to a subdirectory on the server, set [output.assetPrefix](/config/output/asset-prefix.md) as the base path: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; export default defineConfig({ output: { assetPrefix: '/some-base-folder/', }, }); ``` If you prefer to serve static assets from a CDN for better performance instead of alongside the HTML on your server, set [output.assetPrefix](/config/output/asset-prefix.md) to the CDN address so the application can reference the assets correctly. ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; export default defineConfig({ output: { assetPrefix: 'https://cdn.com/path/', }, }); ``` With this configuration, when referencing static assets in HTML, the specified prefix will be automatically added. For example: ```html ``` ## Deployment platforms The following sections describe how to deploy on several common platforms. > Platform names are listed in alphabetical order. ### Cloudflare Pages [Cloudflare Pages](https://developers.cloudflare.com/pages/) is a static site hosting platform provided by Cloudflare. You can follow the [Cloudflare Pages - Git integration guide](https://developers.cloudflare.com/pages/get-started/git-integration/) to integrate with Git and deploy your site to Cloudflare Pages. When configuring, complete the following fields under "Build settings": * **Build command**: fill in the project's build command, typically `npm run build`. * **Build output directory**: fill in the project's output directory, which defaults to `dist`. Then click the **Save and Deploy** button to start the deployment. ### GitHub pages [GitHub Pages](https://pages.github.com/) is a static site hosting service that takes HTML, CSS, and JavaScript files straight from a repository on GitHub. The following are step-by-step instructions for deploying to GitHub Pages. 1. Configure the URL prefix for static assets using [output.assetPrefix](/config/output/asset-prefix.md). ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; export default defineConfig({ output: { // Please replace with the repository name. // For example, "/my-project/" assetPrefix: '//', }, }); ``` 2. Open the "Settings" page of your GitHub repository, click "Pages" in the left menu to access the GitHub Pages configuration page. 3. Select "Source" → "GitHub Actions" and click "create your own" to create a GitHub Action configuration file. 4. Paste the following content into the editor and name the file `github-pages.yml` (you can adjust the content and filename as needed). ```yaml title="github-pages.yml" # Sample workflow for building and deploying a Rsbuild site to GitHub Pages name: Rsbuild Deployment on: # Runs on pushes targeting the default branch push: branches: ['main'] # Allows you to run this workflow manually from the actions tab workflow_dispatch: # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: contents: read pages: write id-token: write # Allow only one concurrent deployment concurrency: group: 'pages' cancel-in-progress: false jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Use Node.js uses: actions/setup-node@v4 with: node-version: 22 # If you use other package managers like yarn or pnpm, # you will need to install them first - name: Install dependencies run: npm i - name: Build run: npm run build - name: Setup Pages uses: actions/configure-pages@v5 - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: path: './dist' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 ``` 5. Commit and wait for GitHub Actions to execute. Once complete, you can visit `https://.github.io//` to view the deployed page. ### Netlify [Netlify Core](https://netlify.com/) is a frontend cloud solution for developers to build and deploy future-proof digital solutions with modern, composable tooling. #### Add new site Netlify provides a detailed guide. You can follow the instructions in [Netlify - Add new site](https://docs.netlify.com/welcome/add-new-site/), configure the basic settings, and start the deployment. You need to configure the following fields: * **Build command**: fill in the project's build command, typically `npm run build`. * **Publish directory**: fill in the project's output directory, which defaults to `dist`. Then click the **Deploy site** button to start the deployment. #### Custom domains If you want to make your sites accessible at custom domain names, you can configure this in Netlify's "Domain management" section. > Detailed guide: [Netlify - Custom domains](https://docs.netlify.com/domains-https/custom-domains/). ### Vercel [Vercel](https://vercel.com/) is a platform for developers that provides the tools, workflows, and infrastructure you need to build and deploy your web apps faster, without the need for additional configuration. #### Add new site Vercel provides a detailed guide. You can follow [Vercel - Projects](https://vercel.com/docs/projects/overview) to create a project in your dashboard, configure the basic settings, and start the deployment. Only the following fields under "Build and Output Settings" need to be configured: * **Output directory**: fill in the project's output directory, which defaults to `dist`. Then click the **Deploy** button to start the deployment. #### Configure domains If you want to make your sites accessible at custom domain names, you can configure this in Vercel's "Domains" section. > Detailed guide: [Vercel - Domains](https://vercel.com/docs/projects/domains). ### Zephyr Cloud [Zephyr Cloud](https://zephyr-cloud.io) is a zero-config deployment platform that integrates directly into your build process and provides global edge distribution for federated applications. #### How to deploy Follow the steps in [zephyr-rsbuild-plugin](https://www.npmjs.com/package/zephyr-rsbuild-plugin). During the build process, your application will be automatically deployed and you'll receive a deployment URL. Zephyr Cloud handles asset optimization, global CDN distribution, module federation setup, and provides automatic rollback capabilities. Start for free today at [zephyr-cloud.io](https://zephyr-cloud.io). --- # Source: https://rsbuild.dev/config/server/strict-port.md # server.strictPort * **Type:** `boolean` * **Default:** `false` When a port is occupied, Rsbuild will automatically increment the port number until an available port is found. Set `strictPort` to `true` and Rsbuild will throw an exception when the port is occupied. ## Example ### Basic usage Enable strict port mode to ensure the dev server fails if the specified port is occupied: ```ts title="rsbuild.config.ts" export default { server: { strictPort: true, }, }; ``` ### Use with specific port When you need to ensure your application runs on a specific port: ```ts title="rsbuild.config.ts" export default { server: { port: 3333, strictPort: true, }, }; ``` With this configuration, if port 3333 is already in use, Rsbuild will throw an error instead of automatically using port 3334. --- # Source: https://rsbuild.dev/config/tools/style-loader.md # tools.styleLoader * **Type:** `Object | Function` * **Default:** `{}` The config of [style-loader](https://github.com/webpack/style-loader) can be set through `tools.styleLoader`. It is worth noting that Rsbuild does not enable `style-loader` by default. You can use [output.injectStyles](/config/output/inject-styles.md) config to enable it. ## Object type When `tools.styleLoader` is an object, it will be merged with the default configuration using `Object.assign`. ```ts title="rsbuild.config.ts" export default { tools: { styleLoader: { insert: 'head', }, }, }; ``` ## Function type When `tools.styleLoader` is a function, the default options will be passed in as the first parameter. You can directly modify this object or return a new object as the final options to be used. For example: ```ts title="rsbuild.config.ts" export default { tools: { styleLoader: (config) => { config.insert = 'head'; return config; }, }, }; ``` --- # Source: https://rsbuild.dev/guide/framework/svelte.md # Svelte In this document, you will learn how to build a Svelte application using Rsbuild. ## Create a Svelte application Use [create-rsbuild](/guide/start/quick-start.md#create-an-rsbuild-application) to create a Svelte application with Rsbuild. Run the following command: import { PackageManagerTabs } from '@theme'; Then select `Svelte` when prompted to "Select framework". ## Use Svelte in an existing project To compile Svelte components (`.svelte` files), you need to register the Rsbuild [Svelte plugin](/plugins/list/plugin-svelte.md). The plugin will automatically add the necessary configuration for Svelte builds. For example, register in `rsbuild.config.ts`: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; import { pluginSvelte } from '@rsbuild/plugin-svelte'; export default defineConfig({ plugins: [pluginSvelte()], }); ``` --- # Source: https://rsbuild.dev/config/tools/swc.md # Source: https://rsbuild.dev/guide/configuration/swc.md # Configure SWC [SWC](https://github.com/swc-project/swc) (Speedy Web Compiler) is a transformer and minimizer for JavaScript and TypeScript based on Rust. SWC provides similar functionality to Babel and Terser, and it is 20x faster than Babel on a single thread and 70x faster on four cores. Rsbuild enables the following SWC features by default: * Transform JavaScript and TypeScript code using Rspack's [builtin:swc-loader](https://rspack.rs/guide/features/builtin-swc-loader), which is the Rust version of [swc-loader](https://github.com/swc-project/pkgs/tree/main/packages/swc-loader). * Minify JavaScript code using Rspack's [SwcJsMinimizerRspackPlugin](https://rspack.rs/plugins/rspack/swc-js-minimizer-rspack-plugin). ## Loader options The options for `builtin:swc-loader` are the same as those for the JS version of `swc-loader`. Rsbuild exposes some options to configure `builtin:swc-loader`: * [tools.swc](/config/tools/swc.md):to configure the options for `builtin:swc-loader`. * [source.include](/config/source/include.md):to specify files that need to be compiled by SWC. * [source.exclude](/config/source/exclude.md):to exclude files that do not need to be compiled by SWC. Here are some examples: ### Register SWC plugin `tools.swc` can be used to register SWC's Wasm plugins, for example, registering [@swc/plugin-styled-components](https://npmjs.com/package/@swc/plugin-styled-components): ```js export default { tools: { swc: { jsc: { experimental: { plugins: [['@swc/plugin-styled-components', {}]], }, }, }, }, }; ``` > You can check out the [awesome-swc](https://github.com/swc-contrib/awesome-swc) repository to see the SWC plugins available in the community. ### SWC plugin version Please note that the SWC plugin is still an experimental feature, and the SWC Wasm plugin is currently not backward compatible. The version of the SWC plugin is closely tied to the version of `swc_core` that Rspack depends on. This means that you must choose an SWC plugin that matches the current version of `swc_core` to ensure that it works properly. If the version of the SWC plugin you are using does not match the version of `swc_core` that Rspack depends on, Rspack will throw an error during the build process. Please refer to [Rspack FAQ - SWC Plugin Version Unmatched](https://rspack.rs/errors/swc-plugin-version) for more information. ### Enable Emotion support Example of enabling the Emotion support using the `builtin:swc-loader`: ```js export default { tools: { swc: { jsc: { experimental: { plugins: [['@swc/plugin-emotion', {}]], }, }, }, }, }; ``` For more options, please refer to [@swc/plugin-emotion](https://npmjs.com/package/@swc/plugin-emotion). ### Enable Relay support Example of enabling the Relay support using the `builtin:swc-loader`: ```js export default { tools: { swc: { jsc: { experimental: { plugins: [['@swc/plugin-relay', {}]], }, }, }, }, }; ``` For more options, please refer to [@swc/plugin-relay](https://npmjs.com/package/@swc/plugin-relay). ## Minimizer options Rsbuild provides the [output.minify.js](/config/output/minify.md) option to configure the SwcJsMinimizerRspackPlugin. Here are some examples: ### Exclude files You can exclude certain files from being minified using the `exclude` option: ```ts export default { output: { minify: { jsOptions: { exclude: /foo\/bar/, }, }, }, }; ``` ## Switching minifier See [output.minify - Switching minifier](/config/output/minify.md#switching-minifier) to learn how to switch to other JavaScript minifier. --- # Source: https://rsbuild.dev/guide/styling/tailwindcss-v3.md # Tailwind CSS v3 [Tailwind CSS](https://v3.tailwindcss.com/) is a CSS framework and design system based on utility classes, which can quickly add common styles to components and supports flexible extension of theme styles. You can integrate Tailwind CSS in Rsbuild via PostCSS plugins. ## Installing Tailwind CSS Rsbuild has built-in support for PostCSS, you can install `tailwindcss` package to integrate Tailwind CSS: import { PackageManagerTabs } from '@theme'; ## Configuring PostCSS You can register the `tailwindcss` PostCSS plugin through [postcss.config.cjs](https://npmjs.com/package/postcss-loader#config) or [tools.postcss](/config/tools/postcss.md). ```js title="postcss.config.cjs" module.exports = { plugins: { tailwindcss: {}, }, }; ``` ## Configuring Tailwind CSS Create a `tailwind.config.js` file in the root directory of your project and add the following content: ```js title="tailwind.config.js" /** @type {import('tailwindcss').Config} */ module.exports = { content: ['./src/**/*.{html,js,ts,jsx,tsx}'], theme: { extend: {}, }, plugins: [], }; ``` :::tip The above configuration is for reference only and can be modified to suit the needs of your project. For example, non-TypeScript projects do not need to include ts and tsx files. ::: Note that the `content` option should include the paths to all source files that contain Tailwind class names. For details, see [tailwindcss - Content Configuration](https://v3.tailwindcss.com/docs/content-configuration). ```js title="tailwind.config.js" /** @type {import('tailwindcss').Config} */ module.exports = { content: [ './src/**/*.{html,js,ts,jsx,tsx}', '../../lib1/src/**/*.{js,ts,jsx,tsx}', ], theme: { extend: {}, }, plugins: [], }; ``` ### Other configuration methods * You can directly pass the Tailwind CSS configuration to `postcss.config.cjs`: ```js title="postcss.config.cjs" module.exports = { plugins: { tailwindcss: { content: ['./src/**/*.{html,js,ts,jsx,tsx}'], // ...other options }, }, }; ``` * You can also set the Tailwind CSS configuration through [tools.postcss](/config/tools/postcss.md): ```js title="rsbuild.config.js" import tailwindcss from 'tailwindcss'; export default { tools: { postcss: { postcssOptions: { plugins: [ tailwindcss({ content: ['./src/**/*.{html,js,ts,jsx,tsx}'], // ...other options }), ], }, }, }, }; ``` But we recommend placing the Tailwind CSS configuration in `tailwind.config.*` because other methods may cause the Tailwind CSS build performance to degrade, refer to [tailwindcss/issues/14229](https://github.com/tailwindlabs/tailwindcss/issues/14229). ## Importing CSS Add the `@tailwind` directives in your CSS entry file: ```css title="main.css" @tailwind base; @tailwind components; @tailwind utilities; ``` Depending on your needs, you can selectively import the CSS styles provided by Tailwind CSS. Please refer to the [@tailwind documentation](https://v3.tailwindcss.com/docs/functions-and-directives#tailwind) for detailed usage of the `@tailwind` directives. ## Done You have now completed all the steps to integrate Tailwind CSS in Rsbuild! You can use Tailwind's utility classes in any component or HTML, such as: ```html

Hello world!

``` For more usage details, refer to the [Tailwind CSS documentation](https://v3.tailwindcss.com/). ## VS Code extension Tailwind CSS provides a [Tailwind CSS IntelliSense](https://github.com/tailwindlabs/tailwindcss-intellisense) plugin for VS Code to automatically complete Tailwind CSS class names, CSS functions, and directives. You can install this plugin in VS Code to enable the autocompletion feature. ## Optimize build performance When using Tailwind CSS, if the `content` field in `tailwind.config.js` is not correctly configured, this can lead to poor build performance and HMR performance. This is because Tailwind CSS internally matches files based on the glob defined in `content`. The more files it matches, the greater the performance overhead. Therefore, we recommend that you specify the paths to be scanned accurately to avoid unnecessary performance overhead. For example, only include HTML or JS files in the project source code that actually contain Tailwind class names, and avoid including irrelevant files or directories, especially the `node_modules` directory. Here is a bad example of scanning the `node_modules`: ```js title="tailwind.config.js" /** @type {import('tailwindcss').Config} */ module.exports = { content: [ './src/**/*.{html,js,ts,jsx,tsx}', // Scanning a large number of files, leading to performance degradation './node_modules/**/*.js', ], }; ``` Sometimes, you may accidentally scan the `node_modules` directory, for example, when scanning files in a monorepo: ```js title="tailwind.config.js" module.exports = { content: [ './src/**/*.{html,js,ts,jsx,tsx}', // Incorrectly includes the `packages/ui/node_modules` directory // Should be '../../packages/ui/src/**/*.{html,js,ts,jsx,tsx}' '../../packages/ui/**/*.{html,js,ts,jsx,tsx}', ], }; ``` ## Optimize CSS size To optimize the size of Tailwind CSS styles, you can try [rsbuild-plugin-tailwindcss](https://github.com/rstackjs/rsbuild-plugin-tailwindcss). This plugin reads the module graph information of Rspack, automatically sets the accurate `content` configuration to generate minimal Tailwind CSS styles. ```ts title="rsbuild.config.ts" import { pluginTailwindCSS } from 'rsbuild-plugin-tailwindcss'; export default { plugins: [pluginTailwindCSS()], }; ``` > See [rsbuild-plugin-tailwindcss](https://github.com/rstackjs/rsbuild-plugin-tailwindcss) for more information. --- # Source: https://rsbuild.dev/guide/styling/tailwindcss.md # Tailwind CSS v4 [Tailwind CSS](https://tailwindcss.com/) is a CSS framework and design system based on utility classes, which can quickly add common styles to components and supports flexible extension of theme styles. You can integrate Tailwind CSS in Rsbuild via PostCSS plugins. ## Choosing Tailwind CSS version This document introduces the integration of Tailwind CSS v4. Please note that Tailwind CSS v4 uses many modern CSS features, such as [Cascade Layers](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Cascade_layers), if your target browser does not support these features, please use Tailwind CSS v3 first, see [Using Tailwind CSS v3](/guide/styling/tailwindcss-v3.md) for more details. More information can be found in [Tailwind CSS - Compatibility](https://tailwindcss.com/docs/compatibility). ## Installing Tailwind CSS Rsbuild has built-in support for PostCSS, you can install `tailwindcss` and `@tailwindcss/postcss` packages to integrate Tailwind CSS: import { PackageManagerTabs } from '@theme'; ## Configuring PostCSS You can register the Tailwind CSS PostCSS plugin through [postcss.config.cjs](https://npmjs.com/package/postcss-loader#config) or [tools.postcss](/config/tools/postcss.md). ```js title="postcss.config.mjs" export default { plugins: { '@tailwindcss/postcss': {}, }, }; ``` ## Importing CSS Add an `@import` to your CSS entry file that imports Tailwind CSS. ```css title="src/index.css" @import 'tailwindcss'; ``` :::tip Tailwind CSS v4 cannot be used with CSS preprocessors like Sass, Less, or Stylus. You need to place the `@tailwind` directive at the beginning of your `.css` file, see [Tailwind CSS - Compatibility](https://tailwindcss.com/docs/compatibility#sass-less-and-stylus) for more details. ::: ## Done You have now completed all the steps to integrate Tailwind CSS in Rsbuild! You can use Tailwind's utility classes in any component or HTML, such as: ```html

Hello world!

``` For more usage details, refer to the [Tailwind CSS documentation](https://tailwindcss.com/). ## VS Code extension Tailwind CSS provides a [Tailwind CSS IntelliSense](https://github.com/tailwindlabs/tailwindcss-intellisense) plugin for VS Code to automatically complete Tailwind CSS class names, CSS functions, and directives. You can install this plugin in VS Code to enable the autocompletion feature. --- # Source: https://rsbuild.dev/config/output/target.md # output.target * **Type:** ```ts type RsbuildTarget = 'web' | 'node' | 'web-worker'; ``` * **Default:** `'web'` * **Version:** `>= 1.0.0` Sets the build target for Rsbuild. Rsbuild supports multiple build targets for running in different environments. After setting the target type, Rsbuild's default configuration will change accordingly. ## Default target The target is `'web'` by default, building outputs for browsers. Rsbuild reads the [Browserslist config](https://github.com/browserslist/browserslist) in the project to determine the range of supported browsers. ## Optional values In addition to `'web'`, `target` can also be set to the following values: * `'node'`: Build for Node.js environment, usually used in SSR or other scenarios. * `'web-worker'`: Build for Web Workers environment. For example, to build for the Node.js environment: ```ts title="rsbuild.config.ts" export default { output: { target: 'node', }, }; ``` ## Parallel builds You can use [environments](/config/environments.md) to build multiple targets in parallel. To build `web` and `node` outputs simultaneously, use [environments](/config/environments.md): ```ts title="rsbuild.config.ts" export default { environments: { web: { output: { target: 'web', }, }, node: { output: { target: 'node', }, }, }, }; ``` ## Node target Refers to the build target for running in the Node.js environment, usually used in scenarios such as SSR. When `target` is set to `'node'`, Rsbuild will: * Set Rspack's [target](https://rspack.rs/config/target) to `'node'`. * No HTML files will be generated, and HTML-related logic will not be executed, since HTML is not required in the Node.js environment. * The default code split strategy will be disabled, but dynamic import can still work. * Disable HMR. * Set the default value of Browserslist to `['node >= 16']`. * Set the default value of [output.emitCss](/config/output/emit-css.md) to `false`. This means CSS code will not be extracted to separate files, but CSS Modules id information will be included in the bundle. ### Node addons When `target` is set to `'node'`, Rsbuild allows you to import Node.js [Addons](https://nodejs.org/api/addons.html) in JavaScript files. For example: ```js title="src/index.js" import addon from './addon.node'; addon.doSomething(); ``` The referenced addons file will be output to the `dist` directory: ``` dist/index.js dist/addon.node ``` ## Web Workers target Refers to the build target for running in the [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) environment. When `target` is set to `'web-worker'`, Rsbuild will: * Set Rspack's [target](https://rspack.rs/config/target) to `'webworker'`. * No HTML files will be generated, and HTML-related logic will not be executed, since HTML is not required in the Web Worker environment. * CSS code will not be bundled or extracted, but CSS Modules id information will be included in the bundle (the default value of [output.emitCss](/config/output/emit-css.md) is `false`). * The default code split strategy will be disabled, and **dynamic import cannot work**, because Web Workers only run a single JavaScript file. * Set the default value of [output.emitCss](/config/output/emit-css.md) to `false`. This means CSS code will not be extracted to separate files, but CSS Modules id information will be included in the bundle. * Disable HMR. For more information, see [Using Web Workers](/guide/basic/web-workers.md). ## Other targets [Rspack](https://rspack.rs/config/target) supports other target types, such as `electron-main` and `electron-renderer`. Rsbuild currently does not support these targets. You can configure these targets using [tools.rspack](/config/tools/rspack.md). For example, setting the `target` to `'electron-main'` will override the default `'web'` set by Rsbuild. ```ts title="rsbuild.config.ts" export default { tools: { rspack: { target: 'electron-main', }, }, }; ``` --- # Source: https://rsbuild.dev/config/html/template-parameters.md # html.templateParameters * **Type:** `Record | Function` * **Default:** ```ts type DefaultParameters = { mountId: string; // the value of `html.mountId` config entryName: string; // entry name assetPrefix: string; // the value of dev.assetPrefix or output.assetPrefix configs compilation: Compilation; // Compilation object of Rspack rspackConfig: Rspack.Configuration; // Rspack config object // generated by html-rspack-plugin htmlPlugin: { tags: { headTags: HtmlTagObject[]; bodyTags: HtmlTagObject[]; }; files: { publicPath: string; js: string[]; css: string[]; favicon?: string; }; }; }; ``` Define the parameters in the HTML template, see [HTML Template - Template Parameters](/guide/basic/html-template.md#template-parameters) for detailed usage. ## Object usage If the value of `templateParameters` is an object, it will be merged with the default parameters using `Object.assign`. For example, if you need to use the `foo` parameter in an HTML template, you can add the following settings: ```ts title="rsbuild.config.ts" export default { html: { templateParameters: { foo: 'bar', }, }, }; ``` Then, you can read the parameter in the HTML template using `<%= foo %>`: ```html ``` The compiled HTML code will be: ```html ``` ## Function usage * **Type:** ```ts type TemplateParametersFunction = ( defaultValue: Record, utils: { entryName: string }, ) => Record | void; ``` When `html.templateParameters` is of type Function, the function receives two parameters: * `value`: Default `templateParameters` configuration of Rsbuild. * `utils`: An object containing the `entryName` field, corresponding to the name of the current entry. In the context of a multi-page application (MPA), you can set different `templateParameters` based on the entry name: ```ts title="rsbuild.config.ts" export default { html: { templateParameters(defaultValue, { entryName }) { const params = { foo: { ...defaultValue, type: 'Foo', }, bar: { ...defaultValue, type: 'Bar', hello: 'world', }, }; return params[entryName] || defaultValue; }, }, }; ``` --- # Source: https://rsbuild.dev/guide/advanced/testing.md # Testing Rsbuild doesn't include built-in testing frameworks, but integrates seamlessly with popular testing tools. This guide shows how to add [unit testing](#unit-testing) and [end-to-end testing](#end-to-end-testing) to Rsbuild applications. ## Unit testing Unit tests verify individual components and functions in isolation. Rsbuild can work with testing frameworks like [Rstest](https://rstest.rs), [Vitest](https://vitest.dev/), [Jest](https://jestjs.io/), and others. The following example uses Rstest to show how to add unit tests to an Rsbuild application. ### Rstest [Rstest](https://rstest.rs/) is a testing framework built on Rsbuild that provides first-class support for Rsbuild applications. It offers Jest-compatible APIs while natively supporting modern features like TypeScript and ESM. #### Installing import { PackageManagerTabs } from '@theme'; #### Configuring scripts Add test scripts to your `package.json`: ```json { "scripts": { "test": "rstest", "test:watch": "rstest -w" } } ``` #### Writing tests Create test files, for example: ```ts title="src/utils.ts" export function add(a: number, b: number) { return a + b; } ``` ```ts title="src/utils.test.ts" import { expect, test } from '@rstest/core'; import { add } from './utils'; test('should add two numbers correctly', () => { expect(add(1, 2)).toBe(3); expect(add(-1, 1)).toBe(0); }); ``` #### Running tests ```bash # Run tests npm run test # Run and watch npm run test:watch ``` These are the basic steps for using Rstest. Check the [Rstest documentation](https://rstest.rs/guide/start/) for more usage details. ### Examples Refer to the following examples for more usage patterns: * [react-rstest](https://github.com/rstackjs/rstack-examples/tree/main/rsbuild/react-rstest): Using Rstest and [React Testing Library](https://github.com/testing-library/react-testing-library) to test React components. * [react-jest](https://github.com/rstackjs/rstack-examples/tree/main/rsbuild/react-jest): Using Jest and [React Testing Library](https://github.com/testing-library/react-testing-library) to test React components. ## End-to-end testing End-to-end testing validates complete user workflows, ensuring your application functions correctly in real browser environments. For E2E testing, we recommend Playwright, a modern end-to-end testing framework. See the [Playwright documentation](https://playwright.dev/docs/intro) for details. --- # Source: https://rsbuild.dev/config/html/title.md # html.title * **Type:** `string | Function` * **Default:** `'Rsbuild App'` Set the title tag of the HTML page. :::tip If the HTML template used in the current project already includes the `` tag, the `html.title` will not take effect. ::: ## String usage `html.title` can be directly set as a string: ```ts title="rsbuild.config.ts" export default { html: { title: 'Example', }, }; ``` The `title` tag generated in HTML will be: ```html <title>Example ``` ## Function usage * **Type:** ```ts type TitleFunction = ({ value: string; entryName: string }) => string | void; ``` When `html.title` is of type Function, the function receives an object as the argument, and the object's values include: * `value`: the default title configuration of Rsbuild. * `entryName`: the name of the current entry. In the MPA (multi-page application) scenario, you can return different `title` strings based on the entry name, thus generating different `title` tags for each page: ```ts title="rsbuild.config.ts" export default { html: { title({ entryName }) { const titles = { foo: 'Foo Page', bar: 'Bar Page', }; return titles[entryName] || 'Other Page'; }, }, }; ``` ## Unset `` tag When `html.title` is set to an empty string, Rsbuild will not inject the `<title>` tag: ```ts title="rsbuild.config.ts" export default { html: { title: '', }, }; ``` --- # Source: https://rsbuild.dev/config/source/transform-import.md # source.transformImport * **Type:** ```ts type TransformImport = | Array<{ libraryName: string; libraryDirectory?: string; style?: string | boolean; styleLibraryDirectory?: string; camelToDashComponentName?: boolean; transformToDefaultImport?: boolean; customName?: string; customStyleName?: string; }> | Function; ``` * **Default:** `undefined` Transform the import path to modularly import subpaths of third-party packages. The functionality is similar to [babel-plugin-import](https://npmjs.com/package/babel-plugin-import). ## Example ### Import antd on demand When using the [antd](https://github.com/ant-design/ant-design) component library (versions below v5), you can import components on demand with this config: ```ts title="rsbuild.config.ts" export default { source: { transformImport: [ { libraryName: 'antd', libraryDirectory: 'es', style: 'css', }, ], }, }; ``` The source code is: ```js import { Button } from 'antd'; ``` Will be transformed into: ```js import Button from 'antd/es/button'; import 'antd/es/button/style'; ``` ### Import lodash on demand When using lodash, you can automatically refer to the subpath through `transformImport` to reduce bundle size. ```ts title="rsbuild.config.ts" export default { source: { transformImport: [ { libraryName: 'lodash', customName: 'lodash/{{ member }}', }, ], }, }; ``` The source code is: ```js import { get } from 'lodash'; ``` Will be transformed to: ```js import get from 'lodash/get'; ``` Please avoid the following usage, otherwise all of lodash's code will be imported: ```js import _ from 'lodash'; import lodash from 'lodash'; ``` ## Scope `transformImport` is only applicable to modules compiled by Rsbuild. Note that Rsbuild does not compile JavaScript files in the node\_modules by default. This means that the code in the node\_modules directory will not be processed by `transformImport`. If you want to process the code in node\_modules through `transformImport`, please add the relevant modules to the [source.include](/config/source/include.md) config. ```ts title="rsbuild.config.ts" export default { source: { include: [/node_modules[\\/]some-package[\\/]/], }, }; ``` ## Options ### libraryName * **Type:** `string` The original import path that needs to be transformed. ### libraryDirectory * **Type:** `string` * **Default:** `'lib'` Constructs the transformed path by concatenating `${libraryName}/${libraryDirectory}/${member}`, where member is the imported member. Example: ```ts import { Button } from 'foo'; ``` Out: ```ts import Button from 'foo/lib/button'; ``` ### style * **Type:** `boolean` * **Default:** `undefined` Determines whether to import related styles. If it is `true`, the path `${libraryName}/${libraryDirectory}/${member}/style` will be imported. If it is `false` or `undefined`, the style will not be imported. When it is set to `true`: ```ts import { Button } from 'foo'; ``` Out: ```ts import Button from 'foo/lib/button'; import 'foo/lib/button/style'; ``` ### styleLibraryDirectory * **Type:** `string` * **Default:** `undefined` Constructs the import path when importing styles. If this configuration is specified, the `style` configuration option will be ignored. The constructed import path is `${libraryName}/${styleLibraryDirectory}/${member}`. When it is set to `styles`: ```ts import { Button } from 'foo'; ``` Out: ```ts import Button from 'foo/lib/button'; import 'foo/styles/button'; ``` ### camelToDashComponentName * **Type:** `boolean` * **Default:** `true` Whether to convert camelCase imports to kebab-case. Example: ```ts import { ButtonGroup } from 'foo'; ``` Out: ```ts // set to true: import ButtonGroup from 'foo/button-group'; // set to false: import ButtonGroup from 'foo/ButtonGroup'; ``` ### transformToDefaultImport * **Type:** `boolean` * **Default:** `true` Whether to convert import statements to default imports. Example: ```ts import { Button } from 'foo'; ``` Out: ```ts // set to true: import Button from 'foo/button'; // set to false: import { Button } from 'foo/button'; ``` ### customName * **Type:** `string` * **Default:** `undefined` Customize the transformed path. For example, the following config will transform `import { foo } from 'my-lib'` into `import foo from 'my-lib/foo'`. ```ts title="rsbuild.config.ts" export default { source: { transformImport: [ { libraryName: 'my-lib', customName: `my-lib/{{ member }}`, }, ], }, }; ``` In addition, you can also declare the format of the path after transformation, for example setting it to `my-lib/{{ camelCase member }}` to convert member into camel case. The following formats are supported: * `kebabCase`: lowercase letters, words joined by hyphens. For example: `my-variable-name`. * `snakeCase`: lowercase letters, words joined by underscores. For example: `my_variable_name`. * `camelCase`: first letter lowercase, the first letter of each following word uppercase. For example: `myVariableName`. * `upperCase`: uppercase letters, other characters unchanged. For example: `MY-VARIABLE-NAME`. * `lowerCase`: lowercase letters, other characters unchanged. For example: `my-variable-name`. ### customStyleName * **Type:** `string` * **Default:** `undefined` Customize the transformed style path, the usage is consistent with `customName`. ## Function type The `transformImport` can be a function, it will accept the previous value, and you can modify it. ```ts title="rsbuild.config.ts" export default { source: { transformImport: (imports) => { return imports.filter((data) => data.libraryName !== 'antd'); }, }, }; ``` You can also return a new value as the final result in the function, which will replace the previous value. ```ts title="rsbuild.config.ts" export default { source: { transformImport: () => { return [ { libraryName: 'antd', libraryDirectory: 'es', style: 'css', }, ]; }, }, }; ``` --- # Source: https://rsbuild.dev/config/source/tsconfig-path.md # source.tsconfigPath * **Type:** `string` * **Default:** `'tsconfig.json'` Configure a custom tsconfig.json file path to use, can be a relative or absolute path. ## Purpose The `tsconfig.json` configuration file affects the following behaviors of Rsbuild: * The `paths` field configures [Path Aliases](/guide/advanced/alias.md). * Sets the scope and rules for the [@rsbuild/plugin-type-check](https://github.com/rstackjs/rsbuild-plugin-type-check). ## Example The value of `source.tsconfigPath` can be set to a relative or an absolute path. Relative path will be resolved relative to the project root directory. * Relative path example: ```ts title="rsbuild.config.ts" export default { source: { tsconfigPath: './tsconfig.custom.json', }, }; ``` * Absolute path example: ```ts import path from 'node:path'; export default { source: { tsconfigPath: path.join(__dirname, 'tsconfig.custom.json'), }, }; ``` --- # Source: https://rsbuild.dev/api/javascript-api/types.md # Rsbuild types This section describes some of the type definitions provided by the Rsbuild. ## RsbuildInstance The type of Rsbuild instance, corresponding to the return value of the [createRsbuild](/api/javascript-api/core.md#creatersbuild) method. ```ts import type { RsbuildInstance } from '@rsbuild/core'; let rsbuild: RsbuildInstance; ``` ## RsbuildConfig The type of Rsbuild configuration. ```ts import type { RsbuildConfig } from '@rsbuild/core'; const config: RsbuildConfig = { // ... }; ``` You can also import the type definitions of each field in the Rsbuild config: ```ts import type { DevConfig, HtmlConfig, ToolsConfig, SourceConfig, ServerConfig, OutputConfig, SecurityConfig, PerformanceConfig, ModuleFederationConfig, } from '@rsbuild/core'; ``` ## NormalizedConfig The type of Rsbuild configuration after normalization, corresponding to the return value of the [getNormalizedConfig](/plugins/dev/core.md#apigetnormalizedconfig) method. ```ts import type { NormalizedConfig } from '@rsbuild/core'; const config: NormalizedConfig = api.getNormalizedConfig(); ``` You can also import the type definitions of each field in the normalized config: ```ts import type { NormalizedDevConfig, NormalizedHtmlConfig, NormalizedToolsConfig, NormalizedSourceConfig, NormalizedServerConfig, NormalizedOutputConfig, NormalizedSecurityConfig, NormalizedPerformanceConfig, NormalizedModuleFederationConfig, } from '@rsbuild/core'; ``` ## NormalizedEnvironmentConfig The type of Rsbuild environment configuration after normalization, corresponding to the return value of the [`getNormalizedConfig({ environment })`](/plugins/dev/core.md#apigetnormalizedconfig) method. ```ts import type { NormalizedEnvironmentConfig } from '@rsbuild/core'; const config: NormalizedEnvironmentConfig = api.getNormalizedConfig({ environment, }); ``` ## RsbuildContext The type of the [context property](/api/javascript-api/instance.md#rsbuildcontext) in the Rsbuild instance. ```ts import type { RsbuildContext } from '@rsbuild/core'; const context: RsbuildContext = rsbuild.context; ``` ## RsbuildPlugin Defines the structure and behavior of an Rsbuild plugin. Rsbuild plugins provide a standardized way to extend build functionality through lifecycle hooks and configuration modifications. ```ts import type { RsbuildPlugin } from '@rsbuild/core'; const myPlugin: RsbuildPlugin = { name: 'my-plugin', setup() {}, }; ``` ## RsbuildPluginAPI The API interface that Rsbuild exposes to plugins through the `setup` function. It allows plugins to interact with the build process, modify configurations, register hooks, and access context information. ```ts import type { RsbuildPluginAPI } from '@rsbuild/core'; const myPlugin = { name: 'my-plugin', setup(api: RsbuildPluginAPI) {}, }; ``` ## RsbuildTarget The type of build target. ```ts import type { RsbuildTarget } from '@rsbuild/core'; ``` ## CreateRsbuildOptions The param type of [createRsbuild](/api/javascript-api/core.md#creatersbuild) method. ```ts import type { CreateRsbuildOptions } from '@rsbuild/core'; ``` ## InspectConfigOptions The param type of [rsbuild.inspectConfig](/api/javascript-api/instance.md#rsbuildinspectconfig) method. ```ts import type { InspectConfigOptions } from '@rsbuild/core'; ``` ## Rspack Includes all types exported by `@rspack/core`, such as `Rspack.Configuration`. ```ts import type { Rspack } from '@rsbuild/core'; const rspackConfig: Rspack.Configuration = {}; ``` ## Others See [@rsbuild/core - src/index.ts](https://github.com/web-infra-dev/rsbuild/blob/main/packages/core/src/index.ts) for all exported types. --- # Source: https://rsbuild.dev/guide/basic/typescript.md # TypeScript Rsbuild supports TypeScript by default, allowing you to directly use `.ts` and `.tsx` files in your project. ## TypeScript transformation Rsbuild uses [SWC](/guide/configuration/swc.md) by default for transforming TypeScript code to JavaScript, and also supports switching to [Babel](/plugins/list/plugin-babel.md) for transformation. ### Isolated modules Unlike the native TypeScript compiler, tools like SWC and Babel compile each file separately and cannot determine whether an imported name is a type or value. When using TypeScript in Rsbuild, enable the [verbatimModuleSyntax](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax) or [isolatedModules](https://typescriptlang.org/tsconfig/#isolatedModules) option in `tsconfig.json`: * For TypeScript >= 5.0.0, use the `verbatimModuleSyntax` option, which enables the `isolatedModules` option by default: ```json title="tsconfig.json" { "compilerOptions": { "verbatimModuleSyntax": true } } ``` * For TypeScript \< 5.0.0, use the `isolatedModules` option: ```json title="tsconfig.json" { "compilerOptions": { "isolatedModules": true } } ``` The `isolatedModules` option prevents syntax that SWC and Babel cannot compile correctly, such as cross-file type references. It guides you toward correct usage: ```ts // Wrong export { SomeType } from './types'; // Correct export type { SomeType } from './types'; ``` > See [SWC - Migrating from tsc](https://swc.rs/docs/migrating-from-tsc) for more details about the differences between SWC and tsc. ## Preset types `@rsbuild/core` provides preset type definitions, including CSS files, CSS Modules, static assets, `import.meta`, and other types. Create a `src/env.d.ts` file to reference these types: ```ts title="src/env.d.ts" /// <reference types="@rsbuild/core/types" /> ``` > See [types.d.ts](https://github.com/web-infra-dev/rsbuild/blob/main/packages/core/types.d.ts) for the complete preset type definitions that Rsbuild includes. ## Type checking When transpiling TypeScript code using tools like SWC and Babel, type checking isn't performed. ### Type check plugin To enable type checking, you can use the [@rsbuild/plugin-type-check](https://github.com/rstackjs/rsbuild-plugin-type-check) plugin. This plugin runs TypeScript type checking in a separate process and internally integrates [ts-checker-rspack-plugin](https://github.com/rstackjs/ts-checker-rspack-plugin). The plugin supports type checking in both dev and build modes, helping you catch type errors early in development. Refer to [@rsbuild/plugin-type-check](https://github.com/rstackjs/rsbuild-plugin-type-check) for usage instructions. ### Using tsc You can also use [tsc](https://www.typescriptlang.org/docs/handbook/compiler-options.html) directly for type checking by adding a `type-check` step to your `build` script. This approach only performs type checking after the build and doesn't run during dev mode. ```json title="package.json" { "scripts": { "build": "rsbuild build && npm run type-check", "type-check": "tsc --noEmit" }, "devDependencies": { "typescript": "^5.0.0" } } ``` For Vue applications, use [vue-tsc](https://github.com/vuejs/language-tools/tree/master/packages/tsc) instead of `tsc`. It supports Vue SFCs in addition to TypeScript files. ```json title="package.json" { "scripts": { "build": "rsbuild build && npm run type-check", "type-check": "vue-tsc --noEmit" }, "devDependencies": { "typescript": "^5.0.0", "vue-tsc": "^3.0.0" } } ``` ## tsconfig.json Path Rsbuild reads the `tsconfig.json` file from the root directory by default. Use [source.tsconfigPath](/config/source/tsconfig-path.md) to configure a custom tsconfig.json file path. ```ts export default { source: { tsconfigPath: './tsconfig.custom.json', }, }; ``` ## Path extensions When importing another module in a TypeScript module, TypeScript allows using the `.js` file extension: ```ts title="src/index.ts" // The actual referenced module could be `./some-module.ts` or `./some-module.tsx` import { someFn } from './some-module.js'; ``` Rsbuild supports this feature through Rspack's [extensionAlias](https://rspack.rs/config/resolve#resolveextensionalias) configuration. In TypeScript projects, Rsbuild adds the following configuration by default: ```js const rspackConfig = { resolve: { extensionAlias: { '.js': ['.js', '.ts', '.tsx'], '.jsx': ['.jsx', '.tsx'], }, }, }; ``` This means: * You can use the `.js` extension to import `.ts` or `.tsx` files. * You can use the `.jsx` extension to import `.tsx` files. ## Decorators version Rsbuild does not read the `experimentalDecorators` option in `tsconfig.json`, instead, it provides the [decorators.version](/config/source/decorators.md#decoratorsversion) configuration to specify the decorator version. By default, Rsbuild uses the `2022-03` version of the decorators, you can also set it to `legacy` to use the legacy decorators: ```ts title="rsbuild.config.ts" export default { source: { decorators: { version: 'legacy', }, }, }; ``` --- # Source: https://rsbuild.dev/guide/styling/unocss.md # UnoCSS [UnoCSS](https://unocss.dev/) is the instant atomic CSS engine, which is designed to be flexible and extensible. The core is un-opinionated, and all the CSS utilities are provided via presets. You can integrate UnoCSS in Rsbuild via PostCSS plugins. ## Installing UnoCSS You need to install `unocss` and `@unocss/postcss` first. import { PackageManagerTabs } from '@theme'; <PackageManagerTabs command="add unocss @unocss/postcss -D" /> ## Configuring PostCSS You can register the `unocss` PostCSS plugin through [postcss.config.mjs](https://www.npmjs.com/package/postcss-loader#config) or [tools.postcss](/config/tools/postcss.md). ```js title="postcss.config.mjs" import UnoCSS from '@unocss/postcss'; export default { plugins: [UnoCSS()], }; ``` Rsbuild has integrated [autoprefixer](https://github.com/postcss/autoprefixer), so you only need to register the `UnoCSS` plugin. ## Configuring UnoCSS Create a `uno.config.ts` file in the root directory of your project and add the following content: ```js title="uno.config.ts" import { defineConfig, presetUno } from 'unocss'; export default defineConfig({ content: { filesystem: ['./src/**/*.{html,js,ts,jsx,tsx}'], }, presets: [presetUno()], }); ``` :::tip The above configuration is for reference only and can be modified to suit the needs of your project. ::: ## Importing CSS Add the `@unocss` directives in your CSS entry file: ```css title="main.css" @unocss preflights; @unocss default; ``` Depending on your needs, you can selectively import the CSS styles provided by UnoCSS. Please refer to the [unocss documentation](https://unocss.dev/integrations/postcss#usage) for detailed usage of the UnoCSS. ## Done You have now completed all the steps to integrate UnoCSS in Rsbuild! You can use UnoCSS's utility classes in any component or HTML, such as: ```html <h1 class="px-2 items-center justify-between">Hello world!</h1> ``` For more usage details, refer to the [UnoCSS documentation](https://unocss.dev/). ## VS Code extension UnoCSS provides a [VS Code Extension](https://unocss.dev/integrations/vscode) plugin for VS Code to decoration and tooltip for matched utilities. You can install this plugin in VS Code to enable more intelligent features. --- # Source: https://rsbuild.dev/guide/upgrade/upgrade-rsbuild.md # Upgrading Rsbuild This section explains how to upgrade your project's Rsbuild dependencies to the latest version. :::tip * See [Releases](/community/releases/index.md) to learn about Rsbuild's release strategy. * See [npm - @rsbuild/core](https://npmjs.com/package/@rsbuild/core) to view the latest version. ::: ## Using taze We recommend using [Taze](https://github.com/antfu-collective/taze) to upgrade the Rsbuild version. Taze is a CLI tool for updating npm dependencies. ### Usage Run the following command to upgrade all dependencies that include `rsbuild` in their names: ```bash npx taze --include /rsbuild/ -w ``` The result will look similar to: ```bash rsbuild - 3 patch @rsbuild/core dev ~1mo ^1.0.0 → ^1.2.0 @rsbuild/plugin-react dev ~1mo ^1.0.0 → ^1.2.0 @rsbuild/plugin-type-check dev ~1mo ^1.0.0 → ^1.2.0 ℹ changes written to package.json, run npm i to install updates. ``` You can also adjust the `include` pattern to match specific packages. For example, to upgrade only packages under the `@rsbuild` scope: ```bash npx taze --include /@rsbuild/ -w ``` ### Options Here are some examples of using Taze options: * In a monorepo, you can add the `-r` option to upgrade recursively: ```bash npx taze --include /rsbuild/ -w -r ``` * Add `-l` to upgrade locked versions: ```bash npx taze --include /rsbuild/ -w -l ``` * To upgrade to a major version: ```bash npx taze major --include /rsbuild/ -w ``` > For more options, please refer to the [taze documentation](https://github.com/antfu-collective/taze). --- # Source: https://rsbuild.dev/community/releases/v0-1.md *November 22, 2023* # Announcing Rsbuild 0.1 ![](https://assets.rspack.rs/rsbuild/rsbuild-banner-v0-1.png) We are pleased to announce **the release of** **[Rsbuild](https://github.com/web-infra-dev/rsbuild)** **0.1!** Rsbuild is an Rspack-based build tool, designed to be **an enhanced Rspack** **CLI** that is both more user friendly and out-of-the-box. Rsbuild is the ideal solution for those looking to migrate from webpack to Rspack. It significantly reduces configuration by 90% while offering a 10x build speed. ### 🚀 Performance The build performance of Rsbuild is on par with native Rspack. Considering that Rsbuild includes more out-of-the-box features, its performance will be slightly lower than Rspack. This is the time it takes to build 1000 React components: import { BenchmarkGraph } from '@components/Benchmark'; <BenchmarkGraph /> > The data is based on the benchmark built by the Farm team, more info in [build-tools-performance](https://github.com/rstackjs/build-tools-performance). ### 🔥 Features Rsbuild has the following features: * **Easy to Configure**: One of the goals of Rsbuild is to provide out-of-the-box build capabilities for Rspack users, allowing developers to start a web project with zero configuration. In addition, Rsbuild provides semantic build configuration to reduce the learning curve for Rspack configuration. * **Performance Oriented**: Rsbuild integrates high-performance Rust-based tools from the community, including [Rspack](https://github.com/web-infra-dev/rspack), [SWC](https://swc.rs/) and [Lightning CSS](https://lightningcss.dev/), to deliver top-notch build speed and development experience. Compared to webpack-based tools like Create React App and Vue CLI, Rsbuild provides 5 to 10 times faster build performance and lighter dependencies. * **Plugin Ecosystem**: Rsbuild has a lightweight plugin system and includes a range of high-quality official plugins. Furthermore, Rsbuild is compatible with most webpack plugins and all Rspack plugins, allowing users to leverage existing community or in-house plugins in Rsbuild without the need for rewriting code. * **Stable Artifacts**: Rsbuild is designed with a strong focus on the stability of build artifacts. It ensures high consistency between artifacts in the development and production builds, and automatically completes syntax downgrading and polyfill injection. Rsbuild also provides plugins for type checking and artifact syntax validation to prevent quality and compatibility issues in production code. * **Framework Agnostic**: Rsbuild is not coupled with any front-end UI framework. It supports frameworks like React, Vue, Svelte, Solid and Preact through plugins, and plans to support more UI frameworks from the community in the future. ### 💡 Next step Currently, Rsbuild is still evolving rapidly and plans to introduce many more powerful new features. For example, we are developing **Rsdoctor**, a robust build analysis tool that can be used with all Rspack and webpack projects. It will provide a visual user interface to help developers analyze build times, duplicate dependencies, code transformation processes, and more, making it easier to locate and resolve build issues. ![Rsdoctor preview](https://assets.rspack.rs/rsbuild/assets/rsdoctor-preview.jpg) We will be releasing the first working version of Rsdoctor soon. Thereafter, Rsbuild will iterate in sync with Rspack, with plans to release version 1.0 in the first half of 2024. --- # Source: https://rsbuild.dev/community/releases/v0-2.md *December 11, 2023* # Announcing Rsbuild 0.2 ![](https://assets.rspack.rs/rsbuild/rsbuild-banner-v0-2.png) The Rsbuild 0.2 contains some incompatible API changes. Please refer to the current documentation for upgrading. ## Targets We will move the `target` option of `createRsbuild` to rsbuild config, this change allows user to configure `targets` in the rsbuild config file. * before: ```js const rsbuild = await createRsbuild({ target: ['web', 'node'], }); ``` * after: ```js // rsbuild.config.ts export default { output: { targets: ['web', 'node'], }, }; ``` > Only affect JavaScript API. Users using the Rsbuild CLI do not need to change. ## Entry Remove the deprecated `source.entries` config. `source.entries` has been renamed to `source.entry` since Rsbuild 0.1.0, and we will remove the legacy `source.entries` config in Rsbuild v0.2.0. * before: ```js // rsbuild.config.ts export default { source: { entries: {}, }, }; ``` * after: ```js // rsbuild.config.ts export default { source: { entry: {}, }, }; ``` ## Write to disk `dev.writeToDisk` defaults to `false`. Motivation: * Reduce fs overhead and improve dev server performance. * Avoid trigger watcher of UnoCSS and other tools. See [#654](https://github.com/web-infra-dev/rsbuild/issues/654). * Align the default behavior with webpack-dev-middleware and other community dev servers. User can enable writeToDisk manually: ```js export default { dev: { writeToDisk: true, }, }; ``` ## Babel plugin `@rsbuild/plugin-babel` will move all babel-loader options to `babelLoaderOptions`: * before: ```ts pluginBabel({ plugins: [], presets: [], }); ``` * after: ```ts pluginBabel([ babelLoaderOptions: { plugins: [], presets: [], } ]); ``` This change allows us to add more options for `pluginBabel`, such as `include` and `exclude`. ## Source map `output.disableSourceMap` has been renamed to `output.sourceMap`. * before: ```js export default { output: { disableSourceMap: { js: true, css: true, }, }, }; ``` * after: ```js export default { output: { sourceMap: { js: false, css: false, }, }, }; ``` The default value of source map has also been updated to improve build performance. * before: generate JS / CSS source map in development, generate JS source map in production. * after: generate JS source map in development, no source map are generated in production. ## Inject styles Rename `output.disableCssExtract` to `output.injectStyles` to be clearer: * before: ```js export default { output: { disableCssExtract: true, }, }; ``` * after: ```js export default { output: { injectStyles: true, }, }; ``` --- # Source: https://rsbuild.dev/community/releases/v0-3.md *January 10, 2024* # Announcing Rsbuild 0.3 ![](https://assets.rspack.rs/rsbuild/rsbuild-banner-v0-3.png) Rsbuild 0.3 version has upgraded Rspack to 0.5 and now supports Module Federation. In addition, it includes some incompatible API changes. Please refer to the current documentation for upgrading. ## Rspack 0.5 Bump Rspack to v0.5.0, see: [Rspack 0.5 Release Announcement](https://rspack.rs/blog/announcing-0-5) Notable changes: * [Module Federation added to Rspack](https://rspack.rs/blog/module-federation-added-to-rspack) * [Remove deprecated builtins options](https://rspack.rs/blog/announcing-0-5#make-swchelpers-and-react-refresh-as-peerdependencies) ## TOML / YAML plugin The need to import TOML and YAML in JS is not common, so Rsbuild core will no longer support import TOML and YAML by default in v0.3.0. The TOML and YAML plugin will become a independent plugin: * TOML: ```ts // rsbuild.config.ts import { pluginToml } from '@rsbuild/plugin-toml'; export default { plugins: [pluginToml()], }; ``` * YAML: ```ts // rsbuild.config.ts import { pluginYaml } from '@rsbuild/plugin-yaml'; export default { plugins: [pluginYaml()], }; ``` ## JavaScript API Some JavaScript APIs have changed: * The `printURLs` option of `rsbuild.startDevServer` is deprecated, use [server.printUrls](/config/server/print-urls.md) instead. * The `logger` option of `rsbuild.startDevServer` is deprecated, use [logger.override()](/api/javascript-api/core.md#logger) instead. ## Node target * Adjust default browserslist for node target, from `node >= 14` to `node >= 16`. * The default value of `output.distPath.server` is changed from `'bundles'` to `'server'` --- # Source: https://rsbuild.dev/community/releases/v0-4.md *February 06, 2024* # Announcing Rsbuild 0.4 ![](https://assets.rspack.rs/rsbuild/rsbuild-banner-v0-4.png) Rsbuild 0.4 provides built-in support for module federation. It also contains some incompatible API updates. Please refer to the current document for upgrading. ### Module Federation config Rsbuild now provides a built-in [moduleFederation](/config/module-federation/options.md) option, which will make configuring Module Federation in Rsbuild much easier. * **Example:** ```ts title="rsbuild.config.ts" export default defineConfig({ moduleFederation: { options: { // ModuleFederationPluginOptions }, }, }); ``` When you use this option, Rsbuild will automatically set the default `publicPath` and `splitChunks` config, making module federation ready to use out of the box. > See [RFC - Provide first-class support for Module Federation](https://github.com/web-infra-dev/rsbuild/discussions/1461) for details. ### Plugin hook order In Rsbuild plugin, you can now declare the order of hooks using the `order` field: ```ts const myPlugin = () => ({ setup(api) { api.modifyRsbuildConfig({ handler: () => console.log('hello'), order: 'pre', }); }, }); ``` > For more details, see [Plugin Hooks](/plugins/dev/hooks.md). ### Rename disableFilenameHash The `output.disableFilenameHash` config has been renamed to [output.filenameHash](/config/output/filename-hash.md). * Before: ```ts export default { output: { disableFilenameHash: true, }, }; ``` * After: ```ts export default { output: { filenameHash: false, }, }; ``` ## Remove postcss-flexbugs-fixes Rsbuild 0.4 removed the built-in [postcss-flexbugs-fixes](https://github.com/luisrudge/postcss-flexbugs-fixes) plugin. This plugin is used to fix some flex bugs for IE 10 / 11. Considering that modern browsers no longer have these flex issues, we removed this plugin to improve build performance. If your project needs to be compatible with IE 10 / 11 and encounters these flex issues, you can manually add this plugin in Rsbuild: * Install plugin: ```bash npm add postcss-flexbugs-fixes -D ``` * Register plugin in `postcss.config.cjs`: ```js module.exports = { 'postcss-flexbugs-fixes': {}, }; ``` ## Pure React plugin The React plugin has removed default [source.transformImport](/config/source/transform-import.md) config for [antd](https://npmjs.com/package/antd) v4 and [@arco-design/web-react](https://npmjs.com/package/@arco-design/web-react). Configurations related to the UI library should be provided in the UI library-specific plugins, such as `rsbuild-plugin-antd` or `rsbuild-plugin-arco`, and the React plugin will concentrate on providing fundamental abilities for React. * If your project is using `antd` v3 or v4, you can manually add the following config: ```ts title="rsbuild.config.ts" export default { source: { transformImport: [ { libraryName: 'antd', libraryDirectory: 'es', style: 'css', }, ], }, }; ``` * If your project is using `@arco-design/web-react`, you can manually add the following config: ```ts title="rsbuild.config.ts" export default { source: { transformImport: [ { libraryName: '@arco-design/web-react', libraryDirectory: 'es', camelToDashComponentName: false, style: 'css', }, { libraryName: '@arco-design/web-react/icon', libraryDirectory: 'react-icon', camelToDashComponentName: false, }, ], }, }; ``` ## JavaScript API The `loadConfig` method now returns both the contents of the config and the path to the config file: ```js import { loadConfig } from '@rsbuild/core'; // 0.3 const config = await loadConfig(); // 0.4 const { content, filePath } = await loadConfig(); ``` --- # Source: https://rsbuild.dev/community/releases/v0-5.md *March 19, 2024* # Announcing Rsbuild 0.5 ![](https://assets.rspack.rs/rsbuild/rsbuild-banner-v0-5.png) Rsbuild 0.5 is an important milestone. As of this release, most of the Rsbuild API has reached a stable state and we expect to release Rsbuild 1.0 in Q3 2024. Main changes: * ⚡️ Support for [Lightning CSS](https://lightningcss.dev/) to speed up CSS compilation. * 🌟 Support for custom server based on the new JavaScript API. * 🍭 Refactor the SVGR plugin to support more usages. * 📍 Support for custom minify options. ## ⚡️ Supports Lightning CSS Lightning CSS is a high performance CSS parser, transformer and minifier written in Rust. It supports parsing and transforming many modern CSS features into syntax supported by target browsers, and also provides a better compression ratio. Rsbuild provides the Lightning CSS plugin to use Lightning CSS on an opt-in basis, replacing the built-in PostCSS, autoprefixer, and SWC CSS minimizer in Rsbuild. All you need to do is register the Lightning CSS plugin in the Rsbuild configuration to complete the switch: ```ts title="rsbuild.config.ts" import { pluginLightningcss } from '@rsbuild/plugin-lightningcss'; export default { plugins: [pluginLightningcss()], }; ``` In a real large-scale web application, we have integrated the Rsbuild Lightning CSS plugin and used [Rsdoctor](https://rsdoctor.rs/) to analyze the changes in build time: * CSS compilation time was reduced from 8.4s to 0.12s, a 70x improvement. * The overall build time was reduced from 33.1s to 25.4s, a 30% increase. ## 🌟 Support for custom server Rsbuild now supports replacing the dev server with a custom server that reuses Rsbuild's page preview, routing, and module hot update features. This makes it easier to integrate Rsbuild with other Node.js frameworks. For example, you can implement a custom server based on express: ```ts import express from 'express'; import { createRsbuild } from '@rsbuild/core'; async function startCustomServer() { const app = express(); const rsbuild = await createRsbuild({ config: { server: { middlewareMode: true, }, }, }); const { port, middlewares } = await rsbuild.createDevServer(); app.use(middlewares); app.listen(port); } ``` For more details, please refer to [Rsbuild - createDevServer](/api/javascript-api/instance.md#rsbuildcreatedevserver). ## 🍭 Refactoring SVGR plugin In versions prior to 0.5.0, the default usage of the SVGR plugin was the same as create-react-app, allowing SVGs to be used via mixed import: ```js import logoUrl, { ReactComponent as Logo } from './logo.svg'; console.log(logoUrl); // -> string console.log(Logo); // -> React component ``` However, there are two problems with this approach: 1. **Increased bundle size**: Mixed import causes a single SVG module to be compiled into two types of code (even if some exports are not used), which will increase the bundle size. 2. **Slow down compiling**: Mixed import will cause extra compilation overhead. Even if the ReactComponent export is not used in the code, the SVG file will still be compiled by SVGR. And SVGR is based on Babel, which has a high performance overhead. So we have refactored the `@rsbuild/plugin-svgr` plugin to support converting SVGs to React components via the `?react` query. This approach can solve the problems mentioned above, and is more in line with community best practices. ```jsx import logoUrl from './logo.svg'; import Logo from './logo.svg?react'; console.log(logoUrl); // -> string console.log(Logo); // -> React component ``` The SVGR plugin now supports switching between different SVGR usages. If a project needs to use the previous mixed import usage, you can manually enable the [mixedImport](/plugins/list/plugin-svgr.md#mixedimport) option: ```js pluginSvgr({ mixedImport: true, }); ``` ## 📍 Custom minify options The `output.disableMinimize` option has been renamed to [output.minify](/config/output/minify.md), and it allows customizing JS and HTML minification options. ```ts title="rsbuild.config.ts" export default { output: { minify: { jsOptions: { minimizerOptions: { mangle: false, }, }, }, }, }; ``` Projects using `output.disableMinimize` can refer to the example below: ```ts export default { output: { disableMinimize: true, // [!code --] minify: false, // [!code ++] }, }; ``` > See ["allow customize minify options"](https://github.com/web-infra-dev/rsbuild/issues/1681). *** For more information, please refer to: * [Rsbuild 0.5.0 Changelog](https://github.com/web-infra-dev/rsbuild/releases/tag/v0.5.0) * [Rsbuild 0.5.0 Breaking Changes](https://github.com/web-infra-dev/rsbuild/discussions/1732) --- # Source: https://rsbuild.dev/community/releases/v0-6.md *April 10, 2024* # Announcing Rsbuild 0.6 ![](https://assets.rspack.rs/rsbuild/rsbuild-banner-v0-6.png) Rsbuild 0.6 has been released along with Rspack 0.6! Notable changes: * Upgrade to Rspack 0.6 * Error overlay enabled by default * Support for Vue JSX HMR * New transform plugin API * Default port changed to 3000 ## Upgrade to Rspack 0.6 Rsbuild has upgraded the dependent Rspack to version 0.6, and adapted the breaking changes of CSS Modules contained in Rspack 0.6. In the new version, Rspack has enabled the new tree shaking algorithm by default, resulting in a significant improvement in bundle size and artifact stability. Please refer to the [Rspack 0.6 release announcement](https://rspack.rs/blog/announcing-0-6) to learn more. ## Error overlay enabled by default Starting from Rsbuild 0.6, the default value of [dev.client.overlay](/config/dev/client.md) has been adjusted to `true`. This means that when a compilation error occurs, Rsbuild will pop up the error overlay by default to display the error information: ![](https://assets.rspack.rs/rsbuild/assets/rsbuild-error-overlay.png) If you do not need this feature, you can set `dev.client.overlay` to `false` to disable it. ```ts title="rsbuild.config.ts" export default defineConfig({ dev: { client: { overlay: false, }, }, }); ``` ## Support for Vue JSX HMR `@rsbuild/plugin-vue-jsx` now supports JSX HMR. When you modify JSX code in a Vue 3 application, it will automatically trigger hot module replacement and preserve the current page state. This feature is implemented by community contributor [@liyincode](https://github.com/liyincode) ❤️, and released as a standalone package [babel-plugin-vue-jsx-hmr](https://github.com/liyincode/babel-plugin-vue-jsx-hmr), for use in projects outside of Rsbuild. ## New transform API Rsbuild plugin now supports the [transform API](/plugins/dev/core.md#apitransform), which can be thought of as a lightweight implementation of Rspack loader. It provides a simple and easy to use API and automatically calls Rspack loader at the backend to transform the code. In Rsbuild plugins, you can quickly implement code transformation functions using `api.transform`, which can handle the majority of common scenarios without having to learn how to write an Rspack loader. For example, match modules with the `.pug` extension and transform them to JavaScript code: ```ts import pug from 'pug'; const pluginPug = () => ({ name: 'my-pug-plugin', setup(api) { api.transform({ test: /\.pug$/ }, ({ code }) => { const templateCode = pug.compileClient(code, {}); return `${templateCode}; module.exports = template;`; }); }, }); ``` For some complex code transformation scenarios, `api.transform` may not be sufficient. In such situations, you can implement it using the Rspack loader. ## Default port changed to 3000 Rsbuild has changed the default value of [server.port](/config/server/port.md) from `8080` to `3000`. Port 3000 is commonly used for web development, and is also the default port used by tools such as create-react-app. Changing the default port to 3000 can prevent possible port conflicts when using 8080. To use port 8080, set it manually as follows: ```ts title="rsbuild.config.ts" export default defineConfig({ server: { port: 8080, }, }); ``` --- # Source: https://rsbuild.dev/community/releases/v0-7.md *May 28, 2024* # Announcing Rsbuild 0.7 ![](https://assets.rspack.rs/rsbuild/rsbuild-banner-v0-7.png) Rsbuild 0.7 has been released with Rspack 0.7! This is the last minor release before the Rsbuild 1.0. After this, the Rspack team will focus on the development of 1.0 and aim to launch the Rspack / Rsbuild 1.0 alpha version soon. Notable changes in Rsbuild 0.7: * [Support for Storybook](#support-for-storybook) * [Faster Sass Compilation](#faster-sass-compilation) * [Better CSS supports](#better-css-supports) * [Typed CSS Modules](#typed-css-modules) * [ESM/CJS Exports](#esmcjs-exports) * [Breaking Changes](#breaking-changes) ## Support for Storybook Rsbuild now supports Storybook! [storybook-builder-rsbuild](https://github.com/rstackjs/storybook-rsbuild) is a Storybook builder based on Storybook v8 and Rsbuild that allows you to quickly build your components and stories. ![](https://assets.rspack.rs/rsbuild/rsbuild-banner-with-storybook.png) * For projects using Rsbuild, you can now quickly integrate Storybook and reuse your existing Rsbuild config. * For projects using the Storybook webpack builder, you can now upgrade to Rsbuild and **get ~5x faster build performance**. We provide `storybook-react-rsbuild` and `storybook-vue3-rsbuild` to support React and Vue 3. For example, to integrate React: ```js title=".storybook/main.js" import { StorybookConfig } from 'storybook-react-rsbuild'; const config: StorybookConfig = { framework: 'storybook-react-rsbuild', }; export default config; ``` ![](https://assets.rspack.rs/rsbuild/assets/storybook-rsbuild-preview.png) > For more usage, please refer to [storybook-rsbuild repository](https://github.com/rstackjs/storybook-rsbuild). ## Faster Sass compilation In Rsbuild 0.7, **Sass compilation is 3~10 times faster**. The performance improvements are particularly noticeable on large projects. Comparison of build times for Rsbuild 0.6 and 0.7 when compiling Bootstrap's Sass code: ![](https://assets.rspack.rs/rsbuild/assets/sass-embedded-compare.jpeg) This improvement is due to Rsbuild's default use of [sass-embedded](https://npmjs.com/package/sass-embedded), a JavaScript wrapper around the native Dart Sass executable that provides a consistent API and superior performance. Rsbuild has also enabled the latest sass-loader's [modern-compiler](https://github.com/webpack/sass-loader/releases/tag/v14.2.0) API. This can enable Sass's shared resources feature, which allows the same compiler process to be reused when compiling multiple files, improving build performance. ## Better CSS supports Rsbuild now uses [CssExtractRspackPlugin](https://rspack.rs/plugins/rspack/css-extract-rspack-plugin) to extract CSS into separate files, rather than using the [experimental.css](https://rspack.rs/config/experiments#experimentscss) config to do so. This allows Rsbuild to support more CSS features, including: * Support for using `<style module>` in the Vue SFC: ```html title="index.vue" <template> <p :class="$style.red">Red</p> </template> <style module> .red { color: red; } </style> ``` * Support for complex CSS Modules `:global()` syntax ```css title="style.module.css" :local(.parent):global(.child) > ul { color: red; } ``` * Support for more CSS Modules options, such as [cssModules.exportGlobals](/config/output/css-modules.md#cssmodulesexportglobals) * Now you can use [tools.cssExtract](/config/tools/css-extract.md) to configure CssExtractRspackPlugin. ## Typed CSS Modules Rsbuild 0.7 added a new [Typed CSS Modules plugin](https://github.com/rstackjs/rsbuild-plugin-typed-css-modules), which is used to generate type declaration files for CSS Modules in the project. When you use CSS Modules in a TypeScript project, the default type definition is as follows. It can only provide basic type support, and cannot accurately prompt which class names are exported by CSS Modules. ```ts title="src/env.d.ts" declare module '*.module.css' { const classes: { readonly [key: string]: string }; export default classes; } ``` After using the Typed CSS Modules plugin, Rsbuild will generate type declaration files for all CSS Modules in the project, providing accurate type hints. For example, create two files named `src/index.ts` and `src/index.module.css`: ```tsx title="src/index.ts" import styles from './index.module.css'; console.log(styles.pageHeader); ``` ```css title="index.module.css" .page-header { color: black; } ``` After building, Rsbuild will generate a `src/index.module.css.d.ts` type declaration file: ```ts title="src/index.module.css.d.ts" interface CssExports { 'page-header': string; pageHeader: string; } declare const cssExports: CssExports; export default cssExports; ``` Now when you open the `src/index.ts` file, you can see that the `styles` object already has an accurate type. ## ESM/CJS Exports Now, all packages of Rsbuild provide exports in both ES modules and CommonJS formats, and ["type"="module"](https://nodejs.org/api/packages.html#type) has been declared in the package.json. ![](https://assets.rspack.rs/rsbuild/assets/rsbuild-dual-package-example.png) This allows you to use `import` or `require` to use the JavaScript API of Rsbuild: ```js // ES module import { createRsbuild } from '@rsbuild/core'; // CommonJS const { createRsbuild } = require('@rsbuild/core'); ``` ESM/CJS interop is a tricky issue, so we will provide both formats for a long time to make it easier for more users to use. ## Breaking changes ### Upgrade Rspack to 0.7 Rsbuild has upgraded the dependent Rspack to version 0.7 and adapted to the breaking changes included in it. Typically, these breaking changes will not affect you. In the new version, Rspack supports lazy compilation, which can significantly improve the dev startup time for large projects. Please refer to [Announcing Rspack 0.7](https://rspack.rs/blog/announcing-0-7) to learn more. In Rsbuild, you can use [dev.lazyCompilation](/config/dev/lazy-compilation.md) to enable lazy compilation. ### Sass and Less plugins Rsbuild's Sass and Less plugins are now two separate npm packages instead of being built into `@rsbuild/core` as before. This change allows users to enable Sass and Less compilation as needed. For example, projects using CSS solutions such as Tailwind CSS, CSS-in-JS, etc., no longer need to install the dependencies required for Sass and Less, **saving about 7MB of disk space**. * If your project requires compiling `.scss` or `.sass` files, please install and register the [@rsbuild/plugin-sass](/plugins/list/plugin-sass.md) plugin: ```ts title="rsbuild.config.ts" import { pluginSass } from '@rsbuild/plugin-sass'; export default { plugins: [pluginSass()], }; ``` * If your project requires compiling `.less` files, please install and register the [@rsbuild/plugin-less](/plugins/list/plugin-less.md) plugin: ```ts title="rsbuild.config.ts" import { pluginLess } from '@rsbuild/plugin-less'; export default { plugins: [pluginLess()], }; ``` ### dataUriLimit defaults The default value for [output.dataUriLimit](/config/output/data-uri-limit.md) has been changed from `10000 (10 kB)` to `4096 (4 KiB)`. This is because more applications are currently using HTTP 2.0, so splitting assets into separate files would perform better. Meanwhile, inlining assets over 4KiB can make the JS bundle to be too large and not cache friendly. If you prefer the previous defaults, add the following config: ```ts title="rsbuild.config.ts" export default { output: { dataUriLimit: 10000, }, }; ``` --- # Source: https://rsbuild.dev/guide/upgrade/v0-to-v1.md # Upgrading from 0.x to v1 This document lists all breaking changes from Rsbuild 0.7 to 1.0. Use it as a migration reference. > See [Breaking changes in Rsbuild v1.0.0](https://github.com/web-infra-dev/rsbuild/discussions/2508) for details. ## \[Important] Lightning CSS loader Rsbuild now enables [lightningcss-loader](https://rspack.rs/guide/features/builtin-lightningcss-loader) by default to transform CSS files. It replaces `autoprefixer` for adding vendor prefixes and delivers better performance. * `@rsbuild/plugin-lightningcss` is deprecated and no longer needed. * `tools.autoprefixer` config has been removed. Since Lightning CSS has some uncovered edge cases, you can still enable autoprefixer through a postcss config file: ```js title="postcss.config.cjs" module.exports = { plugins: { autoprefixer: {}, }, }; ``` ## \[Important] output.polyfill Rsbuild v1 sets [output.polyfill](/config/output/polyfill.md) to `'off'` by default. This reduces polyfill code and generates smaller bundles. If your application needs polyfills, set `output.polyfill` to `'usage'` or `'entry'`: ```ts title="rsbuild.config.ts" export default { output: { polyfill: 'usage', }, }; ``` ## \[Important] source.decorators Rsbuild now uses `2022-11` decorators version by default. This aligns Rsbuild's default behavior with TypeScript >= 5.0 and esbuild >= 0.21.0. For legacy decorators, add this config: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; export default defineConfig({ source: { decorators: { version: 'legacy', }, }, }); ``` ## \[Important] output.targets :::tip Rsbuild v1 removes the `output.targets` option and target parameters from `source.alias`, `source.entry`, and other configs. Instead, use `environments` for more flexible multi-environment configuration. The `environments` option provides broader coverage and enables differentiated config across multiple environments. For details, see [Multiple-Environment Builds](/guide/advanced/environments.md). ::: The `output.targets` config has been removed. Use [output.target](/config/output/target.md) and [environments](/config/environments.md) instead. * before: ```js export default { output: { targets: ['web', 'node'], }, }; ``` * after: ```js export default { environments: { web: { output: { target: 'web', }, }, node: { output: { target: 'node', }, }, }, }; ``` ## source.alias Removed `target` param for `source.alias` function, use [environments](/config/environments.md) config instead. * before: ```js export default { source: { alias: (alias, { target }) => { if (target === 'node') { alias['@common'] = './src/node/common'; } else if (target === 'web') { alias['@common'] = './src/web/common'; } }, }, output: { targets: ['web', 'node'], }, }; ``` * after: ```js export default { environments: { web: { source: { alias: { '@common': './src/web/common', }, }, output: { target: 'web', }, }, node: { source: { alias: { '@common': './src/node/common', }, }, output: { target: 'node', }, }, }, }; ``` ## source.entry Removed function usage of `source.entry`, use [environments](/config/environments.md) config instead. * before: ```js export default { source: { entry({ target }) { if (target === 'web') { return { index: './src/index.client.js', }; } if (target === 'node') { return { index: './src/index.server.js', }; } }, }, output: { targets: ['web', 'node'], }, }; ``` * after: ```js export default { environments: { web: { source: { entry: { index: './src/index.client.js', }, }, output: { target: 'web', }, }, node: { source: { entry: { index: './src/index.server.js', }, }, output: { target: 'node', }, }, }, }; ``` ## output.overrideBrowserslist `output.overrideBrowserslist` no longer supports `Record<RsbuildTarget, string[]` type, use [environments](/config/environments.md) config instead. * before: ```js export default { output: { overrideBrowserslist: { web: ['iOS >= 9', 'Android >= 4.4'], node: ['node >= 20'], }, }, }; ``` * after: ```js export default defineConfig({ environments: { web: { output: { overrideBrowserslist: ['iOS >= 9', 'Android >= 4.4'], }, }, node: { output: { overrideBrowserslist: ['node >= 20'], }, }, }, }); ``` ## output.emitAssets `output.emitAssets` changed to boolean type, use [environments](/config/environments.md) config instead. * before: ```js export default { output: { targets: ['web', 'node'], emitAssets: ({ target }) => target !== 'node', }, }; ``` * after: ```js export default { environments: { web: { output: { target: 'web', }, }, node: { output: { target: 'node', emitAssets: false, }, }, }, }; ``` ## output.distPath.server Removed `output.distPath.server`, use the [environments](/config/environments.md) config instead. ```js export default { environments: { web: { output: { target: 'web', }, }, node: { output: { target: 'node', distPath: { root: 'dist/server', }, }, }, }, }; ``` ## output.minify.html Rsbuild v1 removed the `output.minify.html` and `output.minify.htmlOptions` options, and no longer minify the HTML files. Previously Rsbuild uses `html-minifier-terser` to minify the HTML files. But the performance of `html-minifier-terser` cannot meet the needs of Rsbuild applications, and in most cases, there is little benefit in compressing HTML. At this stage, Rsbuild will not built-in `html-minifier-terser`, so we provide a standalone [rsbuild-plugin-html-minifier-terser](https://github.com/rstackjs/rsbuild-plugin-html-minifier-terser) to support HTML minification. ```ts title="rsbuild.config.ts" import { pluginHtmlMinifierTerser } from 'rsbuild-plugin-html-minifier-terser'; export default { plugins: [pluginHtmlMinifierTerser()], }; ``` And we plan to use some faster Rust-based HTML minimizer in the future. ## output.charset The default value of [output.charset](/config/output/charset.md) has been changed from `ascii` to `utf8`. To use `ascii`, add the following config: ```ts export default { output: { charset: 'ascii', }, }; ``` ## dev.startUrl `dev.startUrl` has been renamed to [server.open](/config/server/open.md): ```js export default { // [!code --] dev: { startUrl: true, // [!code --] }, // [!code --] // [!code ++] server: { open: true, // [!code ++] }, // [!code ++] }; ``` ## dev.client.port The default value of [dev.client.port](/config/dev/client.md) changed from `<port>` to `''` (use `location.port`). Use the previous value if you want to keep the behavior: ```js export default { dev: { client: { port: '<port>', }, }, }; ``` ## html.appIcon Previously, [html.appIcon](/config/html/app-icon.md) did not support for web app manifests, meaning it was only available on iOS. Now `html.appIcon` supports generating web app manifests, and the type of `html.appIcon` has been changed. * before: ```js export default { html: { appIcon: './src/icon.png', }, }; ``` * after: ```js export default { html: { appIcon: { icons: [{ src: './src/icon.png', size: 180 }], }, }, }; ``` ## Others Rsbuild 1.0 has made some adjustments and optimizations to plugins API and dev server API. Includes: * The `onBeforeBuild` hook supports triggering multiple times in watch mode. * Added `onBeforeEnvironmentCompile` and `onAfterEnvironmentCompile` hooks, which are triggered before/after executing the build of a single environment respectively. * Removed `api.getHtmlPaths` and replaced it with `environment.htmlPaths`. * Removed `api.context.entry` and replaced it with `environment.entry`. * Removed `api.context.targets` and replaced it with `environment.target`. * Removed `rsbuildServer.onHTTPUpgrade` and replaced it with `rsbuildServer.connectWebSocket`. --- # Source: https://rsbuild.dev/community/releases/v1-0.md *September 10, 2024* # Announcing Rsbuild 1.0 ![](https://assets.rspack.rs/rsbuild/assets/rsbuild-1-0-banner.png) We are pleased to announce the release of Rsbuild 1.0! ## Why Rsbuild For a long time, developers using webpack have been bothered by two major issues: **slow build times and configuration complexity**. We have used Rust to rewrite webpack into [Rspack](https://github.com/web-infra-dev/rspack), which addresses the slow build issue. However, to maintain compatibility with the webpack ecosystem, Rspack retains webpack's configuration and API, which means it still has some complexity and a learning curve. ### Evolution of the ecosystem In the early days, there were some excellent tools within the webpack ecosystem, such as Create React App (CRA) and Vue CLI. These tools provided best practices for building React or Vue applications, while hiding the complex webpack configuration. As a result, many React and Vue users used these tools to build applications without having to configure webpack from scratch. As the ecosystem evolved, full-stack web frameworks such as Next.js, Nuxt, and Remix became popular; Vite was introduced as a lightweight build tool and also gained popularity. However, CRA and Vue CLI gradually stopped being maintained. When we look at the npm download numbers for webpack, CRA, and Vue CLI, we find that a large number of projects are still using these tools. For example, webpack has about 25 million weekly downloads, and CRA has nearly 3 million weekly downloads. Many of these projects are CSR applications that do not require the SSR features of full-stack frameworks. Vite seems like a good choice, but after using Vite in our ByteDance projects, we found that migrating from webpack to Vite comes with high costs and introduces new problems, such as dev and build inconsistency, and slow page refreshes in large applications during development. For the webpack ecosystem, we discovered a sad fact: **the webpack ecosystem lacks a build tool that is easy to use and well maintained**. The tool should be as user-friendly as CRA and Vue CLI, fully meet the needs of CSR application development, and have features such as fast startup and plugin support similar to Vite. ### The birth of Rsbuild During the development of Rspack, we became aware of the above problems and decided to create a modern build tool based on Rspack called **Rsbuild**. ![](https://assets.rspack.rs/rsbuild/assets/rsbuild-1-0-build-tools.png) Rsbuild is built on top of Rspack. We designed Rsbuild with an easy-to-use, TypeScript-friendly API and a set of carefully designed configurations to fully leverage the Rspack's build performance while reducing configuration complexity and high up-front costs. When developing Rsbuild, we learned best practices from the best tools in the community and focused on two usage scenarios: * As a lightweight build tool: Helps developers quickly set up web applications with out-of-the-box support for CSR applications. * As a shared infrastructure: Provides [JavaScript API](/api/start/index.md) and [Plugin API](/plugins/dev/index.md) for higher-level tools and frameworks, allowing developers to easily build their tools or frameworks on top of Rsbuild. ## Performance **Rsbuild is currently the fastest build tool in the webpack and Rspack ecosystem**. Here is a comparison between Rsbuild, Create React App, Vite, and Rspack CLI: | Metric | Create React App | Vite (with SWC) | Rspack CLI | Rsbuild | Rsbuild vs CRA | | ------------------------------- | ---------------- | --------------- | ---------- | ------- | ----------------- | | dev startup time (1000 modules) | 5.47s | 1.29s | 0.66s | 0.39s | **14x faster** | | build time (1000 modules) | 5.69s | 1.39s | 0.51s | 0.27s | **20x faster** | | npm dependencies count | 1241 | 15 | 283 | 14 | **99% reduction** | | npm install size | 146.6MB | 56.3MB | 75.1MB | 59.1MB | **60% reduction** | Compared to the [Rspack CLI](https://npmjs.com/package/@rspack/cli), Rsbuild provides a richer set of features while demonstrating superior performance. This is because Rspack CLI needs to maintain compatibility with the [webpack-cli](https://npmjs.com/package/webpack-cli). It relies on the `webpack-dev-server` and provides the same default behavior as webpack, which has some performance limitations. Rsbuild, on the other hand, is designed for modern web development. We have reimplemented a lighter CLI, dev server, and build process for Rsbuild, resulting in faster startup speeds and fewer npm dependencies. > See the [Rsbuild Introduction](/guide/start/index.md) for more comparisons between Rsbuild, webpack, Vue CLI, and Vite. ## Who is using In the [Rspack 1.0 Announcement](https://rspack.rs/blog/announcing-1-0), we introduced that Rspack is growing rapidly, with almost half of Rspack users using Rsbuild and giving us lots of positive feedback. At ByteDance, we use Rsbuild as the cornerstone of our internal web frameworks to support thousands of web projects. These projects cover diverse use cases, including desktop web applications, mobile web applications, cross-platform web applications, documentation sites, and more. For the community, we have open-sourced a high-performance toolchain based on Rsbuild, including the static site generator [Rspress](https://github.com/web-infra-dev/rspress), the library development tool [Rslib](https://github.com/web-infra-dev/rslib), the full-stack React framework [Modern.js](https://github.com/web-infra-dev/modern.js), and the [Storybook Rsbuild](https://github.com/rstackjs/storybook-rsbuild). The extensibility of Rsbuild allows these tools to flexibly integrate with Rsbuild and share its plugin ecosystem. After releasing Rsbuild 1.0, we also plan to collaborate with some excellent teams like [Remix](https://github.com/remix-run/remix), to bring Rsbuild to more web frameworks. ## Plugin ecosystem The Rsbuild plugin ecosystem is constantly evolving. There are currently over 50 [Rsbuild plugins](https://github.com/rstackjs/awesome-rstack?tab=readme-ov-file#rsbuild-plugins) available in the community. We provide several advanced features through plugins to support the development of production-grade applications, such as [type checking](https://github.com/rstackjs/rsbuild-plugin-type-check), [compatibility checking](https://github.com/rstackjs/rsbuild-plugin-check-syntax), and [static assets retry](https://github.com/rstackjs/rsbuild-plugin-assets-retry). Thanks to Rspack's compatibility with webpack, Rsbuild also supports most webpack plugins. Compared to webpack or Rspack, the Rsbuild plugin API is more straightforward and beginner-friendly, allowing developers to easily create plugins to meet their specific needs. For example, let us implement a plugin that outputs a file to the dist directory. The implementation comparison between Rspack and Rsbuild is as follows: ![](https://assets.rspack.rs/rsbuild/assets/rsbuild-1-0-plugin-compare.png) As shown, the API style of the Rsbuild plugin is similar to esbuild, it can be defined by a function. The plugin hooks have been simplified to avoid verbose APIs, making plugin development more intuitive. ## How to use 1.0 * If you haven't used Rsbuild before, you can experience it through the [CodeSandbox example](https://codesandbox.io/p/github/rstackjs/rsbuild-codesandbox-example) or refer to the [Quick start](/guide/start/quick-start.md) to use Rsbuild. * If you are using Rsbuild 0.7 or earlier, please note that 1.0 includes some breaking changes. You can refer to the [Migrating from 0.x](/guide/upgrade/v0-to-v1.md) document to upgrade. * Rsbuild also provides migration guides for projects that use webpack, CRA, Vue CLI, etc. See [Migrate from Existing Projects](/guide/start/quick-start.md#migrate-from-existing-projects). > Give a star 🌟 to the [Rsbuild GitHub repository](https://github.com/web-infra-dev/rsbuild). ## What's next Rsbuild 1.0 provides several advanced features for the development of enterprise applications and higher-level tools, such as the [multi-environment build API](/guide/advanced/environments.md), [SSR API](/guide/advanced/ssr.md), [plugin API](/plugins/dev/index.md), [Module Federation support](/guide/advanced/module-federation.md), and [library build (Rslib)](https://github.com/web-infra-dev/rslib). We plan to continue to enhance these features to better support the development of the Rsbuild ecosystem. In the next 12 to 18 months, Rsbuild will evolve together with Rspack, adopting Rspack's new features as soon as they become available. These features include persistent caching, faster HMR, and TypeScript-based optimizations. For more details, see [Rspack - What's next](https://rspack.rs/blog/announcing-1-0#whats-next). Finally, a big thank you to all the developers who have contributed to Rsbuild ❤️: ![](https://assets.rspack.rs/rsbuild/assets/rsbuild-1-0-contributors.png) --- # Source: https://rsbuild.dev/guide/migration/vite-plugin.md # Vite plugin This chapter introduces how to migrate a Vite plugin to Rsbuild plugin. ## Existing plugins Before migrating a Vite plugin, it is recommended to check if there is a corresponding plugin in the Rsbuild ecosystem. You can find the plugins through the following pages: * [Rsbuild official plugins](/plugins/list.md) * [Rsbuild community plugins](https://github.com/rstackjs/awesome-rstack?tab=readme-ov-file#rsbuild-plugins) ## Define a plugin Rsbuild plugin is defined in a way similar to Vite, usually a function that accepts plugin options as a parameter and returns a plugin description object. The main difference is that Vite's hooks are defined directly on the plugin description object, while Rsbuild's hooks are accessed and called through the [api object](/plugins/dev/core.md). This allows you to control the timing of plugin API calls more flexibly. * Vite plugin: ```ts title="vitePlugin.ts" const vitePlugin = (options) => ({ name: 'vite-plugin', transform() { // ... }, }); ``` * Rsbuild plugin: ```ts title="rsbuildPlugin.ts" const rsbuildPlugin = (options) => ({ name: 'rsbuild-plugin', setup(api) { api.transform(() => { // ... }); }, }); ``` ## Plugin hooks Rsbuild's plugin API covers most of the Vite and Rollup plugin hooks, for example: | Vite plugin hooks | Rsbuild plugin API | | -------------------- | ---------------------------------------------------------------------------------------------------------------------- | | `resolveId` | [resolve](/plugins/dev/core.md#apiresolve) | | `transform` | [transform](/plugins/dev/core.md#apitransform) | | `config` | [modifyRsbuildConfig](/plugins/dev/hooks.md#modifyrsbuildconfig) | | `configResolved` | [getNormalizedConfig](/plugins/dev/core.md#apigetnormalizedconfig) | | `configEnvironment` | [modifyEnvironmentConfig](/plugins/dev/hooks.md#modifyenvironmentconfig) | | `configureServer` | [onBeforeStartDevServer](/plugins/dev/hooks.md#onbeforestartdevserver) | | `buildStart` | [onBeforeBuild](/plugins/dev/hooks.md#onbeforebuild), [onBeforeStartDevServer](/plugins/dev/hooks.md#onbeforestartdevserver) | | `buildEnd` | [onAfterBuild](/plugins/dev/hooks.md#onafterbuild), [onCloseDevServer](/plugins/dev/hooks.md#onclosedevserver) | | `closeBundle` | [onCloseBuild](/plugins/dev/hooks.md#onclosebuild), [onCloseDevServer](/plugins/dev/hooks.md#onclosedevserver) | | `transformIndexHtml` | [modifyHTML](/plugins/dev/hooks.md#modifyhtml), [modifyHTMLTags](/plugins/dev/hooks.md#modifyhtmltags) | See [Plugin system](/plugins/dev/index.md) for more details. ## `config` hook Rsbuild provides the [modifyRsbuildConfig](/plugins/dev/hooks.md#modifyrsbuildconfig) hook to modify Rsbuild configuration. Since Rsbuild and Vite have different configuration structures, you'll need to adjust your configuration when migrating Vite plugins. For example, you should replace Vite's `define` option with Rsbuild's [source.define](/config/source/define.md) option. * Vite plugin: ```ts title="vitePlugin.ts" const vitePlugin = { name: 'my-plugin', config: (config) => { config.define = { ...config.define, FOO: '"foo"', }; }, }; ``` * Rsbuild plugin: ```ts title="rsbuildPlugin.ts" const rsbuildPlugin = { name: 'my-plugin', setup(api) { api.modifyRsbuildConfig((config) => { config.source ||= {}; config.source.define = { ...config.source.define, FOO: '"foo"', }; }); }, }; ``` :::tip See [Config migration](/guide/migration/vite.md#config-migration) to learn how to migrate Vite configurations to Rsbuild. ::: ## `configEnvironment` hook Rsbuild provides the [modifyEnvironmentConfig](/plugins/dev/hooks.md#modifyenvironmentconfig) hook to modify the configuration of a specific environment. * Vite plugin: ```ts const vitePlugin = { name: 'config-environment', configEnvironment(name, config) { if (name === 'web') { config.resolve.alias = { // ... }; } }, }; ``` * Rsbuild plugin: ```js const rsbuildPlugin = { name: 'config-environment', setup(api) { api.modifyEnvironmentConfig((config, { name }) => { if (name === 'web') { config.resolve.alias = { // ... }; } }); }, }; ``` ## `configResolved` hook Rsbuild provides the [api.getNormalizedConfig](/plugins/dev/core.md#apigetnormalizedconfig) method to get the resolved configuration. This method serves a similar purpose to Vite's `configResolved` hook. * Vite plugin: ```ts title="vitePlugin.ts" const vitePlugin = () => { let config; return { name: 'read-config', configResolved(resolvedConfig) { config = resolvedConfig; }, transform() { console.log(config); // ... }, }; }; ``` * Rsbuild plugin: ```ts title="rsbuildPlugin.ts" const rsbuildPlugin = () => ({ name: 'read-config', setup(api) { api.transform(() => { const config = api.getNormalizedConfig(); console.log(config); // ... }); }, }); ``` ## `transformIndexHtml` hook Vite's `transformIndexHtml` hook corresponds to two hooks in Rsbuild: * [modifyHTML](/plugins/dev/hooks.md#modifyhtml): for modifying HTML content * [modifyHTMLTags](/plugins/dev/hooks.md#modifyhtmltags): for modifying HTML tags Here is an example of replacing the HTML title. * Vite Plugin: ```ts title="vitePlugin.ts" const htmlPlugin = () => { return { name: 'html-plugin', transformIndexHtml(html) { return html.replace( /<title>(.*?)<\/title>/, `<title>Title replaced!`, ); }, }; }; ``` * Rsbuild Plugin: ```ts title="rsbuildPlugin.ts" const rsbuildPlugin = { name: 'html-plugin', setup(api) { api.modifyHTML((html) => { return html.replace( /(.*?)<\/title>/, `<title>Title replaced!`, ); }); }, }; ``` ## `configureServer` hook Rsbuild provides the `onBeforeStartDevServer` hook to replace Vite's `configureServer` hook, which allows you to get the dev server instance and add custom middleware. * Vite plugin: ```ts title="vitePlugin.ts" const vitePlugin = () => ({ name: 'setup-middleware', configureServer(server) { server.middlewares.use((req, res, next) => { // custom handle request... }); }, }); ``` * Rsbuild plugin: ```ts title="rsbuildPlugin.ts" const rsbuildPlugin = { name: 'setup-middleware', setup(api) { api.onBeforeStartDevServer(({ server }) => { server.middlewares.use((req, res, next) => { // custom handle request... }); }); }, }; ``` ## `apply` property Rsbuild plugin provides the same [apply property](/plugins/dev/core.md#conditional-application) as Vite plugins. * Vite plugin: ```ts title="vitePlugin.ts" const vitePlugin = { name: 'vite-plugin', apply: 'build', }; ``` * Rsbuild plugin: ```ts title="rsbuildPlugin.ts" const rsbuildPlugin = { name: 'rsbuild-plugin', apply: 'build', }; ``` --- # Source: https://rsbuild.dev/guide/migration/vite.md # Vite This guide explains how to migrate a Vite project to Rsbuild. ## Installing dependencies First, replace Vite's npm dependencies with Rsbuild's equivalents. import { PackageManagerTabs } from '@theme'; * Remove Vite dependencies: * Install Rsbuild dependencies: ## Updating npm scripts Next, update the npm scripts in your package.json to run Rsbuild CLI commands. ```json title="package.json" { "scripts": { "dev": "vite", // [!code --] "build": "vite build", // [!code --] "preview": "vite preview", // [!code --] "dev": "rsbuild dev", // [!code ++] "build": "rsbuild build", // [!code ++] "preview": "rsbuild preview" // [!code ++] } } ``` ## Create configuration file Create an Rsbuild configuration file named `rsbuild.config.ts` alongside package.json, and add the following content: ```ts title="rsbuild.config.ts" import { defineConfig } from '@rsbuild/core'; export default defineConfig({ plugins: [], }); ``` ## Build entry The default build entry points for Rsbuild and Vite are different. Vite uses `index.html` as the default entry, while Rsbuild uses `src/index.js`. When migrating from Vite to Rsbuild, use Rsbuild's [source.entry](/config/source/entry.md) to set the build entry and [html.template](/config/html/template.md) to set the template. Using a newly created Vite project as an example, first delete the ` ``` Then add the following configuration: ```ts title="rsbuild.config.ts" export default { html: { template: './index.html', }, source: { entry: { index: './src/main.ts', }, }, }; ``` Rsbuild automatically injects the `