Multi-environment

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

Define multiple environment configurations

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 a web and node environment respectively.

rsbuild.config.ts
export default {
  environments: {
    // client environment configuration
    web: {
      source: {
        alias: {
          '@common1': './src/web/common1',
        },
        entry: {
          index: './src/index.client.js',
        },
      },
      output: {
        // Define the build product type for the browser side
        target: 'web',
      },
    },
    // SSR environment configuration
    node: {
      source: {
        alias: {
          '@common1': './src/ssr/common1',
        },
        entry: {
          index: './src/index.server.js',
        },
      },
      output: {
        // Define build artifact types for Node.js
        target: 'node',
      },
    },
  },
};

After the above configuration is completed, Rsbuild will calculate the final effective Rsbuild and Rspack configurations based on these two environment configurations and build them.

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

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

Inspect config succeed, open following files to view the content:

  - Rsbuild Config (web): /project/dist/rsbuild.config.web.mjs
  - Rsbuild Config (node): /project/dist/rsbuild.config.node.mjs
  - Rspack Config (web): /project/dist/rspack.config.web.mjs
  - Rspack Config (node): /project/dist/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 set product type (the value of output.target).

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

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

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

Modify environment configuration through plugin API

Add / modify environment configuration

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

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

Modify a single environment configuration

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

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

Get 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 modifyBundlerChain and modifyRspackConfig), Rsbuild supports obtaining the current environment context through the environment parameter.

const myPlugin = () => ({
  setup: (api) => {
    api.modifyBundlerChain((chain, { environment }) => {
      const { name, config, entry } = environment;

      if (config.output.minify !== false) {
        chain.optimization
          .minimizer(CHAIN_ID.MINIMIZER.JS)
          .use(SwcJsMinimizerRspackPlugin)
          .end();
      }
    });
  },
});

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

const myPlugin = () => ({
  setup: (api) => {
    api.onDevCompileDone(({ environments }) => {
      const entries = Object.values(environments).map((e) => e.entry);
    });
  },
});

Use 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 = (serverAPI) => async (_req, res) => {
  const indexModule = await serverAPI.environments.ssr.loadBundle('index');

  const markup = indexModule.render();

  const template = await serverAPI.environments.web.getTransformedHtml('index');

  const html = template.replace('<!--app-content-->', markup);

  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 DevServer 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...\n', err);
      next();
    }
  });

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

  // ...
}

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