close
logologo
Guide
Config
Plugin
API
Community
Version
Changelog
Rsbuild 0.x Doc
English
简体中文
Guide
Config
Plugin
API
Community
Changelog
Rsbuild 0.x Doc
English
简体中文
logologo

Getting Started

Introduction
Quick start
Features
Glossary

Framework

React
Vue
Preact
Svelte
Solid

Basic

CLI
Dev server
Output files
Static assets
HTML
JSON
Wasm
TypeScript
Web Workers
Deploy static site
Upgrade Rsbuild

Configuration

Configure Rspack
Configure Rsbuild
Configure SWC

Styling

CSS
CSS Modules
CSS-in-JS
Tailwind CSS v4
Tailwind CSS v3
UnoCSS

Advanced

Path aliases
Environment variables
Hot module replacement
Browserslist
Browser compatibility
Module Federation
Multi-environment builds
Server-side rendering (SSR)
Testing

Optimization

Code splitting
Bundle size optimization
Improve build performance
Inline static assets

Migration

Migrating from Rsbuild 0.x
webpack
Create React App
Vue CLI
Vite
Vite plugin
Modern.js Builder

Debug

Debug mode
Build profiling
Use Rsdoctor

FAQ

General FAQ
Features FAQ
Exceptions FAQ
HMR FAQ
📝 Edit this page on GitHub
Previous PageModule Federation
Next PageServer-side rendering (SSR)

#Multi-environment builds

Rsbuild supports building outputs for multiple environments at the same time. You can use environments to build multiple environments in parallel and set a different Rsbuild config for each environment.

#What is environment

The environment refers to the runtime environment for build output. Common environments include browsers, Node.js, and Workers. Rsbuild allows you to define any environment names and set build options for each environment individually.

A typical scenario is server-side rendering (SSR). You can define two environments, web and node, where the build targets (output.target) are web and node. These are used for client-side rendering (CSR) and server-side rendering (SSR) scenarios.

You can also define different environments for the same build target, for example:

  • Define rsc and ssr environments, both targeting node, used separately for React Server Components and SSR.
  • Define desktop and mobile environments, both targeting web, used separately for desktop and mobile browsers.

Without the environments configuration, you would need to define multiple configurations for these scenarios and run multiple independent Rsbuild builds. Now, with the environments configuration, you can complete the build for multiple outputs in a single Rsbuild run (Rsbuild achieves this using Rspack's MultiCompiler).

In Rsbuild, each environment is associated with an Rsbuild configuration, an Rspack configuration, and a set of build outputs. Rsbuild plugin developers can customize the build process for a specified environment based on the environment name, such as modifying Rsbuild or Rspack configurations, registering or removing plugins, adjusting Rspack rules, and viewing assets information.

#Environment configs

Rsbuild supports defining different Rsbuild configurations for each environment through environments.

For example, if your project wants to support the SSR function, you need to define different configurations for client and SSR respectively. You can define web and node environments.

rsbuild.config.ts
export default {
  environments: {
    // Configure the web environment for browsers
    web: {
      source: {
        entry: {
          index: './src/index.client.js',
        },
      },
      output: {
        // Use 'web' target for the browser outputs
        target: 'web',
      },
      resolve: {
        alias: {
          '@common': './src/client/common',
        },
      },
    },
    // Configure the node environment for SSR
    node: {
      source: {
        entry: {
          index: './src/index.server.js',
        },
      },
      output: {
        // Use 'node' target for the Node.js outputs
        target: 'node',
      },
      resolve: {
        alias: {
          '@common': './src/server/common',
        },
      },
    },
  },
};

#Config merging

If you configure environments, Rsbuild will merge the config in environments with the outer base config. When merging, the config in environments has higher priority.

In the example above, after merging the configs, Rsbuild generates two standalone environment configs for building web and node environments.

  • web environments config: Generated by merging base config with environments.web
  • node environments config: Generated by merging base config with environments.node

Then, Rsbuild will use these environment configurations to internally generate two Rspack configs and execute a single build using Rspack’s MultiCompiler.

#Debug config

When you execute the command npx rsbuild inspect in the project root directory, you will find the following output:

  • rsbuild.config.[name].mjs: The Rsbuild config used for a certain environment during build.
  • rspack.config.[name].mjs: The Rspack config corresponding to a certain environment when building.
➜ npx rsbuild inspect

config inspection completed, generated files:

  - Rsbuild config (web): /project/dist/.rsbuild/rsbuild.config.web.mjs
  - Rsbuild config (node): /project/dist/.rsbuild/rsbuild.config.node.mjs
  - Rspack config (web): /project/dist/.rsbuild/rspack.config.web.mjs
  - Rspack config (node): /project/dist/.rsbuild/rspack.config.node.mjs

#Default environment

When environments is not specified, Rsbuild will by default create an environment with the same name based on the currently target type (the value of output.target).

rsbuild.config.ts
export default {
  output: {
    target: 'web',
  },
};

The above config is equivalent to a simplification of the following config:

rsbuild.config.ts
export default {
  environments: {
    web: {
      output: {
        target: 'web',
      },
    },
  },
};

#Build specified environment

By default, Rsbuild will build all environments in the Rsbuild configuration when you execute rsbuild dev or rsbuild build. You can build only the specified environment via --environment <name>.

# Build for all environments by default
rsbuild dev

# Build for the web environment
rsbuild dev --environment web

# Build for the web and ssr environments
rsbuild dev --environment web --environment node

# Build multiple environments can be shortened to:
rsbuild dev --environment web,node

#Add plugins for specified environment

Plugins configured through the plugins field support running in all environments. If you want a plugin to run only in a specified environment, you can configure the plugin in the specified environment.

For example, enable the React plugin only in the web environment:

rsbuild.config.ts
import { pluginReact } from '@rsbuild/plugin-react';

export default {
  environments: {
    web: {
      output: {
        target: 'web',
      },
      plugins: [pluginReact()],
    },
    node: {
      output: {
        target: 'node',
      },
    },
  },
};

If you are a plugin developer, you can view Developing environment plugins for details.

#Configuring output directories

When building for multiple environments, it's recommended to configure different output directories for each environment to prevent dist files with the same name from overwriting each other.

You can use output.distPath.root to set independent output root directories for each environment.

For example, output the web bundles to the default dist directory, and the node bundles to dist/server:

rsbuild.config.ts
export default {
  environments: {
    web: {
      source: {
        entry: {
          index: './src/index.client.js',
        },
      },
    },
    node: {
      source: {
        entry: {
          index: './src/index.server.js',
        },
      },
      output: {
        target: 'node',
        distPath: {
          root: 'dist/server',
        },
      },
    },
  },
};

#Plugin API

#Update environment config

Rsbuild supports modifying or adding environment config through the modifyRsbuildConfig hook.

const myPlugin = () => ({
  setup(api) {
    api.modifyRsbuildConfig((config, { mergeRsbuildConfig }) => {
      return mergeRsbuildConfig(config, {
        environments: {
          web1: {
            source: {
              entry: {
                index: './src/web1/index',
              },
            },
          },
        },
      });
    });
  },
});

#Configuring a specific environment

Rsbuild supports modifying the Rsbuild config of a specific environment through the modifyEnvironmentConfig hook.

const myPlugin = () => ({
  setup(api) {
    api.modifyEnvironmentConfig((config, { name }) => {
      if (name !== 'web') {
        return config;
      }
      config.html.title = 'My Default Title';
    });
  },
});

#Environment context

Environment context is a read-only object that provides some context infos about the current environment. Rsbuild supports obtaining environment context information in plugin hooks.

For some plugin hooks related to the build environment (such as modifyRspackConfig and modifyBundlerChain), Rsbuild supports obtaining the current environment context through the environment parameter.

const myPlugin = () => ({
  setup(api) {
    api.modifyRspackConfig((rspackConfig, { environment }) => {
      if (environment.name === 'node') {
        // do some thing
      }
    });
  },
});

For some global plugin hooks (such as onAfterDevCompile, onBeforeStartDevServer, etc.), Rsbuild supports obtaining the context of all environments through the environments parameter.

const myPlugin = () => ({
  setup(api) {
    api.onAfterDevCompile(({ environments }) => {
      environments.forEach((environment) => {
        console.log('environment', environment);
      });
    });
  },
});

#Environment API

Rsbuild server provides a series of APIs related to the build environment. Users can operate the build artifacts in a specific environment on the server side through the Rsbuild environment API.

You can use the environment API in Rsbuild DevMiddleware or Custom Server.

For example, you can quickly implement an SSR function through the Rsbuild environment API in development mode:

import express from 'express';
import { createRsbuild, loadConfig } from '@rsbuild/core';

const serverRender =
  ({ environments }) =>
  async (_req, res) => {
    const bundle = await environments.node.loadBundle('index');
    const rendered = bundle.render();
    const template = await environments.web.getTransformedHtml('index');
    const html = template.replace('<!--app-content-->', rendered);

    res.writeHead(200, {
      'Content-Type': 'text/html',
    });
    res.end(html);
  };

export async function startDevServer() {
  const { content } = await loadConfig();

  // Init Rsbuild
  const rsbuild = await createRsbuild({
    rsbuildConfig: content,
  });

  const app = express();

  // Create Rsbuild dev server instance
  const rsbuildServer = await rsbuild.createDevServer();

  const serverRenderMiddleware = serverRender(rsbuildServer);

  app.get('/', async (req, res, next) => {
    try {
      await serverRenderMiddleware(req, res, next);
    } catch (err) {
      logger.error('SSR render error, downgrade to CSR...');
      logger.error(err);
      next();
    }
  });

  // Apply Rsbuild’s built-in middleware
  app.use(rsbuildServer.middlewares);

  // ...
}

For detailed usage, please refer to: SSR + Express Example.

#Build order

By default, Rsbuild builds all environments in parallel.

To control the build order between different environments, you can set build dependencies through Rspack's dependencies configuration.

For example, if you need to build the web environment first, then build the node environment, you can add the following configuration:

rsbuild.config.ts
export default {
  environments: {
    web: {
      tools: {
        rspack: {
          name: 'foo',
        },
      },
    },
    node: {
      tools: {
        rspack: {
          dependencies: ['foo'],
        },
      },
    },
  },
};

We can use a simple plugin to test the build order of multiple environments:

const testPlugin: RsbuildPlugin = {
  name: 'test-plugin',
  setup(api) {
    api.onBeforeEnvironmentCompile(({ environment }) => {
      console.log('build start:', environment.name);
    });

    api.onAfterEnvironmentCompile(({ stats, environment }) => {
      console.log('build done:', environment.name);
      console.log('stats', stats);
    });
  },
};

// The plugin will output:
// - build start: web
// - build done: web
// - stats: { ... }
// - build start: node
// - build done: node
// - stats: { ... }