feat: builtin react server component#12012
Conversation
✅ Deploy Preview for rspack canceled.
|
📦 Binary Size-limit
❌ Size increased by 479.63KB from 47.70MB to 48.17MB (⬆️0.98%) |
CodSpeed Performance ReportMerging this PR will not alter performanceComparing Summary
Footnotes
|
948b3e2 to
cedca6d
Compare
Deploying rspack-v2 with
|
| Latest commit: |
0cfbe8e
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://c91a7800.rspack-v2.pages.dev |
| Branch Preview URL: | https://react-server-component.rspack-v2.pages.dev |
db8125e to
626f6fd
Compare
626f6fd to
40268c3
Compare
|
📝 Benchmark detail: Open
Threshold exceeded: ["10000_development-mode + exec","10000_development-mode_noop-loader + exec","10000_production-mode + exec","10000_production-mode_persistent-cold + exec","10000_production-mode_persistent-hot + exec","arco-pro_production-mode_persistent-hot + exec","threejs_production-mode_10x_persistent-hot + exec"] |
|
is the codspeed performance regression expected or just flaky? |
|
Deploying rspack with
|
| Latest commit: |
4276a07
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://d994fc02.rspack-v2.pages.dev |
| Branch Preview URL: | https://react-server-component.rspack-v2.pages.dev |
There was a problem hiding this comment.
Pull request overview
This PR introduces first-class React Server Components (RSC) support into Rspack by wiring together compiler/runtime coordination, SWC transforms, and public plugin APIs, with an accompanying Rust plugin crate and Node bindings.
Changes:
- Adds a new
rspack_plugin_rsccrate implementing server/client RSC plugins, a manifest runtime module, loaders, hot-reload tracking, and coordination between server/client compilers. - Integrates RSC support into the JS/TS surface: exports
experiments.rsc, wires the builtin plugins through@rspack/binding, adds SWC loader options (rspackExperiments.reactServerComponents), and extends runtime globals and compiler hooks. - Adjusts core compiler/watch infrastructure (new
CompilerDone/CompilerFailedhooks, updatedWatchingdependency handling) and SWC/Javascript compiler plumbing to support the new RSC transforms and metadata.
Reviewed changes
Copilot reviewed 58 out of 61 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
packages/rspack/src/exports.ts |
Exposes the new rsc builtin via experiments.rsc so RSC plugins can be accessed from the JS API. |
packages/rspack/src/builtin-plugin/rsc/index.ts |
Defines the high-level rsc helper (plugin factory + layer constants) wrapping the client/server RSC builtin plugins. |
packages/rspack/src/builtin-plugin/rsc/RscServerPlugin.ts |
JS wrapper around the native RscServerPlugin, connecting the Coordinator binding into the builtin-plugin framework. |
packages/rspack/src/builtin-plugin/rsc/RscClientPlugin.ts |
JS wrapper around the native RscClientPlugin, similarly bridging the Coordinator into client compilation. |
packages/rspack/src/builtin-plugin/rsc/Coordinator.ts |
JS-side coordinator that shares a binding JsCoordinator instance between server/client compilers and proxies watching behavior from server to client. |
packages/rspack/src/builtin-plugin/index.ts |
Re-exports the rsc helper from the builtin-plugin index. |
packages/rspack/src/builtin-loader/swc/types.ts |
Adds rspackExperiments.reactServerComponents?: boolean to SWC loader options to toggle the RSC SWC transforms. |
packages/rspack/src/Watching.ts |
Moves construction of dependency sets into the process.nextTick path so they reflect any mutations made in compiler.hooks.done, which RSC’s coordinator relies on. |
packages/rspack/src/MultiCompiler.ts |
Minor formatting separation around unsafeFastDrop accessor (no functional change). |
packages/rspack/src/Compiler.ts |
Introduces GET_COMPILER_ID symbol and a non-enumerable property that exposes the underlying JsCompiler ID to the binding-level Coordinator. |
packages/rspack/scripts/check-documentation-coverage.ts |
Excludes the new RSC-related plugins from documentation coverage checks while they stabilize. |
packages/rspack/etc/core.api.md |
Updates the generated public API surface to include rsc, RSC plugin classes, Coordinator, SWC options, and associated types. |
crates/swc_plugin_ts_collector/tests/fixture.rs |
Updates the test harness to pass an Arc<FileName> and SWC comments, matching the new JavaScriptCompiler::transform signature. |
crates/rspack_plugin_rsc/src/utils.rs |
Provides utilities for normalizing module resources, detecting CSS modules, iterating chunk modules, JSON literal encoding, and URI-encoding paths, used by the manifest builder and plugins. |
crates/rspack_plugin_rsc/src/server_plugin.rs |
Implements the Rust-side RscServerPlugin: tracks server component changes, coordinates multi-phase compilations via Coordinator, injects client/SSR/action entries, and wires the RSC manifest runtime module. |
crates/rspack_plugin_rsc/src/reference_manifest.rs |
Declares data structures representing the RSC server reference manifest and module loading metadata (including crossorigin behavior). |
crates/rspack_plugin_rsc/src/plugin_state.rs |
Maintains per-compiler RSC plugin state (client/SSR manifests, entry CSS/JS files, actions, and change tracking) in a global map keyed by CompilerId. |
crates/rspack_plugin_rsc/src/manifest_runtime_module.rs |
Generates the runtime RSC manifest (__webpack_require__.rscM) based on collected plugin state, including server actions, client modules, server-consumer module map, and per-entry assets. |
crates/rspack_plugin_rsc/src/loaders/* |
Adds loaders and corresponding plugins for client entries and action entries; they parse loader query JSON, generate appropriate import/export stubs, and register the loaders via NormalModuleFactoryResolveLoader. |
crates/rspack_plugin_rsc/src/lib.rs |
Exposes the RSC client/server plugins, Coordinator, and loader plugins as the public Rust crate API. |
crates/rspack_plugin_rsc/src/hot_reloader.rs |
Implements hashing-based tracking of changed server components per entry to drive HMR callbacks. |
crates/rspack_plugin_rsc/src/coordinator.rs |
Coordinates the multi-step compilation workflow (server entries → client entries → server actions), with a small state machine and async transitions. |
crates/rspack_plugin_rsc/src/constants.rs |
Centralizes RSC layer names and regexes for CSS and image detection. |
crates/rspack_plugin_rsc/src/component_info.rs |
Walks the module graph from an entry to collect client component imports, CSS imports, actions, and SSR injection flags, driving client/SSR entry injection. |
crates/rspack_plugin_rsc/src/client_plugin.rs |
Implements the Rust-side RscClientPlugin: tracks injected client entries, builds client/SSR manifests (including per-entry JS/CSS assets), and triggers coordinator transitions. |
crates/rspack_plugin_rsc/LICENSE |
Adds an MIT license file for the new RSC plugin crate. |
crates/rspack_plugin_rsc/Cargo.toml |
Declares the new rspack_plugin_rsc crate and its dependencies (SWC, async runtime, simd-json, etc.). |
crates/rspack_plugin_javascript/src/parser_plugin/api_plugin.rs |
Adds support for the __rspack_rsc_manifest__ API symbol, mapping it to the new RuntimeGlobals::RSC_MANIFEST. |
crates/rspack_loader_swc/src/rsc_transforms/* |
Introduces RSC-specific SWC passes: RSC directive handling, server action transforms, server/client entry proxy generation, CJS detection, and RSC metadata collection into RscMeta. |
crates/rspack_loader_swc/src/options.rs |
Wires react_server_components into parsed SWC options, bridging the TS reactServerComponents flag to the Rust side. |
crates/rspack_loader_swc/src/lib.rs |
Enables the RSC SWC passes when the experiment flag is set, passes comments into the JS compiler, and writes back RscMeta, optionally replacing server entry sources with generated proxy modules. |
crates/rspack_loader_swc/Cargo.toml |
Adds RSC transform dependencies (hex, indoc, once_cell, regex, sha2) and makes rspack_util non-optional. |
crates/rspack_javascript_compiler/src/compiler/transform.rs |
Extends JavaScriptCompiler::transform to accept shared comments and uses an Arc<FileName>, propagating comments into JavaScriptTransformer. |
crates/rspack_javascript_compiler/examples/transform.rs |
Updates the example to match the new transform API, including comments and Arc<FileName>. |
crates/rspack_core/src/runtime_globals.rs |
Introduces RuntimeGlobals::RSC_MANIFEST and maps it to __webpack_require__.rscM. |
crates/rspack_core/src/module_graph/mod.rs |
Adds get_resolved_module helper for looking up the resolved module identifier from a dependency ID, simplifying RSC graph traversals. |
crates/rspack_core/src/module.rs |
Adds RscModuleType and RscMeta to BuildInfo for per-module RSC metadata, and implements cacheable serialization for Wtf8Atoms and the action ID map. |
crates/rspack_core/src/compiler/rebuild.rs |
Wraps rebuild with calls to new CompilerDone/CompilerFailed hooks so compiler plugins (including RSC) are notified of rebuild outcomes. |
crates/rspack_core/src/compiler/mod.rs |
Defines CompilerDone/CompilerFailed hooks, adds CompilerId as a cacheable ID type, and wraps build to invoke these hooks on success/failure. |
crates/rspack_cacheable/src/with/as_preset/swc.rs |
Extends the generic SWC AsPreset serializer to support Wtf8Atom, used in RscMeta. |
crates/rspack_binding_api/src/swc.rs |
Updates the binding-side transform wrapper to pass comments and Arc<FileName> into JavaScriptCompiler::transform. |
crates/rspack_binding_api/src/raw_options/raw_builtins/mod.rs |
Adds BuiltinPluginName::RscServerPlugin/RscClientPlugin, wiring them to rspack_plugin_rsc via new JS-exposed options and the JsCoordinator. |
crates/rspack_binding_api/src/plugins/rsc.rs |
Implements the Node binding layer for RSC: JsCoordinator (bridging compiler IDs from JS) and JS-visible RSC plugin options that are converted into Rust options. |
crates/rspack_binding_api/src/plugins/mod.rs |
Re-exports JsCoordinator and the RSC plugin option types for use in the TS side. |
crates/rspack_binding_api/src/lib.rs |
Automatically registers the RSC loader plugins in the default JsCompiler and exposes a get_compiler_id method to JS. |
crates/rspack_binding_api/Cargo.toml |
Adds rspack_plugin_rsc as a dependency so bindings can construct its plugins. |
crates/node_binding/scripts/banner.d.ts |
Extends the banner with a CompilerId type alias and coordinates its exposure in the generated N-API declarations. |
crates/node_binding/rspack.wasi.cjs / rspack.wasi-browser.js |
Re-exports the new JsCoordinator constructor from the WASI bindings. |
crates/node_binding/napi-binding.d.ts |
Updates the N-API TypeScript declarations with CompilerId, the JsCoordinator class, RSC builtin plugin names, plugin option types, and JsCompiler.getCompilerId. |
Cargo.toml / Cargo.lock |
Wires the rspack_plugin_rsc crate into the workspace and adds shared dependencies (e.g. form_urlencoded) to the root manifest. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let module = &loader_context.context.module; | ||
| let is_react_server_layer = module | ||
| .get_layer() | ||
| .is_some_and(|layer| layer == "react-server-components"); |
There was a problem hiding this comment.
@copilot There might be a better approach to avoid hard coding the same string in multiple Rust crates.
Summary
This PR adds built-in RSC plugins to Rspack. We recommend using them via the Rsbuild plugin wrapper available at https://github.com/rstackjs/rsbuild-plugin-rsc.
For usage examples, please refer to: https://github.com/rstackjs/rsbuild-plugin-rsc/tree/main/examples
The
builtin:swc-loaderhas been enhanced to identify"use client"and"use server"directives. Within the RSC layer, it utilizes thereact-server-dom-rspackpackage to transform these modules into the appropriate client and server references required by React.RSC requires separate compilation for Server and Client bundles. This PR introduces
ServerPluginandClientPlugin(created viarsc.createPlugins()), which orchestrate the two compilers to:The
ServerPluginincludes anonServerComponentChangescallback. This is triggered whenever the Server Compiler detects changes in a Server Component.Related links
Checklist