or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-apis.mddata-communication.mdindex.mdnodejs-integration.mdserver-apis.mdstatic-rendering.mdwebpack-plugin.md

nodejs-integration.mddocs/

0

# Node.js Integration

1

2

Node.js-specific utilities for server component module loading, directive processing, and runtime integration with React Server Components.

3

4

## Capabilities

5

6

### Module Registration

7

8

Registers Node.js module compilation hooks to automatically process "use client" and "use server" directives during module loading.

9

10

```javascript { .api }

11

/**

12

* Registers Node.js module hooks for directive processing

13

* Hooks into the Node.js module system to handle RSC directives

14

*/

15

function register(): void;

16

```

17

18

**Usage Examples:**

19

20

```javascript

21

// Register hooks before importing any server components

22

const register = require("react-server-dom-webpack/node-register");

23

register();

24

25

// Now you can import modules with directives

26

const ServerComponent = require("./ServerComponent"); // Contains "use server"

27

const ClientComponent = require("./ClientComponent"); // Contains "use client"

28

```

29

30

**Package.json Integration:**

31

32

```json

33

{

34

"scripts": {

35

"dev": "node -r react-server-dom-webpack/node-register src/server.js",

36

"start": "node --require react-server-dom-webpack/node-register dist/server.js"

37

}

38

}

39

```

40

41

**Programmatic Registration:**

42

43

```javascript

44

// server.js

45

require("react-server-dom-webpack/node-register")();

46

47

// Import React Server Components after registration

48

const { renderToPipeableStream } = require("react-server-dom-webpack/server.node");

49

const App = require("./App"); // Can contain RSC directives

50

51

function handleRequest(req, res) {

52

const { pipe } = renderToPipeableStream(<App />, clientManifest);

53

pipe(res);

54

}

55

```

56

57

### Directive Processing

58

59

The registration system automatically processes modules containing RSC directives:

60

61

#### "use client" Directive Processing

62

63

Files with "use client" are converted to client module proxies:

64

65

```javascript

66

// components/Button.js

67

"use client";

68

69

import { useState } from "react";

70

71

export function Button({ children, onClick }) {

72

const [loading, setLoading] = useState(false);

73

// ... component implementation

74

}

75

76

// After processing, exports become client module proxies

77

// that reference the client-side bundle

78

```

79

80

#### "use server" Directive Processing

81

82

Files with "use server" have their functions registered as server references:

83

84

```javascript

85

// actions/userActions.js

86

"use server";

87

88

export async function updateUser(userData) {

89

// This function is registered as a server reference

90

return await database.users.update(userData);

91

}

92

93

export async function deleteUser(userId) {

94

// This function is also registered as a server reference

95

return await database.users.delete(userId);

96

}

97

98

// After processing, functions can be called from client components

99

```

100

101

### Module Loading Patterns

102

103

Different patterns for loading and using the registration system:

104

105

#### Early Registration Pattern

106

107

```javascript

108

// server/index.js

109

// Register before any imports

110

require("react-server-dom-webpack/node-register")();

111

112

// Safe to import RSC modules after registration

113

const express = require("express");

114

const { renderToPipeableStream } = require("react-server-dom-webpack/server.node");

115

const App = require("../components/App");

116

117

const app = express();

118

119

app.get("/", (req, res) => {

120

const { pipe } = renderToPipeableStream(<App />, clientManifest);

121

res.setHeader("Content-Type", "text/html");

122

pipe(res);

123

});

124

```

125

126

#### Conditional Registration Pattern

127

128

```javascript

129

// utils/setup.js

130

let registered = false;

131

132

function ensureRegistered() {

133

if (!registered) {

134

require("react-server-dom-webpack/node-register")();

135

registered = true;

136

}

137

}

138

139

module.exports = { ensureRegistered };

140

141

// Use in multiple entry points

142

const { ensureRegistered } = require("./utils/setup");

143

ensureRegistered();

144

```

145

146

#### Development vs Production Pattern

147

148

```javascript

149

// server/setup.js

150

if (process.env.NODE_ENV === "development") {

151

// Enable directive processing in development

152

require("react-server-dom-webpack/node-register")();

153

}

154

155

// In production, components are pre-processed during build

156

```

157

158

### Error Handling

159

160

The registration system provides comprehensive error handling for directive processing:

161

162

#### Conflicting Directives

163

164

```javascript

165

// This will throw an error

166

"use client";

167

"use server"; // Cannot have both directives

168

169

// Error message:

170

// "Cannot have both 'use client' and 'use server' directives in the same file."

171

```

172

173

#### Parse Errors

174

175

```javascript

176

// Malformed syntax in directive file

177

"use client";

178

export function Component() {

179

// Syntax error here

180

return <div>Hello</div>

181

}

182

183

// Error logged to console:

184

// "Error parsing [filename] [error message]"

185

```

186

187

### ESM Loader Integration

188

189

For ESM modules, use the dedicated loader instead of the CommonJS register:

190

191

```javascript

192

// package.json

193

{

194

"type": "module",

195

"scripts": {

196

"dev": "node --loader react-server-dom-webpack/node-loader src/server.js"

197

}

198

}

199

```

200

201

**ESM Server Setup:**

202

203

```javascript

204

// server.js (ESM)

205

import { renderToPipeableStream } from "react-server-dom-webpack/server.node";

206

import App from "./components/App.js";

207

208

// ESM loader automatically processes directives

209

export function handleRequest(req, res) {

210

const { pipe } = renderToPipeableStream(<App />, clientManifest);

211

pipe(res);

212

}

213

```

214

215

### Advanced Integration Patterns

216

217

#### Framework Integration

218

219

```javascript

220

// next.config.js (example integration)

221

module.exports = {

222

experimental: {

223

serverComponentsExternalPackages: ["react-server-dom-webpack"]

224

},

225

webpack: (config, { isServer }) => {

226

if (isServer) {

227

// Ensure registration happens in server environment

228

config.plugins.push({

229

apply(compiler) {

230

compiler.hooks.beforeRun.tap("RSCRegister", () => {

231

require("react-server-dom-webpack/node-register")();

232

});

233

}

234

});

235

}

236

return config;

237

}

238

};

239

```

240

241

#### Testing Integration

242

243

```javascript

244

// test/setup.js

245

const register = require("react-server-dom-webpack/node-register");

246

247

// Register before running tests

248

beforeAll(() => {

249

register();

250

});

251

252

// test/server-components.test.js

253

const ServerComponent = require("../components/ServerComponent");

254

255

test("server component renders correctly", async () => {

256

// ServerComponent contains "use server" directive

257

const result = await ServerComponent.someAction();

258

expect(result).toBeDefined();

259

});

260

```

261

262

#### Hot Reload Integration

263

264

```javascript

265

// dev-server.js

266

const chokidar = require("chokidar");

267

268

// Watch for changes and re-register

269

chokidar.watch("./src/**/*.js").on("change", (path) => {

270

// Clear module cache

271

delete require.cache[require.resolve(path)];

272

273

// Re-register to pick up directive changes

274

require("react-server-dom-webpack/node-register")();

275

});

276

```

277

278

### Performance Considerations

279

280

#### Module Caching

281

282

The registration system respects Node.js module caching:

283

284

```javascript

285

// First import processes and caches the module

286

const Component1 = require("./MyComponent");

287

288

// Second import uses cached result

289

const Component2 = require("./MyComponent"); // Same instance

290

```

291

292

#### Directive Detection Optimization

293

294

The system performs fast string checks before parsing:

295

296

```javascript

297

// Fast path: no parsing needed

298

if (content.indexOf('use client') === -1 && content.indexOf('use server') === -1) {

299

return originalCompile.apply(this, arguments);

300

}

301

302

// Only parse files that might contain directives

303

```

304

305

## Types

306

307

```javascript { .api }

308

// No exported types - register() is a side-effect function

309

// The registration affects the module loading behavior globally

310

311

interface ModuleCompilerHook {

312

/** Original Node.js module compilation function */

313

_compile(content: string, filename: string): void;

314

}

315

316

interface DirectiveInfo {

317

/** Whether file contains "use client" */

318

useClient: boolean;

319

/** Whether file contains "use server" */

320

useServer: boolean;

321

/** Parsed AST body for directive detection */

322

body: any[];

323

}

324

```

325

326

## Integration Notes

327

328

### Build vs Runtime

329

330

- **Development**: Use `node-register` for runtime directive processing

331

- **Production**: Pre-process directives during build for better performance

332

- **Testing**: Register hooks in test setup for consistent behavior

333

334

### Compatibility

335

336

- **CommonJS**: Use `require("react-server-dom-webpack/node-register")()`

337

- **ESM**: Use `--loader react-server-dom-webpack/node-loader`

338

- **Mixed**: Can use both in hybrid applications

339

340

### Debugging

341

342

Enable verbose logging for directive processing:

343

344

```javascript

345

// Set environment variable for debugging

346

process.env.DEBUG = "react-server-dom-webpack:*";

347

348

require("react-server-dom-webpack/node-register")();

349

```