web-infra-dev / rsbuild

The Rspack-based build tool. It's fast, out-of-the-box and extensible.
https://rsbuild.dev/
MIT License
1.29k stars 102 forks source link

[Feature]: Build orchestration API #2916

Open jacob-ebey opened 1 month ago

jacob-ebey commented 1 month ago

What problem does this feature solve?

In some situations (such as RSC) we need to be able to orchestrate the order and number of times an environments build is ran. A simple example of this goes something like this:

  1. Build server, discover "use client"
  2. Build client with discovered client modules, discover "use server"
  3. Re-build server with discovered server modules, discover new "use client"
  4. etc...

What does the proposed API look like?

Vite's new environments API comes with a builder.buildApp API and I propose something very similar for use here:

export default defineConfig({
  builder: {
    buildApp: async (builder) => {
      await builder.build(builder.environments.browser);
      await builder.build(builder.environments.server);
    },
  },
});

This would allow us to write logic such as:

export default defineConfig({
  builder: {
    buildApp: async (builder) => {
      do {
        checkpointDiscoveredModules();
        await builder.build(builder.environments.server);
        await Promise.all([
          builder.build(builder.environments.browser),
          builder.build(builder.environments.ssr),
        ]);
      } while (discoveredNewModules());
    },
  },
});
chenjiahan commented 1 month ago

I totally agree, Rsbuild needs to provide similar capabilities.

First we need to clarify what is the main difference between the proposed builder.build API and Rsbuild's JavaScript API (rsbuild.build()). And I wonder if it should be implemented via the JavaScript API rather than the Rsbuild configuration.

jacob-ebey commented 1 month ago

I'm beyond tired of having to maintain "build CLIs". Vite's approach is correct here. It allows a plugin / framework to define the order / interplay between builds completely within their plugin. No more xyz build, xyz dev. It's just bundler dev builder build --app to specify we want the output of the environments that make up the cohesive application. For cohesion today everywhere except for Vite6 MUST be done via a custom maintained CLI / tool that uses the specific bundler JS APIs.

jacob-ebey commented 1 month ago

I'd recommend implementing it via the JS API and exposing that to plugins / config via the above convenience layer so it can be used "internally" instead of "externally".

chenjiahan commented 1 month ago

Ok, so our goal is to allow Rsbuild plugin to orchestrate the build process, instead of calling JS API via a custom CLI. This should be useful for frameworks like Remix.

We will look at the design of Vite 6 next week and consider how Rsbuild can achieve this.