--- url: /guide/start/index.md --- # Introduction Rslib is a library development tool that leverages the well-designed configurations and plugins of [Rsbuild](https://rsbuild.dev), empowering library developers to take advantage of the extensive knowledge and ecosystem of webpack and Rspack. Rslib provides a comprehensive set of build features for library development, including: * **Compilation of diverse languages**: TypeScript, JSX, Sass, Less, CSS Modules, Wasm, and more. * **Flexible build modes**: Bundle and bundleless options to meet varying needs. * **Multiple output formats**: ESM, CJS, and UMD for maximum compatibility. * **Declaration file generation**: Including isolated declarations. * **Advanced features**: Module Federation, asset compression, PostCSS, Lightning CSS, and more. ## ✨ Why Rslib During the development of component or utility libraries, developers need to focus not only on implementing project logic, but also on handling tasks that are separate from the code itself, such as building, debugging, documentation, and testing. Although many community tools and solutions can address some of these needs, developers who are not familiar with them often face cumbersome configuration requirements or need to coordinate multiple tools to meet these demands. Based on Rspack and Rsbuild, Rslib offers a comprehensive solution tailored to the diverse requirements of library development, effectively addressing issues such as incomplete tool ecosystems, high costs for module standard compatibility, and insufficient output optimization. Rslib optimizes webpack's limited support for library ESM outputs, reducing redundant runtime code and generating high-quality ESM outputs that are tree-shaking friendly for library consumers. Additionally, Rslib fully leverages the build performance advantages of Rspack and capitalizes the strengths of both the webpack and Rspack ecosystems to robustly support features such as Module Federation. Furthermore, Rslib utilizes Rsbuild's out-of-the-box configuration to facilitate configuration sharing between application and library projects, resolving the challenge of reusing build configurations between application projects and library projects, thereby reducing the configuration overhead for developers and improving development efficiency and experience. In the future, Rslib will explore additional possibilities by leveraging the new features of Rspack. ## 🔥 Features Rslib has the following features: * **Easy to Configure**: Rslib aims to simplify library development by offering ready-to-use build capabilities, enabling developers to kickstart their library projects with minimal configuration. * **Performance Oriented**: Rslib integrates high-performance Rust-based tools from the community, including [Rspack](https://rspack.dev/), [SWC](https://swc.rs/) and [Lightning CSS](https://lightningcss.dev/), to deliver first-class build speed and development experience. * **Plugin Ecosystem**: Powered by Rsbuild, Rslib benefits from a lightweight plugin system and a collection of high-quality official plugins. Furthermore, Rsbuild's compatibility with most webpack plugins and all Rspack plugins allows library developers to seamlessly integrate existing community or in-house plugins into their library projects. ## 🎯 Ecosystem Rslib is implemented based on Rsbuild and fully reuses the capabilities and ecosystem of Rsbuild. The following diagram illustrates the relationship between Rslib and other tools in the ecosystem: ![Rspack stack layers](https://assets.rspack.dev/rsbuild/assets/rspack-stack-layers.png) ## 🦀 Links * [Rspack](https://github.com/web-infra-dev/rspack): A fast Rust-based web bundler. * [Rsbuild](https://github.com/web-infra-dev/rsbuild): A Rspack Powered Build Tool. * [Rspress](https://github.com/web-infra-dev/rspress): A fast static site generator based on Rsbuild. * [Rsdoctor](https://github.com/web-infra-dev/rsdoctor): A one-stop build analyzer for Rspack and webpack. * [Modern.js](https://github.com/web-infra-dev/modern.js): A progressive React framework based on Rsbuild. * [awesome-rspack](https://github.com/web-infra-dev/awesome-rspack): A curated list of awesome things related to Rspack and Rsbuild. * [rspack-examples](https://github.com/rspack-contrib/rspack-examples): Examples for Rspack, Rsbuild, Rspress and Rsdoctor. * [storybook-rsbuild](https://github.com/rspack-contrib/storybook-rsbuild): Storybook builder powered by Rsbuild. * [rsbuild-plugin-template](https://github.com/rspack-contrib/rsbuild-plugin-template): Use this template to create your own Rsbuild plugin. * [rstack-design-resources](https://github.com/rspack-contrib/rstack-design-resources): Design resources for Rspack, Rsbuild, Rslib, Rspress and Rsdoctor. ## 🧑‍💻 Community Come and chat with us on [Discord](https://discord.gg/XsaKEEk4mW)! The Rspack / Rsbuild / Rslib team and users are active there, and we're always looking for contributions. --- url: /guide/start/quick-start.md --- # Quick start ## Setup environment Before getting started, you will need to install [Node.js](https://nodejs.org/) >= 16, it is recommended to use the Node.js LTS version. Check the current Node.js version with the following command: ```bash node -v ``` If you do not have Node.js installed in current environment, or the installed version is too low, you can use [nvm](https://github.com/nvm-sh/nvm) or [fnm](https://github.com/Schniz/fnm) to install. Here is an example of how to install via nvm: ```bash # Install Node.js LTS nvm install --lts # Switch to Node.js LTS nvm use --lts ``` ## Creating an Rslib project You can use the [`create-rslib`](https://www.npmjs.com/package/create-rslib) to create a new Rslib project. Run the following command: Then follow the prompts to complete the operation. ### Templates `create-rslib` is a tool for quickly creating Rslib projects. When creating a project, you can choose from the following templates: | Template | Description | | ---------------------------- | ---------------------------- | | Node.js dual ESM/CJS package | Node.js dual ESM/CJS package | | Node.js pure ESM package | Node.js pure ESM package | | React | React component library | Each template supports both JavaScript and TypeScript, along with optional development tools, formatters, and linters. :::info We're working to provide templates for more frameworks (such as Vue). ::: ### Development tools `create-rslib` can help you set up some commonly used development tools, including [Vitest](https://vitest.dev/), [Storybook](https://storybook.js.org/). You can use the arrow keys and the space bar to make your selections. If you don't need these tools, you can simply press Enter to skip. * Vitest is available for all templates, it will be adapted based on the template's selection. * Storybook is available for web targeted templates (React), it will be adapted based on the template's selection. ```text ◆ Select development tools (Use to select, to continue) │ ◻ Storybook │ ◻ Vitest └ ``` ### Optional tools `create-rslib` can help you set up some commonly used linter and formatter tools, including [Biome](https://biomejs.dev/), [ESLint](https://eslint.org/), and [prettier](https://prettier.io/). You can use the arrow keys and the space bar to make your selections. If you don't need these tools, you can simply press Enter to skip. ```text ◆ Select additional tools (Use to select, to continue) │ ◻ Add Biome for code linting and formatting │ ◻ Add ESLint for code linting │ ◻ Add Prettier for code formatting └ ``` :::tip Biome provides similar linting and formatting features to ESLint and Prettier. If you select Biome, you typically won't need to choose ESLint or Prettier as well. ::: ### Current directory If you need to create a project in the current directory, you can set the target folder to `.`: ```text ◆ Create Rslib Project │ ◇ Project name or path │ . │ ◇ "." is not empty, please choose: │ Continue and override files ``` ### Quick creation [create-rslib](https://www.npmjs.com/package/create-rslib) provides some CLI flags. By setting these CLI flags, you can skip the interactive selection steps and create the project with one command. For example, to create an example project in the `my-project` directory with one command: ```bash npx create-rslib --dir my-project --template example # Using abbreviations npx create-rslib -d my-project -t example ``` All the CLI flags of `create-rslib`: ```text Usage: create-rslib [options] Options: -h, --help display help for command -d, --dir create project in specified directory -t, --template specify the template to use --tools select additional tools (biome, eslint, prettier) --override override files in target directory ``` ## Migrate from existing projects To migrate from an existing project to Rslib, refer to the following guides: * [Migrating from tsup](/guide/migration/tsup.md) * [Migrating from Modern.js Module](/guide/migration/modernjs-module.md) ### Other projects For other types of projects, you can manually install the [@rslib/core](https://www.npmjs.com/package/@rslib/core) package: Then refer to the guide and documentation to enable the features you need: * See [CLI](/guide/basic/cli.md) to learn about available CLI commands. * See [Configure Rslib](/guide/basic/configure-rslib.md) to configure Rslib. --- url: /guide/start/glossary.md --- # Glossary ## ESM ESM stands for ECMAScript Modules, a modern module system introduced in ES2015 that allows JavaScript code to be organized into reusable, self-contained modules. ESM is now the standard for both [browser](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) and [Node.js](https://nodejs.org/api/esm.html) environments, replacing older module systems like [CommonJS (CJS)](https://nodejs.org/api/modules.html) and [AMD](https://requirejs.org/docs/whyamd.html). ## CJS CJS stands for [CommonJS](https://nodejs.org/api/modules.html#modules-commonjs-modules), a module system used in JavaScript, particularly in server-side environments like Node.js. It was created to allow JavaScript to be used outside of the browser by providing a way to manage modules and dependencies. ## UMD UMD stands for [Universal Module Definition](https://github.com/umdjs/umd), a pattern for writing JavaScript modules that can work universally across different environments, such as both the browser and Node.js. Its primary goal is to ensure compatibility with the most popular module systems, including AMD (Asynchronous Module Definition), CommonJS (CJS), and browser globals. ## Bundleless Bundleless means that each source file is compiled and built separately, but not bundled together. Each output file can be found with its corresponding source code file. The process of bundleless build can also be understood as the process of code transformation of source files only. ## Module Federation Module Federation is an architectural pattern for JavaScript application decomposition (similar to microservices on the server-side), allowing you to share code and resources between multiple JavaScript applications (or micro-frontends). See [Module Federation](https://rsbuild.dev/guide/advanced/module-federation) for more details. ## More See more glossary in [Rsbuild - Glossary](https://rsbuild.dev/guide/start/glossary) and [Rspack - Glossary](https://rspack.dev/misc/glossary). --- url: /guide/start/npm-packages.md --- # Packages This document showcases all the npm package information maintained by Rslib team. ## @rslib/core ![](https://img.shields.io/npm/v/@rslib/core?style=flat-square\&colorA=564341\&colorB=F8F5FF) Rslib core package that provides CLI commands and build capabilities based on Rsbuild. * [npm](https://npmjs.com/package/@rslib/core) * [Source Code](https://github.com/web-infra-dev/rslib/tree/main/packages/core) ## rsbuild-plugin-dts ![](https://img.shields.io/npm/v/rsbuild-plugin-dts?style=flat-square\&colorA=564341\&colorB=F8F5FF) Rsbuild plugin that supports emitting declaration files for TypeScript. * [npm](https://npmjs.com/package/rsbuild-plugin-dts) * [Source Code](https://github.com/web-infra-dev/rslib/tree/main/packages/plugin-dts) ## create-rslib ![](https://img.shields.io/npm/v/create-rslib?style=flat-square\&colorA=564341\&colorB=F8F5FF) Used to create a new Rslib project. * [npm](https://npmjs.com/package/create-rslib) * [Source Code](https://github.com/web-infra-dev/rslib/tree/main/packages/create-rslib) --- url: /guide/solution/index.md --- # Solution In this chapter, we will introduce how to use Rslib to development libraries for browser and Node.js. We will also cover how to create libraries for different UI frameworks. ## Browser target When developing a library that runs in the browser, you can package it in both [ESM](/guide/basic/output-format.md#esm--cjs) and [CJS](/guide/basic/output-format.md#esm--cjs) formats for integration with application bundlers. Configuring the package [conditional exports](https://nodejs.org/api/packages.html#conditional-exports) to ESM output allows for better tree shaking. Additionally, you can create [UMD](/guide/basic/output-format.md#umd) format output for direct browser use and even generate [Module Federation ](/guide/advanced/module-federation.md) formats for dynamic loading by other applications. Configure [Browserslist](https://rsbuild.dev/guide/advanced/browserslist) according to the target browser support to determine the downgrade syntax of the output, or add a [polyfill](/guide/advanced/output-compatibility.md) for API compatibility. When publishing to npm, you can choose not to [minify](/config/rsbuild/output.md#outputminify) your code or to minify it while providing a [sourcemap](/config/rsbuild/output.md#outputsourcemap) to enhance the debugging experience for users of your library. For styling, you can use CSS, or CSS pre-processors like Sass, Less, or Stylus, or apply PostCSS for CSS post-processing. Tools like Tailwind CSS can also help in building your styles. Using CSS Modules to create CSS modules is another option. In terms of resource management, Rslib handles static assets used in your code, such as SVG and PNG files. You can also build a component library of [React](/guide/solution/react.md), [Preact](https://github.com/web-infra-dev/rslib/tree/main/examples/preact-component-bundle-false), or other frameworks, and use [Storybook](/guide/advanced/storybook.md) for UI component development and testing. Refer to the solutions in this chapter to learn how to use Rslib to develop browser libraries for different frameworks. {/* TODO: Clarify default behavior */} {/* ### Default Behavior */} ## Node.js target Rslib set [target](/config/rsbuild/output.md#outputtarget) to `"node"` by default to development libraries for Node.js. You can create a [pure ESM](/guide/basic/output-format.md#esm--cjs) package or a [dual package](/guide/basic/output-format.md#esm--cjs) that supports both ESM and CJS as needed. In CJS output, `import.meta.url` will be automatically [shimmed](/config/lib/shims.md) for compatibility and `__dirname` and `__filename` got optional ESM shims to ensure proper use across different module system. Node.js's built-in packages will be [externalized by default](/guide/advanced/third-party-deps.md). {/* TODO: Clarify default behavior */} {/* ### Default Behavior */} --- url: /guide/solution/nodejs.md --- # Node.js In this document, you will learn how to build a Node.js library using Rslib. ## Create Node.js project You can use `create-rslib` to create a project with Rslib + Node.js. Just execute the following command: Then select `Node.js` when prompted to "Select template". ## Use Rslib in an existing project Rslib offers seamless support for Node.js projects, allowing you to build Node.js project effortlessly with minimal configuration. For example, in `rslib.config.ts`: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { format: 'esm', output: { distPath: { root: './dist/esm', }, }, }, { format: 'cjs', output: { distPath: { root: './dist/cjs', }, }, }, ], }); ``` ## Target for Node.js Rslib sets [target](/config/rsbuild/output.md#outputtarget) to `"node"` by default, which is different from the default target of Rsbuild. When target is set to `"node"`, Rslib adjusts many configurations for Node.js. For example, [output.externals](/config/rsbuild/output.md#outputtarget) will exclude built-in Node.js modules, and [shims](/config/lib/shims.md) will add a shim for `import.meta.url` in CJS output by default. ### Externals All Node.js [built-in modules](https://nodejs.org/docs/latest/api/) are externalized by default. ### Shims * `global`: leave it as it is, while it's recommended to use [globalThis](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis) instead. * `__filename`: When outputting in ESM format, replace `__filename` with the result of `fileURLToPath(import.meta.url)`. * `__dirname`: When outputting in ESM format, replace `__dirname` with the result of `dirname(fileURLToPath(import.meta.url))`. {/* TODO: Rspack doesn't support createRequire now */} {/* ### createRequire */} {/* Requiring module with [createRequire](https://nodejs.org/api/module.html#modulecreaterequirefilename) will also works in ESM format. */} --- url: /guide/solution/react.md --- # React In this document, you will learn how to build a React component library with Rslib. ## Create React project You can use `create-rslib` to create a project with Rslib + React. Just execute the following command: Then select `React` when prompted to "Select template". ## Use Rslib in an existing project To develop a React library, you need to set the [target](/config/rsbuild/output.md#outputtarget) to `"web"` in `rslib.config.ts`. This is crucial because Rslib sets the `target` to `"node"` by default, which differs from the default target of Rsbuild. To compile React (JSX and TSX), you need to register the Rsbuild [React Plugin](https://rsbuild.dev/plugins/list/plugin-react). The plugin will automatically add the necessary configuration for React builds. For example, register in `rslib.config.ts`: ```ts title="rslib.config.ts" {2,8-11} import { defineConfig } from '@rslib/core'; import { pluginReact } from '@rsbuild/plugin-react'; export default defineConfig({ lib: [ // ... ], output: { target: 'web', }, plugins: [pluginReact(/** options here */)], }); ``` ## JSX transform * **Type**: `'automatic' | 'classic'` * **Default**: `'automatic'` React introduced a [new JSX transform](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) in version 17. This new transform removes the need to import `React` when using JSX. By default, Rsbuild uses the new JSX transform, which is `runtime: 'automatic'`. It requires at least React `16.14.0` or higher. The `peerDependencies` should be declared as `"react": ">=16.14.0"`. To change the JSX transform, you can pass the [swcReactOptions](https://rsbuild.dev/plugins/list/plugin-react#swcreactoptionsruntime) option to the React plugin. For example, to use the classic runtime: ```ts title="rslib.config.ts" {13-15} import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ // ... ], output: { target: 'web', }, plugins: [ pluginReact({ swcReactOptions: { runtime: 'classic', }, }), ], }); ``` ## JSX import source * **Type**: `string` * **Default**: `'react'` When `runtime` is set to `'automatic'`, you can specify the import path of the JSX transform through `importSource`. For example, when using [Emotion](https://emotion.sh/), you can set `importSource` to `'@emotion/react'`: ```ts title="rslib.config.ts" {13-15} import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ // ... ], output: { target: 'web', }, plugins: [ pluginReact({ swcReactOptions: { importSource: '@emotion/react', }, }), ], }); ``` ## SVGR Read [Import SVGR](/guide/advanced/svgr-files.md) for more details. ## Further reading * [Rsbuild React Plugin](https://rsbuild.dev/plugins/list/plugin-react#swcreactoptionsruntime) * [SWC Compilation - jsc.transform.react](https://swc.rs/docs/configuration/compilation#jsctransformreact) --- url: /guide/basic/cli.md --- # CLI Rslib comes with a lightweight CLI that includes commands such as [rslib build](#rslib-build) and [rslib inspect](#rslib-inspect). ## rslib -h To view all available CLI commands, run the following command in the project directory: ```bash npx rslib -h ``` The output is shown below: ```text Usage: rslib [options] Options: -V, --version output the version number -h, --help display help for command Commands: build [options] build the library for production inspect [options] inspect the Rsbuild / Rspack configs of Rslib projects mf-dev [options] start Rsbuild dev server of Module Federation format help [command] display help for command ``` ## rslib build The `rslib build` command will build the outputs for production in the `dist/` directory by default. ```text Usage: rslib build [options] build the library for production Options: -c --config specify the configuration file, can be a relative or absolute path -r --root specify the project root directory, can be an absolute path or a path relative to cwd --env-mode specify the env mode to load the `.env.[mode]` file --env-dir specify the directory to load `.env` files --lib specify the library (repeatable, e.g. --lib esm --lib cjs) -w --watch turn on watch mode, watch for changes and rebuild -h, --help display help for command ``` ### Watch mode You can use `rslib build --watch` or `rslib build -w` to enable watch mode for watching for changes and rebuild. ```bash npx rslib build -w ``` ### Environment variables Rslib supports injecting env variables or expressions into the code during build, which is helpful for distinguishing the running environment or replacing constants. You can see more details in [Rsbuild - Environment Variables](https://rsbuild.dev/guide/advanced/env-vars). ::: note * If [format](/config/lib/format.md) is `esm` or `cjs`, `process.env.NODE_ENV` will be preserved in the build output. * If [format](/config/lib/format.md) is `mf` or `umd`, `process.env.NODE_ENV` will be replaced to ensure that the output can run in the browser. ::: #### Env mode Rslib supports reading `.env.[mode]` and `.env.[mode].local` files. You can specify the env mode using the `--env-mode ` flag. For example, set the env mode as `test`: ```bash npx rslib build --env-mode test ``` Rslib will then read the following files in sequence: * `.env` * `.env.local` * `.env.test` * `.env.test.local` :::tip The `--env-mode` option takes precedence over `process.env.NODE_ENV`. It is recommended to use `--env-mode` to set the env mode, and not to modify `process.env.NODE_ENV`. ::: #### Env directory By default, the `.env` file is located in the root directory of the project. You can specify the env directory by using the `--env-dir ` option in the CLI. For example, to specify the env directory as `config`: ```bash npx rslib build --env-dir config ``` In this case, Rslib will read the `./config/.env` and other env files. ##### Example For example, create a `.env` file and add the following contents: ```shell title=".env" FOO=hello BAR=1 ``` Then in the `rslib.config.ts` file, you can access the above env variables using `import.meta.env.[name]` or `process.env.[name]`: ```ts title="rslib.config.ts" console.log(import.meta.env.FOO); // 'hello' console.log(import.meta.env.BAR); // '1' console.log(process.env.FOO); // 'hello' console.log(process.env.BAR); // '1' ``` Now, create a `.env.local` file and add the following contents: ```shell title=".env.local" BAR=2 ``` The value of `BAR` is overwritten to `'2'`: ```ts title="rslib.config.ts" console.log(import.meta.env.BAR); // '2' console.log(process.env.BAR); // '2' ``` ## rslib inspect The `rslib inspect` command is used to view the Rsbuild config and Rspack config of the Rslib project. ```text Usage: rslib inspect [options] inspect the Rsbuild / Rspack configs of Rslib projects Options: -c --config specify the configuration file, can be a relative or absolute path -r --root specify the project root directory, can be an absolute path or a path relative to cwd --env-mode specify the env mode to load the `.env.[mode]` file --env-dir specify the directory to load `.env` files --lib specify the library (repeatable, e.g. --lib esm --lib cjs) --output specify inspect content output path (default: ".rsbuild") --verbose show full function definitions in output -h, --help display help for command ``` When you run the command `npx rslib inspect` in the project root directory, the following files will be generated in the `dist/.rsbuild` directory of the project: * `rsbuild.config.mjs`: Represents the Rsbuild configuration used during the build. * `rspack.config.web.mjs`: Represents the Rspack configuration used during the build. ```text ➜ npx rslib inspect Inspect config succeed, open following files to view the content: - Rsbuild Config: /project/dist/.rsbuild/rsbuild.config.mjs - Rspack Config (esm): /project/dist/.rsbuild/rspack.config.esm.mjs ``` ### Verbose content By default, the inspect command omits the content of functions in the configuration object. You can add the `--verbose` option to output the complete content of functions: ```bash rslib inspect --verbose ``` ### Multiple output formats If the current project has multiple output formats, such as ESM artifact and CJS artifact simultaneously, multiple Rspack configuration files will be generated in the `dist/.rsbuild` directory. ```text ➜ npx rslib inspect Inspect config succeed, open following files to view the content: - Rsbuild Config (esm): /project/dist/.rsbuild/rsbuild.config.esm.mjs - Rsbuild Config (cjs): /project/dist/.rsbuild/rsbuild.config.cjs.mjs - Rspack Config (esm): /project/dist/.rsbuild/rspack.config.esm.mjs - Rspack Config (cjs): /project/dist/.rsbuild/rspack.config.cjs.mjs ``` ## rslib mf-dev The `rslib mf-dev` command is utilized to start Rsbuild dev server for the [Module Federation](/guide/advanced/module-federation.md) format. This enables you to develop and debug your mf format module within the host app. ```text Usage: rslib mf-dev [options] start Rsbuild dev server of Module Federation format Options: -c --config specify the configuration file, can be a relative or absolute path -r --root specify the project root directory, can be an absolute path or a path relative to cwd --env-mode specify the env mode to load the `.env.[mode]` file --env-dir specify the directory to load `.env` files --lib specify the library (repeatable, e.g. --lib esm --lib cjs) -h, --help display help for command ``` ## Common options ### Filter libraries Rslib provides the `--lib` option to run command for specified libraries. ```bash # Only build the library with id `esm` npx rslib build --lib esm ``` The `--lib` option can be repeated to specify multiple libraries. ```bash # Build the libraries with id `esm` and `cjs` npx rslib build --lib esm --lib cjs ``` > Check out the [lib.id](/config/lib/id.md) to learn how to get or set the library ID. --- url: /guide/basic/configure-rslib.md --- # Configure Rslib Rslib's configuration is based on Rsbuild, which means that you can use all of Rsbuild configurations, as well as the `lib` configuration specific to Rslib. ## Configuration structure Rslib provides the `lib` option to configure the library outputs. It is an array, and each object is used to describe a format of the output. For example, output ESM and CJS formats, and use `es2021` syntax: ```js title="rslib.config.mjs" export default { lib: [ { format: 'esm', syntax: 'es2021' }, { format: 'cjs', syntax: 'es2021' }, ], }; ``` ### Common Rsbuild configurations You can set common Rsbuild configurations outside the `lib` field, which will be inherited by each configuration object inside the `lib` field. For example, set the [output.target](/config/rsbuild/output.md#outputtarget) of Rsbuild to `web`, which will affect the output of all `lib` configuration objects: ```js title="rslib.config.mjs" export default { lib: [ { format: 'esm', syntax: 'es2021' }, { format: 'cjs', syntax: 'es2021' }, ], output: { target: 'web', }, }; ``` ### Separate Rsbuild configurations In the `lib` field, you can set separate Rsbuild configurations for each output format, which will override the common Rsbuild configurations outside the `lib` field. For example, separately set the [output.target](/config/rsbuild/output.md#outputtarget) of the ESM output to `web`: ```js title="rslib.config.mjs" export default { lib: [ // The target of the ESM output is `web` { format: 'esm', output: { target: 'web', }, }, // The CJS output inherits the common configuration and target is `node` { format: 'cjs', }, ], output: { target: 'node', }, }; ``` Rslib will generate the [environments](https://rsbuild.dev/config/environments) configuration of Rsbuild internally, please refer to [Configuration Debug](#configuration-debug) to view the final generated configuration. You can also refer to the [Configuration Overview](/config/index.md) page to view the detailed introduction of all configurations. ## Configuration file When you use the CLI of Rslib, Rslib will automatically read the configuration file in the root directory of the current project and resolve it in the following order: * `rslib.config.mjs` * `rslib.config.ts` * `rslib.config.js` * `rslib.config.cjs` * `rslib.config.mts` * `rslib.config.cts` We recommend using the `.mjs` or `.ts` format for the configuration file and importing the `defineConfig` utility function from `@rslib/core`. It provides friendly TypeScript type hints and autocompletion, which can help you avoid errors in the configuration. For example, in `rslib.config.ts`, you can define the Rslib [syntax](/config/lib/syntax.md) configuration and the Rsbuild [output.target](https://rsbuild.dev/config/output/target#outputtarget) configuration: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { format: 'esm', syntax: 'es2021', }, ], output: { target: 'node', }, }); ``` If you are developing a non-TypeScript project, you can use the `.mjs` format for the configuration file. :::tip When you use the `.ts`, `.mts`, and `.cts` extensions, Rslib will use [jiti](https://github.com/unjs/jiti) to load configuration files, providing interoperability between ESM and CommonJS. The behavior of module resolution differs slightly from the native behavior of Node.js. ::: ## Specify config file Rslib CLI uses the `--config` option to specify the config file, which can be set to a relative path or an absolute path. For example, if you need to use the `rslib.prod.config.mjs` file when running `build`, you can add the following scripts to `package.json`: ```json title="package.json" { "scripts": { "build": "rslib build --config rslib.prod.config.mjs" } } ``` You can also abbreviate the `--config` option to `-c`: ```bash rslib build -c rslib.prod.config.mjs ``` ## 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="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { format: 'esm', }, ], source: { alias: { '@request': process.env.NODE_ENV === 'development' ? './src/request.dev.js' : './src/request.prod.js', }, }, }); ``` ## Configure Rsbuild Rslib allows you to use most of the Rsbuild configurations. Currently, the `environments` config is not supported because it is generated internally by Rslib. * Refer to [Rsbuild Configuration](/config/rsbuild/index.md) for common Rsbuild configurations. * Refer to [Rsbuild Documentation](https://rsbuild.dev/config/index#config-overview) for all Rsbuild configurations. ## Configure Rspack Rslib is built on top of Rsbuild and Rsbuild supports directly modifying the Rspack configuration object and also supports modifying the built-in Rspack configuration of Rsbuild through `rspack-chain`. This means you can configure Rspack related configurations in an Rslib project as well. For more details, refer to [Configure Rspack](https://rsbuild.dev/guide/basic/configure-rspack). ## Configuration debug You can enable Rslib's debug mode by adding the `DEBUG=rsbuild` environment variable when executing a build. It will display the final Rsbuild/Rspack configuration after processing by Rslib. ```bash DEBUG=rsbuild pnpm build ``` In debug mode, Rslib will write the Rsbuild / Rspack config to the dist directory, which is convenient for developers to view and debug. Here is an example of a library that sets both CJS and ESM formats: ``` Inspect config succeed, open following files to view the content: - Rsbuild Config (esm): /project/dist/.rsbuild/rsbuild.config.esm.mjs - Rsbuild Config (cjs): /project/dist/.rsbuild/rsbuild.config.cjs.mjs - Rspack Config (esm): /project/dist/.rsbuild/rspack.config.esm.mjs - Rspack Config (cjs): /project/dist/.rsbuild/rspack.config.cjs.mjs ``` * Open the generated `/dist/.rsbuild/rsbuild.config.esm.mjs` file to see the complete content of the Rsbuild config. * Open the generated `/dist/.rsbuild/rspack.config.esm.mjs` file to see the complete content of the Rspack config. --- url: /guide/basic/typescript.md --- # Use TypeScript Rslib supports TypeScript by default, allowing you to directly use `.ts` and `.tsx` files in your projects. ## TypeScript transpilation Rslib uses SWC by default for transpiling TypeScript code, and it also supports switching to Babel for transpilation. ### isolatedModules 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 a value. Therefore, when using TypeScript in Rslib, you need to enable the [isolatedModules](https://typescriptlang.org/tsconfig/#isolatedModules) option in your `tsconfig.json` file: ```json title="tsconfig.json" { "compilerOptions": { "isolatedModules": true } } ``` This option can help you avoid using certain syntax that cannot be correctly compiled by SWC and Babel, such as cross-file type references. It will guide you to correct the corresponding 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 `@rslib/core` provides some preset type definitions, including CSS Modules, static assets, `import.meta` and other types. You can create a `src/env.d.ts` file to reference it: ```ts title="src/env.d.ts" /// ``` ## tsconfig.json path Rslib by default reads the `tsconfig.json` file from the root directory. You can use [source.tsconfigPath](/config/rsbuild/source.md#sourcetsconfigpath) to configure a custom `tsconfig.json` file path. ```ts title="rslib.config.ts" export default { lib: [ // ... ], source: { tsconfigPath: './tsconfig.custom.json', }, }; ``` --- url: /guide/basic/output-format.md --- # Output format There are four supported output formats for the generated JavaScript files in Rslib: `esm`, `cjs`, `umd`, and `mf`. In this chapter, we will introduce the differences between these formats and how to choose the right one for your library. ## ESM / CJS Library authors need to carefully consider which module formats to support. Let's understand ESM (ECMAScript Modules) and CJS (CommonJS) and when to use them. ### What are ESM and CJS? * **ESM**: ESM is a modern module system introduced in ES2015 that allows JavaScript code to be organized into reusable, self-contained modules. ESM is now the standard for both [browser](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) and [Node.js](https://nodejs.org/api/esm.html) environments, replacing older module systems like [CommonJS (CJS)](https://nodejs.org/api/modules.html) and [AMD](https://requirejs.org/docs/whyamd.html). * **CommonJS**: [CommonJS](https://nodejs.org/api/modules.html#modules-commonjs-modules) is a module system used in JavaScript, particularly in server-side environments like Node.js. It was created to allow JavaScript to be used outside of the browser by providing a way to manage modules and dependencies. ### What is the dilemma of ESM / CJS > The following references are from [Node Modules at War: Why CommonJS and ES Modules Can't Get Along](https://redfin.engineering/node-modules-at-war-why-commonjs-and-es-modules-cant-get-along-9617135eeca1). 1. You can't `require()` ESM scripts; you can only import ESM scripts, like this: `import {foo} from 'foo'` 2. CJS scripts can't use static `import` statements like the one above. 3. ESM scripts can `import` CJS scripts, but only by using the **default import** syntax `import _ from 'lodash'`, not the **named import** syntax `import {shuffle} from 'lodash'`, which is a hassle if the CJS script uses named exports. (Except, sometimes, unpredictibly, Node can figure out what you meant!) 4. ESM scripts can `require()` CJS scripts, even with named exports, but it's typically not worth the trouble, because it requires even more boilerplate, and, worst of all, bundlers like Webpack and Rollup don't/won't know how to work with ESM scripts that use `require()`. 5. CJS is the default; you have to opt-in to ESM mode. You can opt-in to ESM mode by renaming your script from `.js` to `.mjs`. Alternately, you can set `"type": "module"` in `package.json`, and then you can opt-out of ESM by renaming scripts from `.js` to `.cjs`. (You can even tweak just an individual subdirectory by putting a one-line `{"type": "module"}` `package.json` file in there.) ### When to support which format? For different shapes of libraries, the choice of module format may vary. Here are two common scenarios: #### ship [pure ESM](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) package shipping only ESM is the best choice for libraries that are intended to be used in modern environments, such as browser applications or Node.js applications that support ESM. However, if the upstream library is in format of CJS, they only can import pure ESM by using dynamic import like `const pureEsmLib = await import('pure-esm-lib')`. * **Pros:** * ESM is the official JavaScript standard, making it more future-proof and widely supported across environments. * ESM enables static analysis, which facilitates optimizations like tree-shaking to remove unused code. * The syntax is cleaner and more intuitive, with import and export statements that are easier to read compared to CommonJS. * ESM allows for better compatibility across both browser and server environments, making it ideal for isomorphic or universal JavaScript applications. * **Cons:** * ESM modules are loaded asynchronously, which can complicate conditional imports and lazy loading in some cases. * Some Node.js tools and libraries still have limited or incomplete support for ESM, requiring workarounds or additional configuration. * You must explicitly include file extensions in import paths, which can be cumbersome, especially when working with TypeScript or other transpiled languages. #### ship [ESM & CJS (dual)](https://antfu.me/posts/publish-esm-and-cjs#compatibility) package The community is migrating to ESM, but there are still many projects using CJS. If you want to support both ESM and CJS, you can publish a dual package. For most library authors, offering dual formats is a safer and smoother way to access the best of both worlds. You could read antfu' blog post [Publish ESM and CJS packages](https://antfu.me/posts/publish-esm-and-cjs) for more details. * **Pros:** * Wider compatibility: Dual packages support both modern ESM environments and legacy CJS environments, ensuring broader usage across different ecosystems. * Gradual migration: Developers can gradually transition from CJS to ESM without breaking existing projects, allowing for smoother adoption of the new standard. * Flexibility for consumers: Users of the package can choose which module system best fits their project, providing flexibility in different build tools and environments. * Cross-runtime support: Dual packages can work in multiple runtimes, such as Node.js and browsers, without requiring additional bundling or transpilation. * **Cons:** * Increased complexity: Maintaining two module formats adds complexity to the build process, requiring additional configuration and testing to ensure both versions work correctly. * Dual package hazard: Mixing ESM and CJS can lead to issues such as broken instanceof checks or unexpected behavior when dependencies are loaded in different formats. ## UMD ### What is UMD? UMD stands for [Universal Module Definition](https://github.com/umdjs/umd), a pattern for writing JavaScript modules that can work universally across different environments, such as both the browser and Node.js. Its primary goal is to ensure compatibility with the most popular module systems, including AMD (Asynchronous Module Definition), CommonJS (CJS), and browser globals. ### When to use UMD? If you are building a library that needs to be used in both the browser and Node.js environments, UMD is a good choice. UMD can be used as a standalone script tag in the browser or as a CommonJS module in Node.js. A detailed answer from StackOverflow: [What is the Universal Module Definition (UMD)?](https://stackoverflow.com/a/77284527/8063488) > However, for frontend libraries, you still offer a single file for convenience, that users can download (from a CDN) and directly embed in their web pages. This still commonly employs a UMD pattern, it's just no longer written/copied by the library author into their source code, but added automatically by the transpiler/bundler. > > And similarly, for backend/universal libraries that are supposed to work in > Node.js, you still also distribute a commonjs module build via npm to support > all the users who still use a legacy version of Node.js (and don't want/need > to employ a transpiler themselves). This is less common nowadays for new > libraries, but existing ones try hard to stay backwards-compatible and not > cause applications to break. ### How to build a UMD library? * Set the [lib.format](/config/lib/format.md) to `umd` in the Rslib configuration file. * If the library need to be exported with a name, set [lib.umdName](/config/lib/umd-name.md) to the name of the UMD library. * Use [output.externals](/config/rsbuild/output.md#outputexternals) to specify the external dependencies that the UMD library depends on, [lib.autoExtension](/config/lib/auto-extension.md) is enabled by default for UMD. ### Examples The following Rslib config is an example to build a UMD library. * `lib.format: 'umd'`: instruct Rslib to build in UMD format. * `lib.umdName: 'RslibUmdExample'`: set the export name of the UMD library. * `output.externals.react: 'React'`: specify the external dependency `react` could be accessed by `window.React`. * `runtime: 'classic'`: use the classic runtime of React to support applications that using React version under 18. ```ts title="rslib.config.ts" {7-12,22} import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { format: 'umd', umdName: 'RslibUmdExample', output: { externals: { react: 'React', }, distPath: { root: './dist/umd', }, }, }, ], output: { target: 'web', }, plugins: [ pluginReact({ swcReactOptions: { runtime: 'classic', }, }), ], }); ``` ## MF ### What is MF? MF stands for Module Federation. Module Federation is an architectural pattern for JavaScript application decomposition (similar to microservices on the server-side), allowing you to share code and resources between multiple JavaScript applications (or micro-frontends). See [Module Federation](https://rsbuild.dev/guide/advanced/module-federation) for more details. --- url: /guide/basic/output-structure.md --- # Output structure ## bundle / bundleless So first let's understand bundle and bundleless. Bundle refers to the process of packaging the build outputs, which may be a single file or multiple files based on a certain [code splitting strategy](https://esbuild.github.io/api/#splitting). Bundleless, on the other hand, means that each source file is compiled and built separately, but not bundled together. Each output file can be found with its corresponding source code file. The process of bundleless build can also be understood as the process of code transformation of source files only. ![rslib-bundleless-mode](https://assets.rspack.dev/rslib/rslib-bundleless-mode.png) They have their own benefits. * bundle can reduce the size of build artifacts and also prebundle dependencies to reduce the size of installed dependencies and increase security. Packaging libraries in advance can speed up application project builds. * bundleless maintains the original file structure and is more conducive to debugging and tree shaking. :::warning bundleless is a single-file compilation mode, so for referencing and exporting types, you need to add the `type` keyword. For example, `import type { A } from './types'`. Please refer to [TypeScript - isolatedModules](/guide/basic/typescript.md#isolatedmodules) for more information. ::: You can specify whether to bundle using the [bundle](/config/lib/bundle.md) option, which is set to `true` by default. --- url: /guide/basic/upgrade-rslib.md --- # Upgrade Rslib This section explains how to upgrade the project's Rslib dependencies to the latest version. {/* TODO */} {/* > Please see [Releases](/community/releases/index) to understand the Rsbuild release strategy. */} :::info Rslib is still in 0.x version stage, and the API may change frequently. We recommend upgrading to the latest version to access new features and bug fixes. ::: ## Using taze We recommend using [Taze](https://github.com/antfu-collective/taze) to upgrade the Rslib version. Taze is a CLI tool for updating npm dependencies. ### Usage Run the following command to upgrade all dependencies that include `rslib` and `rsbuild` in their names: ```bash npx taze major --include "/(rsbuild|rslib)/" -w ``` :::tip Rslib has not yet reached version 1.0.0, so you need to add the `major` parameter when updating. ::: The result will look similar to: ```bash rslib - 2 major, 1 patch @rsbuild/plugin-react dev ~2mo ^1.0.1 → ^1.0.6 @rslib/core dev ~7d ^0.0.15 → ^0.0.16 rsbuild-plugin-dts dev ~7d ^0.0.15 → ^0.0.16 ℹ 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 `@rslib` scope: ```bash npx taze --include /@rslib/ -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|rslib)/ -w -r ``` * Add `-l` to upgrade locked versions: ```bash npx taze --include /(rsbuild|rslib)/ -w -l ``` * To upgrade to a major version: ```bash npx taze major --include /(rsbuild|rslib)/ -w ``` > For more options, please refer to the [taze documentation](https://github.com/antfu-collective/taze). --- url: /guide/advanced/third-party-deps.md --- # Handle third-party dependencies This section introduces how to handle third-party dependencies in bundle mode. Generally, third-party dependencies required by a project can be installed via the `install` command in the package manager. After the third-party dependencies are successfully installed, they will generally appear under `dependencies` and `devDependencies` in the project `package.json`. ```json title="package.json" { "dependencies": {}, "devDependencies": {} } ``` Dependencies under `"dependencies"` are generally required for the package in runtime, and if these third-party dependencies are declared under `"devDependencies"`, then there will be missing dependencies in production runtime. In addition to `"dependencies"`, `"peerDependencies"`can also declare dependencies that are needed in the production environment, but it puts more emphasis on the existence of these dependencies declared by `"peerDependencies"` in the project's runtime environment, similar to the plugin mechanism. ## Default handling of third-party dependencies By default, when generating CJS or ESM outputs, third-party dependencies under `"dependencies"`, `"optionalDependencies"` and `"peerDependencies"` are not bundled by Rslib. This is because when the npm package is installed, its `"dependencies"` will also be installed. By not packaging `"dependencies"`, you can reduce the size of the package product. If you need to package some dependencies, it is recommended to move them from `"dependencies"` to `"devDependencies"`, which is equivalent to prebundle the dependencies and reduces the size of the dependency installation. ### Example If the project has a dependency on `react`. ```json title="package.json" { "dependencies": { "react": "^18" }, // or "peerDependencies": { "react": "^18" } } ``` When a `react` dependency is used in the source code: ```tsx title="src/index.ts" import React from 'react'; console.info(React); ``` The `react` code will not be bundled into the output: ```js title="dist/index.js" import * as __WEBPACK_EXTERNAL_MODULE_react__ from 'react'; console.info(__WEBPACK_EXTERNAL_MODULE_react__['default']); ``` If you want to modify the default processing, you can use the following API: * [lib.autoExternal](/config/lib/auto-external.md) * [output.externals](/config/rsbuild/output.md#outputexternals) ## Exclude specified third-party dependencies The configuration described above allows you to implement more fine-grained handling of third-party dependencies. For example, when we need to leave only certain dependencies unbundled, we can configure it as follows. :::tip In this case, some dependencies may not be suitable for bundling. If so, you can handle it as follows. ::: ```ts export default defineConfig({ lib: [ { // ... autoExternal: true, output: { externals: ['pkg-1', /pkg-2/], }, // ... }, ], }); ``` --- url: /guide/advanced/output-compatibility.md --- # Output compatibility This chapter introduces how to specify which target environment should be supported. ## Syntax downgrade By setting [lib.syntax](/config/lib/syntax.md), you can choose the syntax to which JavaScript and CSS will be downgraded. You can use the query syntax from [Browserslist](https://browsersl.ist/). Rslib also supports common ECMAScript version numbers, such as `ES2015`. Rslib also supports using a [.browserslistrc](https://github.com/browserslist/browserslist#config-file) file to specify settings. Note that [lib.syntax](/config/lib/syntax.md) takes precedence over `.browserslistrc`. If both are present, `lib.syntax` will be used. By default, the syntax is set to `ESNext`, which will only supports only the latest version of mainstream browsers (Chrome / Firefox / Edge / macOS Safari / iOS Safari) or Node.js according to [output.target](/config/rsbuild/output.md#outputtarget). ## Polyfill Before dealing with compatibility issues, it is recommended that you understand the following background knowledge to better handle related issues. Check out the background knowledge on [syntax transpilation and API polyfill](https://rsbuild.dev/guide/advanced/browser-compatibility#syntax-downgrade-and-api-downgrade). ### Browser Normally, we don't need to inject polyfill for npm packages, this step should be done on the web application framework side, but in some scenarios we need to inject polyfill in order to make our library run directly in low version browsers. Note that this plugin does not transform your code syntax, it only injects polyfill for unsupported functions used in your code, importing them as normal functions instead of polluting the global. You need to install the [core-js-pure](https://www.npmjs.com/package/core-js-pure) dependency. #### Set up The polyfill relies on Babel to inject the polyfill code, so you need to install the [Rsbuild Babel plugin](https://rsbuild.dev/plugins/list/plugin-babel) and [babel-plugin-polyfill-corejs3](https://www.npmjs.com/package/babel-plugin-polyfill-corejs3) to inject the polyfill code. And install [core-js-pure](https://www.npmjs.com/package/core-js-pure) as the runtime relied code. Configure the Babel plugin with polyfill options, set the [targets](https://babeljs.io/docs/options#targets) field to specify the target browser version. ```ts title="rslib.config.ts" {1,11-24} import { pluginBabel } from '@rsbuild/plugin-babel'; import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ { format: 'esm', }, ], plugins: [ pluginBabel({ babelLoaderOptions: { plugins: [ [ require('babel-plugin-polyfill-corejs3'), { method: 'usage-pure', targets: { ie: '10' }, version: '3.29', }, ], ], }, }), ], }); ``` #### Configurations Check out [babel-plugin-polyfill-corejs3](https://www.npmjs.com/package/babel-plugin-polyfill-corejs3) documentation for more details. ### Node.js :::tip About Node Polyfill Normally, we don't need to use Node libs on the browser side. However, it is possible to use some Node libs when the code will run on both the Node side and the browser side, and Node Polyfill provides browser versions of polyfills for these Node libs. ::: By using [@rsbuild/plugin-node-polyfill](https://github.com/rspack-contrib/rsbuild-plugin-node-polyfill), Node core libs polyfills are automatically injected into the browser-side, allowing you to use these modules on the browser side with confidence. #### Set up Rslib uses [@rsbuild/plugin-node-polyfill](https://github.com/rspack-contrib/rsbuild-plugin-node-polyfill) to provide the Node Polyfill feature. Then add the plugin into the plugins field. ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; import { pluginNodePolyfill } from '@rsbuild/plugin-node-polyfill'; export default defineConfig({ lib: [{ format: 'esm' }], plugins: [pluginNodePolyfill()], }); ``` #### Configurations * For projects with `bundle` enabled, the Node Polyfill will be injected and included in the output. * For projects with `bundle` disabled, polyfills are not injected into the output by default. To avoid inlining the polyfill in every module, the modules are externalized and need to be added to dependencies manually, follow these steps: 1. Configure `output.external` with `resolvedPolyfillToModules`, which you can import from [@rsbuild/plugin-node-polyfill](https://github.com/rspack-contrib/rsbuild-plugin-node-polyfill). This will externalize the polyfill modules to the installed polyfill dependencies. 2. Install used polyfill modules as dependencies. With the following steps, every usage of the polyfill module will be replaced by the corresponding module in the `externals` field. Checkout the of the example for more details. Check out the documentation of [@rsbuild/plugin-node-polyfill](https://github.com/rspack-contrib/rsbuild-plugin-node-polyfill), all the configurations are applicable for Rslib. --- url: /guide/advanced/dts.md --- # Declaration files This chapter introduces what [TypeScript Declaration Files](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html) are and how to generate declaration files in Rslib. ## What is declaration files TypeScript Declaration Files provide type information for JavaScript code. Declaration files typically have a `.d.ts` extension. They allow the TypeScript compiler to understand the type structure of JavaScript code, enabling features like: 1. **Type Checking**: Provide type information for JavaScript code, helping developers catch potential type errors at compile time. 2. **Code Completion**: Enhance code editor features like autocomplete and code navigation. 3. **Documentation Generation**: Generate documentation for JavaScript code, providing better developer experience. 4. **IDE Support**: Improve the developer experience in IDEs like Visual Studio Code, WebStorm, and others. 5. **Library Consumption**: Make it easier for users to use and understand your library. ## What are bundle declaration files and bundleless declaration files ### Bundle declaration files Bundle declaration files involves bundling multiple TypeScript declaration files into a single declaration file. * **Pros:** * **Simplified Management**: Simplifies the management and referencing of type files. * **Easy Distribution**: Reduces the number of files users need to handle when using the library. * **Cons:** * **Complex Generation**: Generating and maintaining a single bundle file can become complex in large projects. * **Debugging Challenges**: Debugging type issues may not be as intuitive as with separate files. ### Bundleless declaration files Bundleless declaration files involves generating a separate declaration file for each module in the library, just like `tsc` does. * **Pros:** * **Modular**: Each module has its own type definitions, making maintenance and debugging easier. * **Flexibility**: Suitable for large projects, avoiding the complexity of a single file. * **Cons:** * **Multiple Files**: Users may need to handle multiple declaration files when using the library. * **Complex Management**: May require additional configuration to correctly reference all files. ## How to generate declaration files in Rslib Rslib defaults to generating bundleless declaration files, which using [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) and bundle declaration files is also supported by [API Extractor](https://api-extractor.com/). If you want to generate bundleless declaration files, you can: * Set `dts: true` or `dts: { bundle: false }` in the Rslib configuration file. If you want to generate bundle declaration files, you can: 1. Install `@microsoft/api-extractor` as `devDependencies`, which is the underlying tool used for bundling declaration files. 2. Set `dts: { bundle: true }` in the Rslib configuration file. It should be noted that during the generation of declaration files, Rslib will automatically enforce some configuration options in `tsconfig.json` to ensure that the [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) generates only declaration files. ```json { "compilerOptions": { "noEmit": false, "declaration": true, "emitDeclarationOnly": true } } ``` The priority from highest to lowest of final output directory of declaration files: * The configuration option [dts.distPath](/config/lib/dts.md#dtsdistpath) * The configuration option `declarationDir` in `tsconfig.json` * The configuration option [output.distPath.root](/config/rsbuild/output.md#outputdistpath) ::: tip You can refer to [lib.dts](/config/lib/dts.md) for more details about declaration files configuration. ::: --- url: /guide/advanced/static-assets.md --- # Import static assets Rslib supports import static assets, including images, fonts, audio and video. ## Assets format The following are the formats supported by Rslib 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). ## Import assets in JavaScript file In JavaScript files, you can directly import static assets with relative paths through `import`: ```tsx // Import the logo.png image in the 'src/assets' directory import logo from './assets/logo.png'; console.log(logo); // "/static/logo.[hash].png" export default = () => ; ``` Import with **alias** is also available: ```tsx import logo from '@/assets/logo.png'; console.log(logo); // "/static/logo.[hash].png" export default = () => ; ``` When the [format](/config/lib/format.md) is set to `cjs` or `esm`, Rslib treats the output as an mid-level artifact that will be consumed by other build tools again and transforms the source file into a JavaScript file and a static asset file that is emitted according to [output.distPath](/config/rsbuild/output.md#outputdistpath) by default with preserving the `import` or `require` statements for static assets. The following is an example of usage, assuming the source code is as follows: ```tsx import logo from './assets/logo.svg'; console.log(logo); ``` Based on the configuration in the [output structure](/guide/basic/output-structure.md) in the configuration file, the following outputs will be emitted: ```tsx import logo_namespaceObject from './static/svg/logo.svg'; console.log(logo_namespaceObject); ``` ```tsx import logo from './assets/logo.mjs'; console.log(logo); ``` ```tsx import logo_namespaceObject from '../static/svg/logo.svg'; export { logo_namespaceObject as default }; ``` ## Import assets in CSS file In CSS files, you can import static assets with relative paths: ```css title="src/index.css" .logo { background-image: url('./assets/logo.png'); } ``` Import with **alias** are also supported: ```css title="src/index.css" .logo { background-image: url('@/assets/logo.png'); } ``` When the [format](/config/lib/format.md) is set to `cjs` or `esm`, Rslib treats the output as an mid-level artifact that will be consumed by other build tools again and preserves relative reference paths in CSS outputs by default via setting [output.assetPrefix](/config/rsbuild/output.md#outputassetprefix) to `"auto"`. The following is an example of usage, assuming the source code is as follows: ```css .logo { background-image: url('./assets/logo.png'); } ``` The following output will be emitted: ```css .logo { background-image: url('./static/image/logo.png'); } ``` *** ### Ignore some assets imported in CSS If you need to import a static asset with an absolute path in a CSS file: ```css @font-face { font-family: DingTalk; src: url('/image/font/foo.ttf'); } ``` By default, the built-in `css-loader` in Rslib will resolve absolute paths in `url()` and look for the specified modules. If you want to skip resolving absolute paths, you can configure [`tools.cssLoader`](/config/rsbuild/tools.md#toolscssloader) to filter out the specified paths. The filtered paths are preserved as they are in the code. ```ts export default { tools: { cssLoader: { url: { filter: (url) => { if (/\/image\/font/.test(url)) { return false; } return true; }, }, }, }, }; ``` ## Inline static assets When the [format](/config/lib/format.md) is set to `cjs` or `esm`, Rslib treats the output as an mid-level artifact that will be consumed by other build tools again and sets [output.dataUriLimit](/config/rsbuild/output.md#outputdataurilimit) to `0` by default to not inline any static assets. ## Build output directory Once static assets are imported, they will automatically be output to the build output directory. You can: * Modify the filename of the outputs through [output.filename](/config/rsbuild/output.md#outputfilename). * Change the output path of the outputs through [output.distPath](/config/rsbuild/output.md#outputdistpath). ## 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 `@rslib/core` package is installed, you can reference the [preset types](/guide/basic/typescript.md#preset-types) provided by `@rslib/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 the TypeScript can correctly identify the type definition. ## Extend asset types If the built-in static assets type of Rslib does not meet your needs, you can extend the additional static assets type in the following ways. ### Use `source.assetsInclude` By using the [source.assetsInclude](/config/rsbuild/source.md#sourceassetsinclude) config, you can specify additional file types to be treated as static assets. ```ts title="rslib.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); ``` ### Use `tools.rspack` You can modify the built-in Rspack configuration and add custom static assets handling rules via [tools.rspack](/config/rsbuild/tools.md#toolsrspack). For example, to treat `*.pdf` files as assets and output them to the dist directory, you can add the following configuration: ```ts title="rslib.config.ts" export default { tools: { rspack(config, { addRules }) { addRules([ { test: /\.pdf$/, // Convert assets to separate files and keep import statements type: 'asset/resource', generator: { importMode: 'preserve', }, }, ]); }, }, }; ``` For more information about asset modules, please refer to [Rspack - Asset modules](https://rspack.dev/guide/features/asset-module). --- url: /guide/advanced/svgr-files.md --- # Import SVGR By default, Rslib treats SVG images as static assets. By adding the [@rsbuild/plugin-svgr](https://rsbuild.dev/plugins/list/plugin-svgr) plugin, Rslib supports transforming SVG to React components via [SVGR](https://react-svgr.com/). ## Quick start ### Install the plugin You can install the plugin using the following command: ### Register the plugin You can register the plugin in the `rslib.config.ts` file: ```ts title="rslib.config.ts" import { pluginSvgr } from '@rsbuild/plugin-svgr'; export default { plugins: [pluginSvgr()], }; ``` ## Examples ### Bundle mode In bundle mode, all usages supported by [@rsbuild/plugin-svgr](https://rsbuild.dev/plugins/list/plugin-svgr) are available in Rslib. The only difference is that when using an SVG file in URL form, Rslib will retain the `import` statement for the static asset in the output according to [Import static assets](/guide/advanced/static-assets.md). Here is an example of usage: ```jsx title="App.jsx" import Logo from './logo.svg?react'; export const App = () => ; ``` If the import path does not include the `?react` suffix, the SVG will be treated as a normal static asset, and the `import` statement for the static asset will be retained. `@rsbuild/plugin-svgr` also supports default imports and mixed imports: ```js import logoURL from './static/logo.svg'; console.log(logoURL); ``` `@rsbuild/plugin-svgr` also supports default import and mixed import: * Enable default import by setting [svgrOptions.exportType](https://rsbuild.dev/plugins/list/plugin-svgr#svgroptionsexporttype) to `'default'`. * Enable mixed import through the [mixedImport](https://rsbuild.dev/plugins/list/plugin-svgr#mixedimport) option to use both default and named import. ### Bundleless mode In bundleless mode, since each file undergoes code transformation independently, the import ways of `?react` and `?url` are not supported. However, the following two usage forms are supported: #### Named import `@rsbuild/plugin-svgr` supports named import of `ReactComponent` to use SVGR. You need to set [svgrOptions.exportType](https://rsbuild.dev/plugins/list/plugin-svgr#svgroptionsexporttype) to `'named'`. ```js pluginSvgr({ svgrOptions: { exportType: 'named', }, }); ``` ```jsx title="App.jsx" import { ReactComponent as Logo } from './logo.svg'; export const App = () => ; ``` All `.svg` files will be transformed into React components. At this time, you can: * Exclude files that do not need to be transformed by setting [exclude](https://rsbuild.dev/plugins/list/plugin-svgr#exclude). * Change to default export by setting [svgrOptions.exportType](https://rsbuild.dev/plugins/list/plugin-svgr#svgroptionsexporttype) to `'default'`. #### Mixed import If your library has both URL and React component import forms for SVG files, you can also use mixed import. ```ts pluginSvgr({ mixedImport: true, svgrOptions: { exportType: 'named', }, }); ``` At this time, the imported SVG file will export both the URL and the React component. ```js import logoUrl, { ReactComponent as Logo } from './logo.svg'; console.log(logoUrl); // -> string console.log(Logo); // -> React component ``` For more information, refer to the [mixedImport](https://rsbuild.dev/plugins/list/plugin-svgr#mixedimport) option. --- url: /guide/advanced/json-files.md --- # Import JSON files Rslib supports importing JSON files in code, and also supports importing [YAML](https://yaml.org/) and [TOML](https://toml.io/en/) files and converting them to JSON format. ## JSON file You can directly import JSON files in JavaScript files. :::warning In bundle mode, JSON files support both default and named import. In bundleless mode, JSON files only support named import. ::: ### Default import ```json title="example.json" { "name": "foo", "items": [1, 2] } ``` ```js title="index.js" import example from './example.json'; console.log(example.name); // 'foo'; console.log(example.items); // [1, 2]; ``` ### Named import Rslib also supports importing JSON files through named import. Here is an example, assuming the source code is as follows: ```js import { name } from './example.json'; console.log(name); // 'foo'; ``` ```json { "name": "foo", "items": [1, 2] } ``` Based on the configuration in the [output structure](/guide/basic/output-structure.md) specified in the configuration file, the following outputs will be emitted: ```tsx var example_namespaceObject = { u: 'foo', }; console.log(example_namespaceObject.u); ``` ```tsx import * as example from './example.js'; console.log(example.name); ``` ```tsx var example_namespaceObject = JSON.parse('{"name":"foo","items":[1,2]}'); var __webpack_exports__items = example_namespaceObject.items; var __webpack_exports__name = example_namespaceObject.name; export { __webpack_exports__items as items, __webpack_exports__name as name }; ``` ## YAML file [YAML](https://yaml.org/) is a data serialization language commonly used for writing configuration files. By adding the [@rsbuild/plugin-yaml](https://github.com/rspack-contrib/rsbuild-plugin-yaml) plugin, you can import `.yaml` or `.yml` files in JavaScript and they will be automatically converted to JavaScript objects. ### Register plugin You can register the plugin in the `rslib.config.ts` file: ```ts title="rslib.config.ts" import { pluginYaml } from '@rsbuild/plugin-yaml'; export default { plugins: [pluginYaml()], }; ``` ### Example ```ts import example from './example.yaml'; console.log(example.hello); // 'world'; console.log(example.foo); // { bar: 'baz' }; ``` ```yaml hello: world foo: bar: baz ``` ## TOML file [TOML](https://toml.io/) is a semantically explicit, easy-to-read configuration file format. By adding the [@rsbuild/plugin-toml](https://github.com/rspack-contrib/rsbuild-plugin-toml) plugin, you can import `.toml` files in JavaScript and it will be automatically converted to JavaScript objects. ### Register plugin You can register the plugin in the `rslib.config.ts` file: ```ts title="rslib.config.ts" import { pluginToml } from '@rsbuild/plugin-toml'; export default { plugins: [pluginToml()], }; ``` ### Example ```ts import example from './example.toml'; console.log(example.hello); // 'world'; console.log(example.foo); // { bar: 'baz' }; ``` ```toml hello = "world" [foo] bar = "baz" ``` ## Type declaration When you import YAML or TOML files in TypeScript code, please create a `src/env.d.ts` file in your project and add the corresponding type declarations. * Method 1: If the `@rslib/core` package is installed, you can reference the [preset types](/guide/basic/typescript.md#preset-types) provided by `@rslib/core`: ```ts title="src/env.d.ts" /// ``` * Method 2: Manually add the required type declarations: ```ts title="src/env.d.ts" declare module '*.yaml' { const content: Record; export default content; } declare module '*.yml' { const content: Record; export default content; } declare module '*.toml' { const content: Record; export default content; } ``` --- url: /guide/advanced/module-federation.md --- # Module Federation This chapter introduces how to build [Module Federation](/guide/basic/output-format.md#mf) output in Rslib. ## Usage scenarios Module federation has some typical usage scenarios, including: * Allows independent applications (called "Micro-Frontend" in the Micro-Frontend architecture) to share modules without having to recompile the entire application. * Different teams work on different parts of the same application without having to recompile the entire application. * Dynamic code loading and sharing between applications at runtime. Module Federation can help you: * Reduce code duplication * Improve code maintainability * Reduce the overall size of the application * Improve application performance ## Quick start First install the [Module Federation Rsbuild Plugin](https://www.npmjs.com/package/@module-federation/rsbuild-plugin). Then register the plugin in the `rslib.config.ts` file: ```ts title='rslib.config.ts' {8-43} import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; export default defineConfig({ lib: [ // ... other format { format: 'mf', output: { distPath: { root: './dist/mf', }, // for production, add online assetPrefix here assetPrefix: 'http://localhost:3001/mf', }, // for Storybook to dev dev: { assetPrefix: 'http://localhost:3001/mf', }, plugins: [ pluginModuleFederation({ name: 'rslib_provider', exposes: { // add expose here }, // can not add 'remote' here, because you may build 'esm' or 'cjs' assets in one build. // if you want the Rslib package use remote module, please see below. shared: { react: { singleton: true, }, 'react-dom': { singleton: true, }, }, }), ], }, ], // for Storybook to dev server: { port: 3001, }, output: { target: 'web', }, plugins: [pluginReact()], }); ``` In this way, we have completed the integration of Rslib Module as a producer. After the construction is completed, we can see that the mf directory has been added to the product, and consumers can directly consume this package. In the above example we added a new `format: 'mf'` , which will help you add an additional Module Federation product, while also configuring the format of `cjs` and `esm` , which does not conflict. However, if you want this Rslib Module to consume other producers at the same time, do not use the build configuration `remote` parameter, because in other formats, this may cause errors, please refer to the example below using the Module Federation runtime ## Develop MF remote module ### Use host app Rslib support developing Module Federation Rslib project with a host application. #### 1. Start `rslib mf-dev` command of library Adding the `dev` command to the `package.json` file: ```json title="package.json" { "scripts": { "dev": "rslib mf-dev" } } ``` Then run the `dev` command can start the Module Federation development mode, enabling consumption by your host app, along with Hot Module Replacement (HMR). #### 2. Start host app Set up the host app to consume the Rslib Module Federation library. Check out the [@module-federation/rsbuild-plugin ](https://www.npmjs.com/package/@module-federation/rsbuild-plugin) for more information. ```ts title="rsbuild.config.ts" {8-24} import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; import { defineConfig } from '@rsbuild/core'; import { pluginReact } from '@rsbuild/plugin-react'; export default defineConfig({ plugins: [ pluginReact(), pluginModuleFederation({ name: 'rsbuild_host', remotes: { rslib: 'rslib@http://localhost:3001/mf/mf-manifest.json', }, shared: { react: { singleton: true, }, 'react-dom': { singleton: true, }, }, // Enable this when the output of Rslib is build under 'production' mode, while the host app is 'development'. // Reference: https://lib.rsbuild.dev/guide/advanced/module-federation#faqs shareStrategy: 'loaded-first', }), ], }); ``` Then start the host app with `rsbuild dev`. ### Use Storybook Rslib support developing Module Federation Rslib project with Storybook. #### 1. Start `rslib mf-dev` command of library Adding the `dev` command to the `package.json` file: ```json title="package.json" { "scripts": { "dev": "rslib mf-dev" } } ``` Then run the `dev` command can start the Module Federation development mode, enabling consumption by Storybook, along with Hot Module Replacement (HMR). #### 2. Set up Storybook configuration First, set up Storybook with the Rslib project. You can refer to the [Storybook chapter](/guide/advanced/storybook.md) to learn how to do this. In this chapter, we will use React as the framework for our example. 1. Install the following Storybook addons to let Storybook work with Rslib Module Federation: * [storybook-addon-rslib](https://www.npmjs.com/package/storybook-addon-rslib): Storybook addon that let Storybook to load the Rslib config. * [@module-federation/storybook-addon](https://www.npmjs.com/package/@module-federation/rsbuild-plugin): Storybook addon that set up the Module Federation config for Storybook. 2. Then set up the Storybook configuration file `.storybook/main.ts`, specify the stories and addons, and set the framework with corresponding framework integration. ```ts title=".storybook/main.ts" {18-38} import { dirname, join } from 'node:path'; import type { StorybookConfig } from 'storybook-react-rsbuild'; function getAbsolutePath(value: string): any { return dirname(require.resolve(join(value, 'package.json'))); } const config: StorybookConfig = { stories: [ '../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', ], framework: { name: getAbsolutePath('storybook-react-rsbuild'), options: {}, }, addons: [ { name: getAbsolutePath('storybook-addon-rslib'), options: { rslib: { include: ['**/stories/**'], }, }, }, { name: '@module-federation/storybook-addon/preset', options: { // add your rslib module manifest here for storybook dev // we have set dev.assetPrefix and server.port to 3001 in rslib.config.ts above remotes: { 'rslib-module': // you can also add shared here for storybook app // shared: {} 'rslib-module@http://localhost:3001/mf/mf-manifest.json', }, }, }, ], }; export default config; ``` #### 3. Writing stories with remote module Import components from remote module. ```ts title="stories/index.stories.tsx" {2-3} import React from 'react'; // Load your remote module here, Storybook will act as the host app. import { Counter } from 'rslib-module'; const Component = () => ; export default { title: 'App Component', component: Component, }; export const Primary = {}; ``` #### 4. Add Module Federation types and stories into `tsconfig.json`. ```json title="tsconfig.json" { "compilerOptions": { // ... "paths": { "*": ["./@mf-types/*"] } }, "include": ["src/**/*", ".storybook/**/*", "stories/**/*"] } ``` #### 5. Start Storybook app There you go, start Storybook with `npx storybook dev`. ## Consume other Module Federation modules Because there are multiple formats in Rslib, if you configure the `remote` parameter to consume other modules during construction, it may not work properly in all formats. It is recommended to access through the [Module Federation Runtime](https://module-federation.io/guide/basic/runtime.html) First install the runtime dependencies Then consume other Module Federation modules at runtime, for example ```ts import { init, loadRemote } from '@module-federation/enhanced/runtime'; import { Suspense, createElement, lazy } from 'react'; init({ name: 'rslib_provider', remotes: [ { name: 'mf_remote', entry: 'http://localhost:3002/mf-manifest.json', }, ], }); export const Counter: React.FC = () => { return (
loading
}> {createElement( lazy( () => loadRemote('mf_remote') as Promise<{ default: React.FC; }>, ), )} ); }; ``` This ensures that modules can be loaded as expected in multiple formats. ## FAQs If the Rslib producer is built with build, this means that the `process.env.NODE_ENV` of the producer is `production` . If the consumer is started in dev mode at this time, due to the shared loading strategy of Module Federation being `version-first` by default, there may be problems loading into different modes of react and react-dom (e.g. react in development mode, react-dom in production mode). You can set up [shareStrategy](https://module-federation.io/configure/sharestrategy) at the consumer to solve this problem, but make sure you fully understand this configuration ```ts pluginModuleFederation({ // ... shareStrategy: 'loaded-first', }), ``` ## Examples [Rslib Module Federation Example](https://github.com/web-infra-dev/rslib/tree/main/examples/module-federation) * `mf-host`: Rsbuild App Consumer * `mf-react-component`: Rslib Module, which is both a producer and a consumer, provides the module to the `mf-host` as a producer, and consumes the `mf-remote` * `mf-remote`: Rsbuild App Producer [Rslib Module Federation Storybook Example](https://github.com/web-infra-dev/rslib/tree/main/examples/module-federation/mf-react-component) --- url: /guide/advanced/storybook.md --- # Use Storybook [Storybook](https://storybook.js.org/) is a powerful tool for developing UI components in isolation for React, Vue, and other frameworks. It enables you to build and test components independently, which can accelerate both development and testing. [storybook-rsbuild](https://github.com/rspack-contrib/storybook-rsbuild) is the Rsbuild powered Storybook builder, and provided the framework integration for React, Vue3 and vanilla JavaScript. The coherent Rsbuild system could make Storybook use an unified configuration with Rslib. :::tip You can create a new project with Storybook by using [create-rslib](/guide/start/quick-start.md#creating-an-rslib-project). ::: ## Getting started ### Setup a Rslib project This is the prerequisite for setting up Storybook. You need to have a Rslib project with components that you want to showcase in Storybook, check out [Solution](/guide/solution/index.md) to setup a Rslib project. ### Add Storybook to project Set up a Storybook project with an existing Rslib project. To use React, Vue 3, vanilla JavaScript, or other frameworks, you must first install the appropriate Storybook framework package. For installation instructions, refer to the [Storybook Rsbuild documentation](https://storybook.rsbuild.dev/guide/framework.html). Using React as an example, at this step you need to: 1. Install the dependencies for Storybook Rsbuild React framework. The essential ones include * [storybook](https://www.npmjs.com/package/storybook): The Storybook core. * [@storybook/addon-essentials](https://www.npmjs.com/package/@storybook/addon-essentials): a curated collection of addons to bring out the best of Storybook. * [@rsbuild/core](https://www.npmjs.com/package/@rsbuild/core): Storybook builder. * [storybook-addon-rslib](https://www.npmjs.com/package/storybook-addon-rslib): This addon will make Storybook Rsbuild could derive Rsbuild configuration from Rslib config file. The addon will automatically read the Rslib configuration and apply it to Storybook Rsbuild, ensuring that the configuration is unified. You can check the [storybook-addon-rslib](https://storybook.rsbuild.dev/guide/integrations/rslib.html) documentation for available options. The dependencies varies for each framework, please refer to the [Storybook Rsbuild documentation](https://storybook.rsbuild.dev/guide/framework.html) for details. In this React example, we will install [storybook-react-rsbuild](https://www.npmjs.com/package/storybook-react-rsbuild) as the framework integration. 2. Configure the Storybook configuration file `.storybook/main.js`, specify the stories and addons, and set the framework with corresponding framework integration. ```js title=".storybook/main.js" export default { stories: [ '../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', ], addons: ['@storybook/addon-essentials', 'storybook-addon-rslib'], framework: 'storybook-react-rsbuild', // storybook-react-rsbuild for example }; ``` 3. Add a simple story to the `stories` directory. For example, create a `Button.stories.js` file with the following content: ```js title="stories/Button.stories.js" import { Button } from '../src/Button'; const meta = { title: 'Example/Button', component: Button, }; export default meta; export const Primary = { args: { primary: true, label: 'Button', }, }; ``` :::tip In case you are using [Yarn Plug-n-Play](https://yarnpkg.com/features/pnp) or your project is set up within a mono repository environment, you might run into issues with module resolution. In such cases, you can add an `getAbsolutePath('storybook-addon-rslib')` function to resolve the addon. Check the [Storybook's FAQ](https://storybook.js.org/docs/faq#how-do-i-fix-module-resolution-in-special-environments) for more information. ::: There you go, you could start and build the Storybook server with the following command: ```bash npx storybook dev // development mode npx storybook build // build static files ``` Check out more details in the [Storybook Rsbuild documentation](https://storybook.rsbuild.dev/) and the [Storybook documentation](https://storybook.js.org/docs/react/get-started/introduction). ## Example * [React component library + Rslib + Storybook](https://github.com/rspack-contrib/storybook-rsbuild/tree/main/sandboxes/rslib-react-component) --- url: /guide/migration/modernjs-module.md --- # Modern.js Module This section introduces how to migrate a project using Modern.js Module to Rslib. ## Adapt package.json `Rslib` has a minimal dependency footprint. For the basic functionality you only need the package `@rslib/core`. You can create a new Rslib project by following the [Quick Start](/guide/start/quick-start.md) to see the `package.json` file. Then update your existing `package.json` file like below: * Remove the fields `main`, `lint-staged`, `simple-git-hooks`, `sideEffects` and `publishConfig` * Change the `types` field from `./dist/types/index.d.ts` to `./dist/index.d.ts` * Change the `module` field from `./dist/es/index.js` to `./dist/index.js` * Remove the scripts fields `prepare`, `build:watch`, `reset`, `change`, `bump`, `pre`, `change-status`, `gen-release-note`, `release`, `new`, `upgrade` * Change the script `build` from `modern build` to `rslib build` * Change the script `dev` from `modern dev` to `rslib build --watch` * Change the script `lint` name to `check` and keep the value * Add a new script `format` with the value `biome format --write` * Add the script `test` with the value `vitest run` * Add the field `exports` (object) * Add the field `"."` (object) * Add the fields `"types": "./dist/index.d.ts"` and `"import": "./dist/index.js"` * Add the field `files` with the value `["dist"]` * Depending on your configuration and use-case the `devDependencies` can vary * It is important to replace `@modern-js/module-tools` with `@rslib/core` * We do not need `rimraf`, `lint-staged` and `simple-git-hooks` anymore for starters * Copy over your required `dependencies` and `peerDependencies` if needed Your `package.json` should look something like this: ```json title="package.json" { "name": "rslib", "version": "1.0.0", "type": "module", "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } }, "module": "./dist/index.js", "types": "./dist/index.d.ts", "files": ["dist"], "scripts": { "build": "rslib build", "check": "biome check --write", "dev": "rslib build --watch", "format": "biome format --write", "test": "vitest run" }, "devDependencies": { "@biomejs/biome": "^1.9.3", "@rslib/core": "^0.1.3", "typescript": "^5.6.3", "vitest": "^2.1.8" }, "peerDependencies": {}, "dependencies": {} } ``` ## Adapt bundler config Now we have a clean slate to work with. We will continue with the `Rslib` configuration. It follows the same pattern as all `Rs*` projects. Since this step is very unique for every environment, below is an basic example: Replace your `modern.config.ts` with a `rslib.config.ts`: ```js title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({ source: { entry: { index: ['./src/**'], }, }, lib: [ { bundle: false, dts: true, format: 'esm', }, ], }); ``` ## TypeScript declaration If you use TypeScript in your `Modern.js Module` and need to generate declaration files, add the following changes: ```js title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({ //... lib: [ { //... dts: true, }, ], }); ``` ## React If you use React in your `Modern.js Module`, add the following changes: ```js title="rslib.config.ts" import { defineConfig } from '@rslib/core'; // Quick tip: You can use all Rsbuild plugins here since they are compatible with Rslib import { pluginReact } from '@rsbuild/plugin-react'; export default defineConfig({ //... output: { target: 'web', }, plugins: [pluginReact()], }); ``` In addition, you have to install the `@rsbuild/plugin-react` package as `devDependencies`. ## Sass If you use Sass in your `Modern.js Module`, add the following changes: ```js title="rslib.config.ts" import { defineConfig } from '@rslib/core'; // Quick tip: You can use all Rsbuild plugins here since they are compatible with Rslib import { pluginSass } from '@rsbuild/plugin-sass'; export default defineConfig({ //... plugins: [pluginSass()], }); ``` In addition, you have to install the `@rsbuild/plugin-sass` package as `devDependencies`. If you run TypeScript together with Sass, you might run into declaration files generation errors. This can be resolved by adding a `env.d.ts` file in your `/src` directory. ```ts title="src/env.d.ts" declare module '*.scss' { const content: { [className: string]: string }; export default content; } ``` or ```ts title="src/env.d.ts" /// ``` ## CSS Modules If you use CSS Modules in your `Modern.js Module`, add the following changes: ```js title="rslib.config.ts" import { defineConfig } from '@rslib/core'; import { pluginSass } from '@rsbuild/plugin-sass'; export default defineConfig({ lib: [ { //... output: { cssModules: { // the CSS Modules options are 1:1 the same as in the official "css-modules" package localIdentName: '[local]--[hash:base64:5]', }, }, }, ], plugins: [pluginSass()], }); ``` ## Contents supplement This migration doc is contributed by community user [YanPes](https://github.com/YanPes). Much appreciation for his contribution! Rslib is designed to be the next generation solution of Modern.js Module, and we will provide detailed configuration mapping documentation as well as feature migration guides and scripts in the second quarter of 2025. --- url: /guide/migration/tsup.md --- # tsup This section introduces how to migrate a project using tsup to Rslib. ## Installing dependencies First, you need to replace the npm dependencies of tsup with Rslib's dependencies. * Remove tsup: - Install Rslib: ## Updating npm scripts Next, you need to update the npm scripts in your package.json to use Rslib's CLI commands. ```diff title="package.json" { "scripts": { - "build": "tsup", - "build:watch": "tsup --watch", + "build": "rslib build", + "build:watch": "rslib build --watch" } } ``` ## Create configuration file Create a Rslib configuration file `rslib.config.ts` in the same directory as `package.json`, and add the following content: ```ts title="rslib.config.ts" import { defineConfig } from '@rslib/core'; export default defineConfig({}); ``` ## Configuration migration Here is the corresponding Rslib configuration for tsup configuration: | tsup | Rslib | | ------------- | ---------------------------------------------------------------------------------------------------------- | | banner | [lib.banner](/config/lib/banner.md) | | bundle | [lib.bundle](/config/lib/bundle.md) | | clean | [output.cleanDistPath](/config/rsbuild/output.md#outputcleandistpath) | | define | [source.define](/config/rsbuild/source.md#sourcedefine) | | dts | [lib.dts](/config/lib/dts.md) | | entry | [source.entry](/config/rsbuild/source.md#sourceentry) | | external | [output.externals](/config/rsbuild/output.md#outputexternals) / [lib.autoExternal](/config/lib/auto-external.md) | | format | [lib.format](/config/lib/format.md) | | footer | [lib.footer](/config/lib/footer.md) | | minify | [output.minify](/config/rsbuild/output.md#outputminify) | | platform | [output.target](/config/rsbuild/output.md#outputtarget) | | plugins | [plugins](/config/rsbuild/plugins.md) | | sourcemap | [output.sourceMap](/config/rsbuild/output.md#outputsourcemap) | | shims | [lib.shims](/config/lib/shims.md) | | terserOptions | [output.minify](/config/rsbuild/output.md#outputminify) | | tsconfig | [source.tsconfigPath](/config/rsbuild/source.md#sourcetsconfigpath) | ## Contents supplement The current document only covers part of the migration process. If you find suitable content to add, feel free to contribute to the documentation via pull request 🤝. > The documentation for Rslib can be found in the [rslib/website](https://github.com/web-infra-dev/rslib/tree/main/website) directory. --- url: /guide/faq/features.md --- # Features FAQ ## Style processing ### How to skip the preprocessing of Less / Sass files in bundleless mode? Bundleless means that each source file is compiled and built separately, which can be understood as the process of code transformation of source files only. To skip the preprocessing of `.less/.scss` files, you need to: 1. Set `source.entry` to remove `.less/.scss` files from the entry. 2. Set `output.copy` to copy `.less/.scss` files to the output directory. 3. Set `redirect.style.extension` to `false` to disable the redirect behavior for the import path of `.less/.scss` files. Below is an example of skipping the `.scss` file processing. All `.scss` files in `src` will be copied to the output directory and retained with consistent relative paths. ```ts title="rslib.config.ts" export default defineConfig({ lib: [ { // ... source: { entry: { index: ['./src/**', '!src/**/*.scss'], }, }, output: { copy: [{ from: '**/*.scss', context: path.join(__dirname, 'src') }], }, redirect: { style: { extension: false, }, }, }, ], }); ``` ## Code minification ### How to preserve all comments in the output files? By default, Rslib uses SWC to remove comments. The corresponding SWC [jsc.minify.format](https://swc.rs/docs/configuration/minification#jscminifyformat) configuration is ```js { comments: 'some', preserveAnnotations: true, } ``` This will only preserve some legal comments and annotations. If you want to preserve all comments, you can refer to the following configuration ```ts title="rslib.config.ts" export default { lib: [ // ... ], output: { minify: { jsOptions: { minimizerOptions: { format: { comments: 'all', // This will preserve all comments }, }, }, }, }, }; ``` ### How to compress the output size while preserving code readability? Compressing code can reduce the output size and improve loading speed, but the compressed code is less readable and harder to debug. If you want to preserve code readability, you can keep variable names and disable compression to facilitate debugging. Refer to [web-infra-dev/rsbuild#966](https://github.com/web-infra-dev/rsbuild/pull/3966). ```ts title="rslib.config.ts" export default { lib: [ // ... ], output: { minify: { jsOptions: { minimizerOptions: { // preserve variable name and disable minify for easier debugging mangle: false, minify: false, compress: true, }, }, }, }, }; ``` ## Declaration files generation ### How to additionally exclude specified dependencies when `dts.bundle` is `true`? Rslib uses [rsbuild-plugin-dts](https://github.com/web-infra-dev/rslib/blob/main/packages/plugin-dts/README.md) to generate declaration files, which supports configuration via [output.externals](/config/rsbuild/output.md#outputtarget) for excluding certain dependencies from bundled declaration files. For example, a typical React component library often does not declare `@types/react` in `peerDependencies` but only in `devDependencies`. Following the [autoExternal](/config/lib/auto-external.md) logic for dependency handling, Rslib will attempt to bundle `@types/react` into the declaration output files during the build. However, in practice, a component library should not bundle `@types/react`. In this scenario, you can configure [output.externals](/config/rsbuild/output.md#outputtarget) to exclude `@types/react`. ```ts title="rslib.config.ts" export default { lib: [ // ... ], output: { externals: ['@types/react'], }, }; ``` --- url: /config/index.md --- This page lists all the configurations for Rslib. See [Configure Rslib](/guide/basic/configure-rslib.md) for detail. --- url: /config/lib/index.md --- # Lib configurations * **Type:** ```ts interface LibConfig extends EnvironmentConfig { format?: Format; bundle?: boolean; autoExtension?: boolean; autoExternal?: AutoExternal; redirect?: Redirect; syntax?: Syntax; externalHelpers?: boolean; banner?: BannerAndFooter; footer?: BannerAndFooter; shims?: Shims; dts?: Dts; umdName?: string; } interface RslibConfig extends RsbuildConfig { lib: LibConfig[]; } ``` * **Default:** `undefined` * **Required:** `true` The `lib` configuration is an array of objects, each representing a distinct set of configurations. These include all Rsbuild configurations as well as Rslib-specific configurations, designed to generate different outputs. --- url: /config/lib/format.md --- # lib.format * **Type:** `'esm' | 'cjs' | 'umd' | 'mf'` * **Default:** `undefined` * **Required**: true Specify the output format for the generated JavaScript output files. For different output formats, Rslib uses the following default value of [output.library.type](https://rspack.dev/config/output#outputlibrarytype) provided by Rspack: * `esm`:[modern-module](https://rspack.dev/config/output#type-modern-module) * `cjs`:[commonjs-static](https://rspack.dev/config/output#type-commonjs-static) * `umd`:[umd](https://rspack.dev/config/output#type-umd) See [Output Format](/guide/basic/output-format.md) and [Module Federation](/guide/advanced/module-federation.md) for more details. ::: note The `umd` format only works when [bundle](/config/lib/bundle.md) is set to `true`. ::: --- url: /config/lib/bundle.md --- # lib.bundle * **Type:** `boolean` * **Default:** `true` Specify whether to bundle the library, which is known as bundle mode when `bundle` is set to `true`, and bundleless mode when set to `false`. See [bundle / bundleless](/guide/basic/output-structure.md#bundle--bundleless) for more details. ## Set entry We should specify the entry file for the build. ### bundle: true When `bundle` is set to `true`, the entry should be set to the entry file. The default entry in bundle mode is `src/index.(ts|js|tsx|jsx|mjs|cjs)`. You should make sure that the entry file exists, or customize entry through the [source.entry](https://rsbuild.dev/config/source/entry) configuration. **Example:** ```ts title="rslib.config.ts" export default { lib: [ { format: 'cjs', bundle: true, }, ], source: { entry: { index: './foo/index.ts', }, }, }; ``` ### bundle: false When `bundle` is set to `false`, the entry should be set to a [glob pattern](https://github.com/micromatch/picomatch#globbing-features) to include all the files. The default entry in bundleless mode is `src/**`. **Example:** ```ts title="rslib.config.ts" export default { lib: [ { format: 'cjs', bundle: false, }, ], source: { entry: { index: './foo/**', }, }, }; ``` You can also use with an exclamation mark to exclude some files. For example, exclude test files within the `src` folder: ```ts title="rslib.config.ts" export default { lib: [ { format: 'cjs', bundle: false, }, ], source: { entry: { index: ['./src/**', '!src/**/*.test.ts'], }, }, }; ``` ::: note If [declaration files generation](/config/lib/dts.md) is enabled, remember to set [exclude](https://www.typescriptlang.org/tsconfig/#exclude) field in `tsconfig.json` to avoid generating TypeScript declaration files for the corresponding files. For example, exclude test files within the `src` folder: ```json // tsconfig.json { "include": ["src"], "exclude": ["src/**/*.test.ts"] } ``` ::: ## Example For below file structure of source code: ``` . ├── src │ ├── index.ts │ ├── foo.ts │ └── bar.ts └── package.json ``` ### bundle: true ```ts title="rslib.config.ts" export default defineConfig({ lib: [ { format: 'cjs', bundle: true, }, ], }); ``` When `bundle` is set to `true`, as known as bundle mode, Rslib will bundle the library into a single file. ```diff . + ├── dist + │ └── index.js ├── src │ ├── index.ts │ ├── foo.ts │ └── bar.ts └── package.json ``` ### bundle: false ```ts title="rslib.config.ts" export default defineConfig({ lib: [ { format: 'cjs', bundle: false, }, ], source: { entry: { index: ['./src/**'], }, }, }); ``` When `bundle` is set to `false`, as known as bundleless mode, Rslib will transform the code into multiple files. ```diff . + ├── dist + │ ├── index.js + │ ├── foo.js + │ └── bar.js ├── src │ ├── index.ts │ ├── foo.ts │ └── bar.ts └── package.json ``` --- url: /config/lib/auto-extension.md --- # lib.autoExtension * **Type:** `boolean` * **Default:** `true` Whether to automatically set the file extension based on the [`format`](/config/lib/format.md) option in the JavaScript output files. ## Default extension By default that when `autoExtension` is set to `true`, the file extension will be: * `.js` with `esm` format and `.cjs` with `cjs` format when `type: module` in `package.json`. * `.js` with `cjs` format and `.mjs` with `esm` format when `type: commonjs` or no `type` field in `package.json`. When `autoExtension` is set to `false`, the file extension will be default to `.js`. ## Customize extension You can set `autoExtension` to `false` and use [output.filename](https://rsbuild.dev/config/output/filename) to customize the JavaScript output files. ```ts title="rslib.config.ts" export default defineConfig({ lib: [ { format: 'cjs', autoExtension: false, output: { filename: { js: '[name].cjs', }, }, }, { format: 'esm', output: { filename: { js: '[name].mjs', }, }, }, ], }); ``` --- url: /config/lib/auto-external.md --- # lib.autoExternal :::info `autoExternal` is a specific configuration for bundle mode. It will not take effect in bundleless mode (set [lib.bundle](/config/lib/bundle.md) to `false`) since deps will not be bundled in bundleless mode. ::: * **Type:** ```ts type AutoExternal = | boolean | { dependencies?: boolean; optionalDependencies?: boolean; devDependencies?: boolean; peerDependencies?: boolean; }; ``` * **Default:** * `true` when [format](/config/lib/format.md) is `cjs` or `esm` * `false` when [format](/config/lib/format.md) is `umd` or `mf` Whether to automatically externalize dependencies of different dependency types and do not bundle them. ## Object type ### autoExternal.dependencies * **Type:** `boolean` * **Default:** `true` Whether to automatically externalize dependencies of type `dependencies`. ### autoExternal.optionalDependencies * **Type:** `boolean` * **Default:** `true` Whether to automatically externalize dependencies of type `optionalDependencies`. ### autoExternal.peerDependencies * **Type:** `boolean` * **Default:** `true` Whether to automatically externalize dependencies of type `peerDependencies`. ### autoExternal.devDependencies * **Type:** `boolean` * **Default:** `false` Whether to automatically externalize dependencies of type `devDependencies`. ## Default value The default value of `autoExternal` is `true`, which means the following dependency types will **not be bundled**: * `dependencies` * `optionalDependencies` * `peerDependencies` And the following dependency types will be **bundled**: * `devDependencies` This configuration is equivalent to the following object type: ```ts export default { lib: [ { format: 'esm', autoExternal: { dependencies: true, optionalDependencies: true, peerDependencies: true, devDependencies: false, }, }, ], }; ``` ## Example ### Customize externalized dependency types To disable the processing of a specific type of dependency, you can configure `autoExternal` as an object like this: ```ts title="rslib.config.ts" export default { lib: [ { format: 'esm', autoExternal: { dependencies: false, peerDependencies: false, }, }, ], }; ``` ### Disable default behavior If you want to disable the default behavior, you can set `autoExternal` to `false`: ```ts title="rslib.config.ts" export default { lib: [ { format: 'esm', autoExternal: false, }, ], }; ``` For more details about handling third-party dependencies, please refer to [Handle Third-party Dependencies](/guide/advanced/third-party-deps.md). --- url: /config/lib/redirect.md --- # lib.redirect :::info `redirect` is the unique configuration for [bundleless mode](/guide/basic/output-structure.md#bundle--bundleless). It will not take effect in bundle mode where all output files are bundled into a single file, eliminating the need for import path redirection. ::: * **Type:** ```ts type JsRedirect = { path?: boolean; extension?: boolean; }; type StyleRedirect = { path?: boolean; extension?: boolean; }; type DtsRedirect = { path?: boolean; extension?: boolean; }; type Redirect = { js?: JsRedirect; style?: StyleRedirect; asset?: boolean; dts?: DtsRedirect; }; ``` * **Default:** ```ts const defaultRedirect = { js: { path: true, extension: true, }, style: { path: true, extension: true, }, asset: true, dts: { path: true, extension: false, }, }; ``` Configure the redirect for import paths in output files. In bundleless mode, there are often needs such as using aliases or automatically appending suffixes for ESM outputs. The `redirect` configuration is designed to address these issues. ## redirect.js Controls the redirect of the import paths of output JavaScript files. :::warning When [output.externals](/config/rsbuild/output.md#outputexternals) is configured and a request is matched, neither `redirect.js.path` nor `redirect.js.extension` will take effect, and the final rewritten request path will be entirely controlled by [output.externals](/config/rsbuild/output.md#outputexternals). ::: ### redirect.js.path Whether to automatically redirect the import paths of JavaScript output files. * **Type:** `boolean` * **Default:** `true` When set to `true`, [resolve.alias](/config/rsbuild/resolve.md#resolvealias) and [resolve.aliasStrategy](/config/rsbuild/resolve.md#aliasstrategy) will take effect and applied in the rewritten import path of the output file. For TypeScript projects, just configure [compilerOptions.paths](https://typescriptlang.org/tsconfig#paths) in the `tsconfig.json` file. When set to `false`, the import path will not be effected by [resolve.alias](/config/rsbuild/resolve.md#resolvealias), [resolve.aliasStrategy](/config/rsbuild/resolve.md#aliasstrategy) and `tsconfig.json`. * **Example:** When set `compilerOptions.paths` to `{ "@/*": ["src/*"] }` in `tsconfig.json`, the output file will be redirected to the correct relative path: ```ts import { foo } from '@/foo'; // source code of './src/bar.ts' ↓ import { foo } from './foo.js'; // expected output of './dist/bar.js' import { foo } from '@/foo'; // source code of './src/utils/index.ts' ↓ import { foo } from '../foo.js'; // expected output './dist/utils/index.js' ``` ### redirect.js.extension Whether to automatically redirect the file extension to import paths based on the JavaScript output files. * **Type:** `boolean` * **Default:** `true` When set to `true`, the file extension will automatically be added to the rewritten import path of the output file, regardless of the original extension or whether it is specified in the import path. When set to `false`, the file extension will remain unchanged from the original import path in the rewritten import path of the output file (regardless of whether it is specified or specified as any value). :::note The extension of the JavaScript output file is related to the [autoExtension](/config/lib/auto-extension.md#libautoextension) configuration. ::: * **Example:** For ESM outputs running in Node.js, the full extension to the module import path must be specified to load correctly. Rslib will automatically add corresponding file extensions based on the actual output JavaScript file. ```ts import { foo } from './foo'; // source code of './src/bar.ts' ↓ import { foo } from './foo.mjs'; // expected output of './dist/bar.mjs' import { foo } from './foo.ts'; // source code of './src/utils/index.ts' ↓ import { foo } from './foo.mjs'; // expected output './dist/utils/index.mjs' ``` ## redirect.style Controls the redirect of the import paths of output style files. ### redirect.style.path Whether to automatically redirect the import paths of style output files. * **Type:** `boolean` * **Default:** `true` When set to `true`, the relevant redirect rules are the same as [redirect.js.path](/config/lib/redirect.md#redirectjspath). When set to `false`, the original import path will remain unchanged. * **Example:** When importing normal style files: ```ts import '@/foo.css'; // source code of './src/bar.ts' ↓ import './foo.css'; // expected output of './dist/bar.js' import '@/foo.css'; // source code of './src/utils/index.ts' ↓ import '../foo.css'; // expected output of './dist/utils/index.js' ``` When importing [CSS Modules](/config/rsbuild/output.md#outputcssmodules) files: ```ts import styles from '@/foo.css'; // source code of './src/bar.ts' ↓ import styles from './foo.css'; // expected output of './dist/bar.js' import styles from '@/foo.css'; // source code of './src/utils/index.ts' ↓ import styles from '../foo.css'; // expected output of './dist/utils/index.js' ``` ### redirect.style.extension Whether to automatically redirect the file extension to import paths based on the style output files. * **Type:** `boolean` * **Default:** `true` When set to `true`: * When importing a normal style file, the path will be rewritten to `.css`. * When importing [CSS Modules](/config/rsbuild/output.md#outputcssmodules), the path will be rewritten to the corresponding JavaScript output file. When set to `false`, the file extension will remain unchanged from the original import path. * **Example:** When importing from a `.less` file: ```ts import './index.less'; // source code ↓ import './index.css'; // expected output import styles from './index.module.less'; // source code ↓ import styles from './index.module.mjs'; // expected output ``` ## redirect.asset Controls the redirect of the import paths of output asset files. * **Type:** `boolean` * **Default:** `true` When set to `true`, the paths of imported asset files will be redirected to the corresponding JavaScript output file. When set to `false`, the file extension will remain unchanged from the original import path. * **Example:** ```ts import url from './assets/logo.svg'; // source code ↓ import url from './assets/logo.mjs'; // expected output ``` ## redirect.dts Controls the redirect of the import paths of output TypeScript declaration files. ### redirect.dts.path Whether to automatically redirect the import paths of TypeScript declaration output files. * **Type:** `boolean` * **Default:** `true` When set to `true`, Rslib will redirect the import path in the declaration output file to the corresponding relative path based on the [compilerOptions.paths](https://typescriptlang.org/tsconfig#paths) configured in `tsconfig.json`. When set to `false`, the original import path will remain unchanged. * **Example:** When `compilerOptions.paths` is set to `{ "@/*": ["src/*"] }` in `tsconfig.json`, the declaration output file will be redirected to the correct relative path: ```ts import { foo } from '@/foo'; // source code of './src/bar.ts' ↓ import { foo } from './foo'; // expected output of './dist/bar.d.ts' import { foo } from '@/foo'; // source code of './src/utils/index.ts' ↓ import { foo } from '../foo'; // expected output './dist/utils/index.d.ts' ``` ### redirect.dts.extension Whether to automatically redirect the file extension to import paths based on the TypeScript declaration output files. * **Type:** `boolean` * **Default:** `false` When set to `true`, the import paths in declaration files will be redirected to the corresponding JavaScript extension which can be resolved to corresponding declaration file. When set to `false`, the file extension will remain unchanged from the original import path in the rewritten import path of the output file (regardless of whether it is specified or specified as any value). :::note The extension of the TypeScript declaration file is related to the [dts.autoExtension](/config/lib/dts.md#dtsautoextension) configuration. ::: * **Example:** For the `.d.mts` declaration file, in some scenarios, the full extension of the module import path is needed to load correctly. ```ts import { foo } from './foo'; // source code of './src/bar.ts' ↓ import { foo } from './foo.mjs'; // expected output of './dist/bar.d.mts' import { foo } from './foo.ts'; // source code of './src/bar.ts' ↓ import { foo } from './foo.mjs'; // expected output of './dist/bar.d.mts' ``` --- url: /config/lib/syntax.md --- # lib.syntax * **Type:** ```ts type EcmaScriptVersion = | 'es5' | 'es6' | 'es2015' | 'es2016' | 'es2017' | 'es2018' | 'es2019' | 'es2020' | 'es2021' | 'es2022' | 'es2023' | 'es2024' | 'esnext'; type Syntax = EcmaScriptVersion | string[]; ``` * **Default:** `'esnext'` Configure the syntax to which JavaScript and CSS will be downgraded. See [Output Compatibility - Syntax Downgrade](/guide/advanced/output-compatibility.md) for more details. ## Set ECMAScript version You can set the ECMAScript version directly, such as `es2015`, `es2022`, etc. ```ts title="rslib.config.ts" export default { lib: [ { syntax: 'es2015', }, ], }; ``` ## Set browserslist query You can also set the [Browserslist query](https://browsersl.ist/), such as `last 2 versions`, `> 1%`, `node >= 16`, `chrome >= 80`, etc. ```ts title="rslib.config.ts" export default { lib: [ { syntax: ['last 2 versions', '> 1%'], }, ], }; ``` ## Mix ECMAScript version and browserslist query You can also mix ECMAScript version and Browserslist query, such as `es2015` and `node 20`. Rslib will turn ECMAScript Version into Browserslist query, and then merge them together. ```ts title="rslib.config.ts" export default { lib: [ { syntax: ['es2015', 'node 20'], }, ], }; ``` --- url: /config/lib/external-helpers.md --- # lib.externalHelpers * **Type:** `boolean` * **Default:** `false` Whether to import SWC helper functions from [@swc/helpers](https://www.npmjs.com/package/@swc/helpers) instead of inlining them. By default, the output JavaScript file may depend on helper functions to support the target environment or output format, and these helper functions will be inlined in the file that requires it. When `externalHelpers` set to `true`, the output JavaScript will import helper functions from the external module `@swc/helpers`. This helps reduce duplicate helper code in the final bundles, and reduces the bundle size. ::: note Make sure to declare and install `@swc/helpers` in `dependencies` field of `package.json`. ::: ## Example Take the following code as an example: ```ts title="index.ts" export default class FOO { get bar() { return; } } ``` When `externalHelpers` is disabled, the output JavaScript will inline helper functions. ```ts title="rslib.config.ts" {5} export default { lib: [ { syntax: 'es5', externalHelpers: false, }, ], }; ``` Below is the output JavaScript file, the highlighted code is the inlined helper functions: ```js title="index.js" {1-18} function _class_call_check(instance, Constructor) { if (!(instance instanceof Constructor)) throw new TypeError('Cannot call a class as a function'); } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _create_class(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var src_FOO = /*#__PURE__*/ (function () { 'use strict'; function FOO() { _class_call_check(this, FOO); } _create_class(FOO, [ { key: 'bar', get: function () {}, }, ]); return FOO; })(); export { src_FOO as default }; ``` When `externalHelpers` is enabled, the output JavaScript will import helper functions from the external module `@swc/helpers`. ```ts title="rslib.config.ts" {5} export default { lib: [ { syntax: 'es5', externalHelpers: true, }, ], }; ``` Below is the output JavaScript file, the highlighted code is importing helper functions: ```js title="index.js" {1-2} import * as __WEBPACK_EXTERNAL_MODULE__swc_helpers_class_call_check__ from '@swc/helpers/_/_class_call_check'; import * as __WEBPACK_EXTERNAL_MODULE__swc_helpers_create_class__ from '@swc/helpers/_/_create_class'; var src_FOO = /*#__PURE__*/ (function () { 'use strict'; function FOO() { (0, __WEBPACK_EXTERNAL_MODULE__swc_helpers_class_call_check__._)(this, FOO); } (0, __WEBPACK_EXTERNAL_MODULE__swc_helpers_create_class__._)(FOO, [ { key: 'bar', get: function () {}, }, ]); return FOO; })(); export { src_FOO as default }; ``` --- url: /config/lib/banner.md --- # lib.banner * **Type:** ```ts type Banner = { js?: string; css?: string; dts?: string; }; ``` * **Default:** `{}` Inject content into the top of each JavaScript, CSS or declaration output file. ## Object type ### banner.js * **Type:** `string` * **Default:** `undefined` Inject content into the top of each JavaScript output file. ### banner.css * **Type:** `string` * **Default:** `undefined` Inject content into the top of each CSS output file. ### banner.dts * **Type:** `string` * **Default:** `undefined` Inject content into the top of each declaration output file. ## Notice The banner content in JavaScript and CSS file is based on the [BannerPlugin](https://rspack.dev/plugins/webpack/banner-plugin) of Rspack. You should notice the following points: * `raw: true` is enabled by default, so the banner content will be injected as a raw string instead of wrapping in a comment. So if you want to inject a comment, you should add `/*` and `*/` or other comment syntax by yourself. * The `stage` option is set to the stage after the JavaScript and CSS files are optimized, thus preventing the banner content from being optimized away. ## Customize banner content If the above default settings cannot meet your requirements, you can customize the banner content through `tools.rspack.plugins` to add a [BannerPlugin](https://rspack.dev/plugins/webpack/banner-plugin) instance with the corresponding options. ```ts title="rslib.config.ts" export default { lib: [ { // ... tools: { rspack: { plugins: [ new rspack.BannerPlugin({ // ... options }), ], }, }, }, ], }; ``` :::warning The banner content in declaration files is handled differently from JavaScript and CSS output files. It is written directly using the file system API, so setting `BannerPlugin` will not affect it. ::: --- url: /config/lib/footer.md --- # lib.footer * **Type:** ```ts type Footer = { js?: string; css?: string; dts?: string; }; ``` * **Default:** `{}` Inject content into the bottom of each JavaScript, CSS or declaration file. ## Object type ### footer.js * **Type:** `string` * **Default:** `undefined` Inject content into the bottom of each JavaScript output file. ### footer.css * **Type:** `string` * **Default:** `undefined` Inject content into the bottom of each CSS output file. ### footer.dts * **Type:** `string` * **Default:** `undefined` Inject content into the bottom of each declaration output file. ## Notice The footer content in JavaScript and CSS file is based on the [BannerPlugin](https://rspack.dev/plugins/webpack/banner-plugin) of Rspack. You should notice the following points: * `raw: true` is enabled by default, so the footer content will be injected as a raw string instead of wrapping in a comment. So if you want to inject a comment, you should add `/*` and `*/` or other comment syntax by yourself. * The `stage` option is set to the stage after the JavaScript and CSS files are optimized, thus preventing the footer content from being optimized away. ## Customize footer content If the above default settings cannot meet your requirements, you can customize the footer content through `tools.rspack.plugins` to add a [BannerPlugin](https://rspack.dev/plugins/webpack/banner-plugin) instance with the corresponding options. ```ts title="rslib.config.ts" export default { lib: [ { // ... tools: { rspack: { plugins: [ new rspack.BannerPlugin({ footer: true, // ... options }), ], }, }, }, ], }; ``` :::warning The footer content in declaration files is handled differently from JavaScript and CSS files. It is written directly using the file system API, so setting `BannerPlugin` will not affect it. ::: --- url: /config/lib/dts.md --- # lib.dts * **Type:** ```ts type Dts = | { bundle?: boolean; distPath?: string; build?: boolean; abortOnError?: boolean; autoExtension?: boolean; } | boolean; ``` * **Default:** `undefined` Configure the generation of the TypeScript declaration files. ## Boolean type Declaration files generation is an optional feature, you can set `dts: true` to enable [bundleless declaration files](/guide/advanced/dts.md#bundleless-declaration-files) generation. ```ts title="rslib.config.ts" {5} export default { lib: [ { format: 'esm', dts: true, }, ], }; ``` If you want to disable declaration files generation, you can set `dts: false` or do not specify the `dts` option. ```ts title="rslib.config.ts" {5} export default { lib: [ { format: 'esm', dts: false, }, ], }; ``` ## Object type If you want to customize the declaration files generation, you can set the `dts` option to an object. ### dts.bundle * **Type:** `boolean` * **Default:** `false` Whether to bundle the declaration files. #### Example If you want to [bundle declaration files](/guide/advanced/dts.md#bundle-declaration-files) files, you should: 1. Install [@microsoft/api-extractor](https://www.npmjs.com/package/@microsoft/api-extractor) as a development dependency, which is the underlying tool used for bundling declaration files. 2. Set `dts.bundle` to `true`. ```ts title="rslib.config.ts" {5-7} export default { lib: [ { format: 'esm', dts: { bundle: true, }, }, ], }; ``` #### Handle third-party packages When we bundle declaration files, we should specify which third-party package types need to be bundled, refer to the [Handle Third-Party Dependencies](/guide/advanced/third-party-deps.md) documentation for more details about externals related configurations. ### dts.distPath * **Type:** `string` The output directory of declaration files. #### Default value The default value follows the priority below: 1. The `dts.distPath` value in the current lib configuration. 2. The `declarationDir` value in the `tsconfig.json` file. 3. The [output.distPath.root](/config/rsbuild/output.md#outputdistpath) value in the current lib configuration. #### Example ```ts title="rslib.config.ts" {5-7} export default { lib: [ { format: 'esm', dts: { distPath: './dist-types', }, }, ], }; ``` ### dts.build * **Type:** `boolean` * **Default:** `false` Whether to generate declaration files with building the project references. This is equivalent to using the `--build` flag with the `tsc` command. See [Project References](https://www.typescriptlang.org/docs/handbook/project-references.html) for more details. ::: note When this option is enabled, you must explicitly set `declarationDir` or `outDir` in `tsconfig.json` in order to meet the build requirements. ::: ### dts.abortOnError * **Type:** `boolean` * **Default:** `true` Whether to abort the build process when an error occurs during declaration files generation. By default, type errors will cause the build to fail. When `abortOnError` is set to `false` like below, the build will still succeed even if there are type issues in the code. ```ts title="rslib.config.ts" {5-7} export default { lib: [ { format: 'esm', dts: { abortOnError: false, }, }, ], }; ``` ::: warning When this configuration is disabled, there is no guarantee that the type files will be generated correctly. ::: ### dts.autoExtension * **Type:** `boolean` * **Default:** `false` Whether to automatically set the declaration file extension based on the [format](/config/lib/format.md) option. #### Default extension By default that when `dts.autoExtension` is `false`, the declaration file extension will be `.d.ts`. When `dts.autoExtension` is set to `true`, the declaration file extension will be: * `.d.ts` with `esm` format and `.d.cts` with `cjs` format when `type: module` in `package.json`. * `.d.ts` with `cjs` format and `.d.mts` with `esm` format when `type: commonjs` or no `type` field in `package.json`. ::: note It follows the same logic as [lib.autoExtension](/config/lib/auto-extension.md), but the default value is different since the declaration file extension may cause some issues with different module resolution strategies. ::: --- url: /config/lib/shims.md --- # lib.shims * **Type:** ```ts type Shims = { cjs?: { 'import.meta.url'?: boolean; }; esm?: { __filename?: boolean; __dirname?: boolean; require?: boolean; }; }; ``` * **Default:** ```js const defaultShims = { cjs: { 'import.meta.url': true, }, esm: { __filename: false, __dirname: false, require: false, }, }; ``` Configure the [shims](https://developer.mozilla.org/en-US/docs/Glossary/Shim) for CommonJS and ESM output. ## shims.cjs Set the fields to `true` to enable the corresponding shims for CommonJS output. ### shims.cjs\['import.meta.url'] Whether to inject shims for the `import.meta.url` in CommonJS output. * **Default:** `true` Options: * `true`: when [format](/config/lib/format.md) is `cjs`, the `import.meta.url` in source code will be replaced with the URL of the current module. For example, given the following source code: ```js import { readFileSync } from 'fs'; const buffer = readFileSync(new URL('./data.proto', import.meta.url)); ``` the CJS output will be transformed to: ```js const { readFileSync } = require('fs'); const buffer = readFileSync( new URL( './data.proto', /*#__PURE__*/ (function () { return typeof document === 'undefined' ? new (module.require('url'.replace('', '')).URL)( 'file:' + __filename, ).href : (document.currentScript && document.currentScript.src) || new URL('main.js', document.baseURI).href; })(), ), ); ``` * `false`: the `import.meta.url` will be leave as is, which will cause a runtime error when running the output. ## shims.esm Set the fields to `true` to enable the corresponding shims for ESM output. ### shims.esm.\_\_filename Whether to inject shims for the global `__filename` of CommonJS in ESM output. * **Default:** `false` Options: * `true`: when [format](/config/lib/format.md) is `esm`, the `__filename` in source code will be replaced with the filename of the current module. For example, given the following source code: ```js console.log(__filename); ``` the ESM output will be transformed to: ```js import { fileURLToPath as __webpack_fileURLToPath__ } from 'url'; import { dirname as __webpack_dirname__ } from 'path'; var src_dirname = __webpack_dirname__( __webpack_fileURLToPath__(import.meta.url), ); var src_filename = __webpack_fileURLToPath__(import.meta.url); console.log(src_filename); ``` * `false`: the `__filename` will be leave as is, which will cause a runtime error when running the output. ### shims.esm.\_\_dirname Whether to inject shims for the global `__dirname` of CommonJS in ESM output. * **Default:** `false` Options: * `true`: when [format](/config/lib/format.md) is `esm`, the `__dirname` in source code will be replaced with the directory name of the current module. For example, given the following source code: ```js console.log(__dirname); ``` the ESM output will be transformed to: ```js import { fileURLToPath as __webpack_fileURLToPath__ } from 'url'; import { dirname as __webpack_dirname__ } from 'path'; var src_dirname = __webpack_dirname__( __webpack_fileURLToPath__(import.meta.url), ); console.log(src_dirname); ``` * `false`: the `__dirname` will be leave as is, which will cause a runtime error when running the output. ### shims.esm.require Whether to inject shims for the global `require` of CommonJS in ESM output. * **Default:** `false` Options: * `true`: when [format](/config/lib/format.md) is `esm`, there will be a `require` that created by `createRequire` at the beginning of the output which can be accessed in source code like the global `require` like CommonJS. For example, given the following source code: ```js const someModule = require('./someModule'); // dynamic require const dynamicRequiredModule = require(SOME_VALUE_IN_RUNTIME); // require.resolve const someModulePath = require.resolve('./someModule'); // use require as a expression const lazyFn = (module, requireFn) => {}; lazyFn('./other.js', require); ``` the ESM output will be transformed to: ```js import __rslib_shim_module__ from 'module'; const require = /*#__PURE__*/ __rslib_shim_module__.createRequire( import.meta.url, ); // dynamic require require(SOME_VALUE_IN_RUNTIME); // require.resolve require.resolve('./someModule'); // use require as a expression const lazyFn = (module, requireFn) => {}; lazyFn('./other.js', require); ``` * `false`: the `require` will be leave as is, which will cause a runtime error when running the output. --- url: /config/lib/id.md --- # lib.id * **Type:** `string` * **Default:** `undefined` Specify the library ID. The ID identifies the library and is useful when using the `--lib` flag to build specific libraries with a meaningful `id` in the CLI. :::tip Rslib uses Rsbuild's [environments](https://rsbuild.dev/guide/advanced/environments) feature to build multiple libraries in a single project under the hood. `lib.id` will be used as the key for the generated Rsbuild environment. ::: ## Default value By default, Rslib automatically generates an ID for each library in the format `${format}${index}`. Here, `format` refers to the value specified in the current lib's [format](/config/lib/format.md), and `index` indicates the order of the library within all libraries of the same format. If there is only one library with the current format, the `index` will be empty. Otherwise, it will start from `0` and increment. For example, the libraries in the `esm` format will start from `esm0`, followed by `esm1`, `esm2`, and so on. In contrast, `cjs` and `umd` formats do not include the `index` part since there is only one library for each format. ```ts title="rslib.config.ts" export default { lib: [ { format: 'esm' }, // id is `esm0` { format: 'cjs' }, // id is `cjs` { format: 'esm' }, // id is `esm1` { format: 'umd' }, // id is `umd` { format: 'esm' }, // id is `esm2` ], }; ``` ## Customize ID You can also specify a readable or meaningful ID of the library by setting the `id` field in the library configuration. The user-specified ID will take priority, while the rest will be used together to generate the default ID. For example, `my-lib-a`, `my-lib-b`, and `my-lib-c` will be the IDs of the specified libraries, while the rest will be used to generate and apply the default ID. {/* prettier-ignore-start */} ```ts title="rslib.config.ts" export default { lib: [ { format: 'esm', id: 'my-lib-a' }, // ID is `my-lib-a` { format: 'cjs', id: 'my-lib-b' }, // ID is `my-lib-b` { format: 'esm' }, // ID is `esm0` { format: 'umd', id: 'my-lib-c' }, // ID is `my-lib-c` { format: 'esm' }, // ID is `esm1` ], }; ``` {/* prettier-ignore-end */} Then you could only build `my-lib-a` and `my-lib-b` by running the following command: ```bash npx rslib build --lib my-lib-a --lib my-lib-b ``` :::note The id of each library must be unique, otherwise it will cause an error. ::: --- url: /config/lib/umd-name.md --- # lib.umdName * **Type:** `string` * **Default:** `undefined` The export name of the [UMD](/guide/basic/output-format.md#umd) bundle. :::tip The module name of the UMD bundle must not conflict with the global variable name. ::: ## Example The UMD bundle will be mounted to `global.MyLibrary`. ```ts title="rslib.config.ts" {5} export default { lib: [ { format: 'umd', umdName: 'MyLibrary', }, ], }; ``` --- url: /config/lib/out-base.md --- # lib.outBase * **Type:** `string` * **Default Value:** `undefined` :::info `outBase` is a specific configuration for [bundleless mode](/guide/basic/output-structure.md#bundle--bundleless). This configuration does not take effect in bundle mode because all output files are bundled into a single file, so there's no need to determine the base output directory. ::: When building a project where source files exist across multiple directories with bundleless mode, the output directory structure will be replicated relative to the `outBase` directory in the output directory. If no base output directory is specified, the [lowest common ancestor](https://en.wikipedia.org/wiki/Lowest_common_ancestor) of all input entry points is used by default. Configuring `outBase` will change the path of the base output directory. `outBase` can be either a relative path from the current process directory or an absolute path. For example, we have the following directory structure: ```txt . ├── package.json ├── rslib.config.ts └── src └── utils ├── bar │ └── index.ts ├── foo │ └── index.ts └── index.ts ``` If the output base directory is not specified, the lowest common ancestor of all input entry point paths, i.e. `./src/utils`, is used by default, and the final file output structure is: ```txt dist ├── bar │ └── index.js ├── foo │ └── index.js └── index.js ``` When `outBase` is configured as `./src`, the output directory structure is: ```txt dist └── utils ├── bar │ └── index.js ├── foo │ └── index.js └── index.js ``` ::: tip When the project needs to generate declaration files, to ensure that the generated declaration files and JS files maintain a consistent output directory structure, if you modify the `outBase` configuration, you need to make sure that the [rootDir](https://www.typescriptlang.org/tsconfig/rootDir.html) in `tsconfig.json` to the same path. ::: --- url: /config/rsbuild/index.md --- # Rsbuild configurations Rslib inherits its configuration from Rsbuild, so you can also configure the options from Rsbuild. This chapter introduces some common configuration items and explains how to use them in Rslib. :::tip To learn more about Rslib configurations, check out [Configure Rslib](/guide/basic/configure-rslib.md). ::: ## Overview * [resolve](/config/rsbuild/resolve.md): Options for module resolution. * [source](/config/rsbuild/source.md): Options for input source code. * [output](/config/rsbuild/output.md): Options for build outputs. * [tools](/config/rsbuild/tools.md): Options for low-level tools. * [plugins](/config/rsbuild/plugins.md): Configure Rsbuild plugins. --- url: /config/rsbuild/resolve.md --- # resolve Options for module resolution. ## resolve.aliasStrategy Control the priority between the `paths` option in `tsconfig.json` and the `resolve.alias` option of Rsbuild. ## resolve.alias Set the alias for the module path, which is used to simplify the import path or redirect the module reference, similar to the [resolve.alias](https://rspack.dev/config/resolve#resolvealias) config of Rspack. For TypeScript projects, you only need to configure [compilerOptions.paths](https://www.typescriptlang.org/tsconfig/#paths) in the `tsconfig.json` file. Rslib will automatically recognize it, so there is no need to configure the `resolve.alias` option separately. It is worth noting that in bundle mode, both `resolve.alias` and [output.externals](/config/rsbuild/output.md#outputexternals) can be used to set aliases, but they differ in the following ways: * `resolve.alias` is used to replace the target module with another module, which will be bundled into the output. For example, if you want to replace `lodash` with `lodash-es` when bundling a package, you can configure it as follows: ```ts title="rslib.config.ts" export default { // ... resolve: { alias: { lodash: 'lodash-es', }, }, }; ``` Now, all `lodash` imports in the source code will be mapped to `lodash-es` and bundled into the output. * `output.externals` is used to handle alias mapping for externalized modules. Externalized modules are not included in the bundle; instead, they are imported from external sources at runtime. For example, if you want to replace externalized modules `react` and `react-dom` with `preact/compat` in the bundle, you can configure it as follows: ```ts title="rslib.config.ts" export default { // ... output: { externals: { react: 'preact/compat', 'react-dom': 'preact/compat', }, }, }; ``` Now, the code `import { useState } from 'react'` will be replaced with `import { useState } from 'preact/compat'`. ::: note In bundleless mode, since there is no bundling concept, all modules will be externalized. Rslib will automatically transform the modules resolved to the [outBase](/en/config/lib/out-base.md) directory based on the mappings configured in `resolve.alias` or [compilerOptions.paths](https://www.typescriptlang.org/tsconfig/#paths) in `tsconfig.json`. ::: ## resolve.dedupe Force Rsbuild to resolve the specified packages from project root, which is useful for deduplicating packages and reducing the bundle size. ## resolve.extensions Automatically resolve file extensions when importing modules. This means you can import files without explicitly writing their extensions. --- url: /config/rsbuild/source.md --- # source Options for input source code. ## source.assetsInclude Include additional files that should be treated as static assets. ## source.decorators Used to configure the decorators syntax. If [experimentalDecorators](https://www.typescriptlang.org/tsconfig/#experimentalDecorators) is enabled in `tsconfig.json`, Rslib will set `source.decorators.version` to `legacy` by default. ## source.define Replaces variables in your code with other values or expressions at compile time. This can be useful for allowing different behavior between development builds and production builds. ## source.entry Used to set the entry modules for building. In Rslib, the default value is: * bundle mode: ```ts const defaultEntry = { // default support for other suffixes such as ts, tsx, jsx, mjs, cjs index: 'src/index.js', }; ``` * bundleless mode: ```ts const defaultEntry = { index: 'src/**', }; ``` :::info Check out the [lib.bundle](/config/lib/bundle.md#set-entry) to learn more about how to set entry for bundle and bundleless project. ::: ## source.exclude Specifies JavaScript/TypeScript files that do not need to be compiled. ## source.include Specify additional JavaScript files that need to be compiled. {/* ## source.preEntry */} {/* Add a script before the entry file of each page. This script will be executed before the page code. It can be used to execute global logics, such as injecting polyfills, setting global styles, etc. */} ## source.transformImport Transform the import path, which can be used to modularly import the subpath of third-party packages. The functionality is similar to [babel-plugin-import](https://npmjs.com/package/babel-plugin-import). ## source.tsconfigPath Configure a custom tsconfig.json file path to use, can be a relative or absolute path. --- url: /config/rsbuild/output.md --- # output Options for build outputs. ## output.assetPrefix Use this option to set the URL prefix for static assets, such as setting it to a CDN URL. In Rslib, the default value for this option depends on [format](/config/lib/format.md): * When `format` is `cjs` or `esm`, the default value is `"auto"`. * When `format` is `mf` or `umd`, the default value is `"/"`. When `output.assetPrefix` is set to `"auto"`, Rslib defaults to setting [importMode](https://rspack.dev/config/module#modulegeneratorassetimportmode) to `"preserve"`, which preserves the `import` or `require` statements for static assets in JavaScript files. Additionally, the static asset references in CSS files remain as relative paths, see [Import static assets](/guide/advanced/static-assets.md) for more details. When `output.assetPrefix` is set to a specific path, the static asset import statements in JavaScript files will no longer be preserved and will be replaced with URLs prefixed by that path. Additionally, the static asset paths in CSS files will be substituted with paths that include this prefix. ## output.charset The `charset` config allows you to specify the [character encoding](https://developer.mozilla.org/en-US/docs/Glossary/Character_encoding) for output files to ensure they are displayed correctly in different environments. ## output.cleanDistPath Whether to clean up all files under the output directory before the build starts (the output directory defaults to `dist`). ## output.copy Copies the specified file or directory to the dist directory, implemented based on [rspack.CopyRspackPlugin](https://rspack.dev/plugins/rspack/copy-rspack-plugin). ## output.cssModules For custom CSS Modules configuration. ## output.dataUriLimit Set the size threshold to inline static assets such as images and fonts. When [format](/config/lib/format.md) is set to `cjs` or `esm`, Rslib defaults to setting `output.dataUriLimit` to `0`, without inlining any static assets, so that build tools on the application side can handle and optimize them. ## output.distPath Set the directory of the dist files. Rsbuild will output files to the corresponding subdirectory according to the file type. By default, Rslib sets `output.distPath` to: ```ts const defaultDistPath = { root: 'dist', js: './', jsAsync: './', css: './', cssAsync: './', svg: 'static/svg', font: 'static/font', wasm: 'static/wasm', image: 'static/image', media: 'static/media', assets: 'static/assets', }; ``` {/* ## output.emitAssets */} {/* Control whether to emit static assets such as images, fonts, audio, video, etc. */} ## output.emitCss Whether to emit CSS to the output bundles. ## output.externals At build time, prevent some `import` dependencies from being packed into bundles in your code, and instead fetch them externally at runtime. In bundle mode, Rslib will automatically add the dependencies listed in the `dependencies`, `optionalDependencies`, and `peerDependencies` fields of `package.json` to `output.externals`. See [lib.autoExternal](/config/lib/auto-external.md) for more information. :::note It is important to note that `output.externals` differs from [resolve.alias](/config/rsbuild/resolve.md#resolvealias). Check out [resolve.alias](/config/rsbuild/resolve.md#resolvealias) documentation for more information. ::: ## output.filenameHash Whether to add a hash value to the filename after the production build. Rslib sets `output.filenameHash` to `false` by default. ::: info Filename hash By default, Rslib does not add a hash value in the middle of filenames. To enable this behavior, you can set `output.filenameHash` to `true`. You can also specify different filenames for different types of files by configuring `output.filename`. ::: ## output.filename Sets the filename of dist files. By default, Rslib will modify the JavaScript output file extension by setting `output.filename.js` according to [format](/config/lib/format.md), see [autoExtension](/config/lib/auto-extension.md) for more details. {/* ## output.injectStyles */} {/* Whether to inject styles into DOM. */} ## output.inlineScripts Whether to inline output scripts files (.js files) into HTML with `