React Server Components bindings for DOM using Webpack, enabling server-side rendering with streaming support and client-server communication.
—
Node.js-specific utilities for server component module loading, directive processing, and runtime integration with React Server Components.
Registers Node.js module compilation hooks to automatically process "use client" and "use server" directives during module loading.
/**
* Registers Node.js module hooks for directive processing
* Hooks into the Node.js module system to handle RSC directives
*/
function register(): void;Usage Examples:
// Register hooks before importing any server components
const register = require("react-server-dom-webpack/node-register");
register();
// Now you can import modules with directives
const ServerComponent = require("./ServerComponent"); // Contains "use server"
const ClientComponent = require("./ClientComponent"); // Contains "use client"Package.json Integration:
{
"scripts": {
"dev": "node -r react-server-dom-webpack/node-register src/server.js",
"start": "node --require react-server-dom-webpack/node-register dist/server.js"
}
}Programmatic Registration:
// server.js
require("react-server-dom-webpack/node-register")();
// Import React Server Components after registration
const { renderToPipeableStream } = require("react-server-dom-webpack/server.node");
const App = require("./App"); // Can contain RSC directives
function handleRequest(req, res) {
const { pipe } = renderToPipeableStream(<App />, clientManifest);
pipe(res);
}The registration system automatically processes modules containing RSC directives:
Files with "use client" are converted to client module proxies:
// components/Button.js
"use client";
import { useState } from "react";
export function Button({ children, onClick }) {
const [loading, setLoading] = useState(false);
// ... component implementation
}
// After processing, exports become client module proxies
// that reference the client-side bundleFiles with "use server" have their functions registered as server references:
// actions/userActions.js
"use server";
export async function updateUser(userData) {
// This function is registered as a server reference
return await database.users.update(userData);
}
export async function deleteUser(userId) {
// This function is also registered as a server reference
return await database.users.delete(userId);
}
// After processing, functions can be called from client componentsDifferent patterns for loading and using the registration system:
// server/index.js
// Register before any imports
require("react-server-dom-webpack/node-register")();
// Safe to import RSC modules after registration
const express = require("express");
const { renderToPipeableStream } = require("react-server-dom-webpack/server.node");
const App = require("../components/App");
const app = express();
app.get("/", (req, res) => {
const { pipe } = renderToPipeableStream(<App />, clientManifest);
res.setHeader("Content-Type", "text/html");
pipe(res);
});// utils/setup.js
let registered = false;
function ensureRegistered() {
if (!registered) {
require("react-server-dom-webpack/node-register")();
registered = true;
}
}
module.exports = { ensureRegistered };
// Use in multiple entry points
const { ensureRegistered } = require("./utils/setup");
ensureRegistered();// server/setup.js
if (process.env.NODE_ENV === "development") {
// Enable directive processing in development
require("react-server-dom-webpack/node-register")();
}
// In production, components are pre-processed during buildThe registration system provides comprehensive error handling for directive processing:
// This will throw an error
"use client";
"use server"; // Cannot have both directives
// Error message:
// "Cannot have both 'use client' and 'use server' directives in the same file."// Malformed syntax in directive file
"use client";
export function Component() {
// Syntax error here
return <div>Hello</div>
}
// Error logged to console:
// "Error parsing [filename] [error message]"For ESM modules, use the dedicated loader instead of the CommonJS register:
// package.json
{
"type": "module",
"scripts": {
"dev": "node --loader react-server-dom-webpack/node-loader src/server.js"
}
}ESM Server Setup:
// server.js (ESM)
import { renderToPipeableStream } from "react-server-dom-webpack/server.node";
import App from "./components/App.js";
// ESM loader automatically processes directives
export function handleRequest(req, res) {
const { pipe } = renderToPipeableStream(<App />, clientManifest);
pipe(res);
}// next.config.js (example integration)
module.exports = {
experimental: {
serverComponentsExternalPackages: ["react-server-dom-webpack"]
},
webpack: (config, { isServer }) => {
if (isServer) {
// Ensure registration happens in server environment
config.plugins.push({
apply(compiler) {
compiler.hooks.beforeRun.tap("RSCRegister", () => {
require("react-server-dom-webpack/node-register")();
});
}
});
}
return config;
}
};// test/setup.js
const register = require("react-server-dom-webpack/node-register");
// Register before running tests
beforeAll(() => {
register();
});
// test/server-components.test.js
const ServerComponent = require("../components/ServerComponent");
test("server component renders correctly", async () => {
// ServerComponent contains "use server" directive
const result = await ServerComponent.someAction();
expect(result).toBeDefined();
});// dev-server.js
const chokidar = require("chokidar");
// Watch for changes and re-register
chokidar.watch("./src/**/*.js").on("change", (path) => {
// Clear module cache
delete require.cache[require.resolve(path)];
// Re-register to pick up directive changes
require("react-server-dom-webpack/node-register")();
});The registration system respects Node.js module caching:
// First import processes and caches the module
const Component1 = require("./MyComponent");
// Second import uses cached result
const Component2 = require("./MyComponent"); // Same instanceThe system performs fast string checks before parsing:
// Fast path: no parsing needed
if (content.indexOf('use client') === -1 && content.indexOf('use server') === -1) {
return originalCompile.apply(this, arguments);
}
// Only parse files that might contain directives// No exported types - register() is a side-effect function
// The registration affects the module loading behavior globally
interface ModuleCompilerHook {
/** Original Node.js module compilation function */
_compile(content: string, filename: string): void;
}
interface DirectiveInfo {
/** Whether file contains "use client" */
useClient: boolean;
/** Whether file contains "use server" */
useServer: boolean;
/** Parsed AST body for directive detection */
body: any[];
}node-register for runtime directive processingrequire("react-server-dom-webpack/node-register")()--loader react-server-dom-webpack/node-loaderEnable verbose logging for directive processing:
// Set environment variable for debugging
process.env.DEBUG = "react-server-dom-webpack:*";
require("react-server-dom-webpack/node-register")();Install with Tessl CLI
npx tessl i tessl/npm-react-server-dom-webpack