Skip to content

Commit 39508ff

Browse files
committed
pin deps, update skill
1 parent f441501 commit 39508ff

File tree

2 files changed

+20
-150
lines changed

2 files changed

+20
-150
lines changed

.claude/skills/docs-rsc-sandpack/SKILL.md

Lines changed: 18 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export default function App() {
3131
|---------|-------------|-----------------|
3232
| Execution model | All code runs in iframe | Server code runs in Web Worker, client code in iframe |
3333
| `'use client'` directive | Ignored (everything is client) | Required to mark client components |
34-
| `'use server'` directive | Not supported | Marks server actions callable from client |
34+
| `'use server'` directive | Not supported | Marks Server Functions callable from client |
3535
| `async` components | Not supported | Supported (server components can be async) |
3636
| External dependencies | Supported via `package.json` | Not supported (only React + react-dom) |
3737
| Entry point | `App.js` with `export default` | `src/App.js` with `export default` |
@@ -47,9 +47,7 @@ Files are classified by the directive at the top of the file:
4747
|-----------|--------------|-------|
4848
| (none) | Web Worker (server) | Default. Can be `async`. Can import other server files. Cannot use hooks, event handlers, or browser APIs. |
4949
| `'use client'` | Sandpack iframe (browser) | Must be first statement. Can use hooks, event handlers, browser APIs. Cannot be `async`. Cannot import server files. |
50-
| `'use server'` | Web Worker (server) | Marks server actions. Can be module-level (all exports are actions) or function-level. Callable from client via props or form `action`. |
51-
52-
**Directive detection** is a string match on the first non-comment statement. The directive must appear exactly as `'use client';` or `'use server';` (single or double quotes, semicolon optional).
50+
| `'use server'` | Web Worker (server) | Marks Server Functions. Can be module-level (all exports are actions) or function-level. Callable from client via props or form `action`. |
5351

5452
---
5553

@@ -200,56 +198,13 @@ These files are automatically injected by `sandpack-rsc-setup.ts` and should nev
200198
| `/src/rsc-server.js` | Wraps pre-bundled worker runtime as ES module |
201199
| `/node_modules/__webpack_shim__/index.js` | Minimal webpack compatibility layer |
202200
| `/node_modules/__rsdw_client__/index.js` | `react-server-dom-webpack/client` as local dependency |
203-
| `/src/styles.css` | Base styles |
204201

205202
### No External Dependencies
206203

207204
`<SandpackRSC>` does not support external npm packages. Only `react` and `react-dom` are available. Do not include `package.json` in RSC examples.
208205

209206
---
210207

211-
## Constraints and Pitfalls
212-
213-
### What Server Components Cannot Do
214-
215-
| Cannot | Reason |
216-
|--------|--------|
217-
| Use hooks (`useState`, `useEffect`, etc.) | Server components are stateless, run once |
218-
| Attach event handlers (`onClick`, `onChange`) | No interactivity on server |
219-
| Access browser APIs (`window`, `document`, `localStorage`) | Runs in Web Worker, not browser |
220-
| Import client components without `'use client'` | Client code must be explicitly marked |
221-
| Use `useContext` | Context is a client concept |
222-
223-
### What Client Components Cannot Do
224-
225-
| Cannot | Reason |
226-
|--------|--------|
227-
| Be `async` | Client components render synchronously |
228-
| Import server-only files directly | Would execute server code in browser |
229-
| Use `'use server'` at module level | That marks a server actions file |
230-
| Read from databases or file systems | Runs in browser |
231-
232-
### Sucrase Compilation Limitations
233-
234-
| Limitation | Detail |
235-
|------------|--------|
236-
| No TypeScript type erasure for complex generics | Sucrase handles basic TS but not all edge cases |
237-
| No decorators | Not supported by Sucrase |
238-
| No dynamic `import()` | Worker module system uses synchronous `require()` |
239-
| CommonJS output only (server side) | Server files compiled to CJS with `var` declarations |
240-
241-
### Other Constraints
242-
243-
| Constraint | Detail |
244-
|------------|--------|
245-
| FormData serialization | FormData is not structurally cloneable for `postMessage`; serialized as `[key, value]` entries and reconstructed in Worker |
246-
| Module resolution | Custom `resolvePath()` — only relative paths (`./`, `../`) with `.js`, `.jsx`, `.ts`, `.tsx` extensions. No `node_modules` resolution. |
247-
| CSS imports | `require('*.css')` returns empty object. No CSS bundling in the Worker. |
248-
| Circular dependencies | Partially supported — partially populated exports returned during circular `require()` |
249-
| React version | Client: `^19.2.1` via Sandpack CDN. Server: pinned to pre-bundled version in `worker-bundle.source.js`. Must stay in sync. |
250-
251-
---
252-
253208
## Architecture Reference
254209

255210
### Three-Layer Architecture
@@ -275,46 +230,27 @@ react.dev page (Next.js)
275230
└─────────────────────────────────────────┘
276231
```
277232

278-
### Data Flow (14 Steps)
279-
280-
1. MDX parser extracts code blocks from `<SandpackRSC>` children
281-
2. `createFileMap()` converts code blocks to Sandpack file map
282-
3. `sandpack-rsc-setup.ts` injects infrastructure files (client bridge, worker bundle, webpack shim)
283-
4. `SandpackProvider` initializes Sandpack with custom bundler URL
284-
5. Sandpack compiles client files and boots the iframe
285-
6. `RscFileBridge` listens for Sandpack `done` events
286-
7. `RscFileBridge` posts all raw file contents to iframe via `postMessage`
287-
8. `rsc-client.source.js` receives files, classifies by directive
288-
9. Client files compiled by Sucrase and registered as webpack modules
289-
10. Server files + manifest sent to Worker via `postMessage` (`deploy` message)
290-
11. Worker compiles server files with Sucrase to CJS, executes with `new Function()`
291-
12. Worker calls `renderToReadableStream()` from `react-server-dom-webpack/server.browser`
292-
13. Flight stream chunks sent back to client via `postMessage` with Transferable `Uint8Array` buffers
293-
14. Client consumes stream with `createFromReadableStream()`, renders via React DOM `startTransition`
294-
295233
### Key Source Files
296234

297-
| File | Purpose |
298-
|------------------------------------------------------------------|---------|
299-
| `src/components/MDX/Sandpack/sandpack-rsc/index.tsx` | Lazy-loading wrapper, file map extraction |
300-
| `src/components/MDX/Sandpack/sandpack-rsc/SandpackRSCRoot.tsx` | SandpackProvider setup, custom bundler URL, UI layout |
301-
| `src/components/MDX/Sandpack/sandpack-rsc/RscFileBridge.tsx` | Monitors Sandpack; posts raw files to iframe |
302-
| `src/components/MDX/Sandpack/sandpack-rsc/sandpack-rsc-setup.ts` | Loads raw source files, assembles infrastructure file map |
303-
| `.../sandbox-code/src/worker-server.source.js` | Worker runtime: module system, Sucrase compilation, `renderToReadableStream()` |
304-
| `.../sandbox-code/src/rsc-client.source.js` | Client bridge: Worker creation, file classification, Flight stream consumption |
305-
| `.../sandbox-code/src/webpack-shim.source.js` | Minimal `__webpack_require__` / `__webpack_module_cache__` shim |
306-
| `.../sandbox-code/src/worker-bundle.source.js` | Pre-bundled IIFE (generated): React server + RSDW/server + Sucrase |
307-
| `scripts/buildRscWorker.mjs` | esbuild script: bundles worker-server.source.js into worker-bundle.source.js |
308-
| `next.config.js` (lines 49-60) | Webpack `raw-loader` rule for `.source.js` files |
309-
| `src/components/MDX/MDXComponents.tsx` | Registers `<SandpackRSC>` as MDX component |
235+
| File | Purpose |
236+
|-----------------------------------------------------------------|--------------------------------------------------------------------------------|
237+
| `src/components/MDX/Sandpack/sandpack-rsc/RscFileBridge.tsx` | Monitors Sandpack; posts raw files to iframe |
238+
| `src/components/MDX/Sandpack/SandpackRSCRoot.tsx` | SandpackProvider setup, custom bundler URL, UI layout |
239+
| `src/components/MDX/Sandpack/templateRSC.ts` | RSC template files |
240+
| `.../sandbox-code/src/__react_refresh_init__.js` | React Refresh shim |
241+
| `.../sandbox-code/src/rsc-server.js` | Worker runtime: module system, Sucrase compilation, `renderToReadableStream()` |
242+
| `.../sandbox-code/src/rsc-client.source.js` | Client bridge: Worker creation, file classification, Flight stream consumption |
243+
| `.../sandbox-code/src/webpack-shim.js` | Minimal `__webpack_require__` / `__webpack_module_cache__` shim |
244+
| `.../sandbox-code/src/worker-bundle.dist.js` | Pre-bundled IIFE (generated): React server + RSDW/server + Sucrase |
245+
| `scripts/buildRscWorker.mjs` | esbuild script: bundles rsc-server.js into worker-bundle.dist.js |
310246

311247
---
312248

313249
## Build System
314250

315251
### Rebuilding the Worker Bundle
316252

317-
After modifying `worker-server.source.js` or `webpack-shim.source.js`:
253+
After modifying `rsc-server.js` or `webpack-shim.js`:
318254

319255
```bash
320256
node scripts/buildRscWorker.mjs
@@ -324,84 +260,18 @@ This runs esbuild with:
324260
- `format: 'iife'`, `platform: 'browser'`
325261
- `conditions: ['react-server', 'browser']` (activates React server export conditions)
326262
- `minify: true`
327-
- Prepends `webpack-shim.source.js` to the output
263+
- Prepends `webpack-shim.js` to the output
328264

329265
### Raw-Loader Configuration
330266

331-
In `next.config.js`, `.source.js` files are loaded as raw strings:
332-
333-
```javascript
334-
config.module.rules.unshift({
335-
test: /\.source\.js$/,
336-
enforce: 'pre', // Bypass Babel/react-refresh
337-
use: [{ loader: 'raw-loader', options: { esModule: false } }],
338-
});
339-
```
340-
341-
`enforce: 'pre'` ensures raw-loader runs before any other loaders (Babel, react-refresh).
342-
343-
### Custom Bundler URL
267+
In `templateRSC.js` files are loaded as raw strings with the `!raw-loader`.
344268

345-
```
346-
https://786946de.sandpack-bundler-4bw.pages.dev
347-
```
348-
349-
A custom Sandpack bundler deployment on Cloudflare Pages. Configured in `SandpackRSCRoot.tsx`.
350-
351-
### RSDW Client Inline Import
352-
353-
The `react-server-dom-webpack` client module is loaded directly from `node_modules` via an inline raw-loader import in `sandpack-rsc-setup.ts`:
354-
355-
```typescript
356-
const rsdwClientCode = require(
357-
'!!raw-loader!react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.js'
358-
).default;
359-
```
360-
361-
---
269+
The strings are necessary to provide to Sandpack as local files (skips Sandpack bundling).
362270

363-
## Debugging
364-
365-
### Common Errors
366-
367-
| Error | Cause | Fix |
368-
|-------|-------|-----|
369-
| `Cannot find module './Component'` | Missing file or wrong path in import | Check file names match exactly (case-sensitive) |
370-
| `X is not a function` | Server component imported without `'use client'` in client file | Add `'use client'` directive to the importing file, or restructure imports |
371-
| Flight stream parse error | Server code threw during render | Check server component for runtime errors (bad data, missing imports) |
372-
| `__webpack_require__ is not defined` | Worker bundle not rebuilt after shim changes | Run `node scripts/buildRscWorker.mjs` |
373-
| Blank preview, no errors | Infrastructure files not injected | Verify `sandpack-rsc-setup.ts` loads all `.source.js` files |
374-
| `FormData is not defined` | Using FormData in server action without proper serialization | The system handles this automatically; check for custom FormData usage |
375-
| Hooks in server component | `useState`/`useEffect` used without `'use client'` | Move interactive code to a client component |
376-
377-
### Debugging Steps
378-
379-
1. **Check browser console** — Flight stream errors and Worker errors surface here
380-
2. **Check the Worker** — In DevTools, navigate to Sources > Worker threads to inspect the Worker
381-
3. **Verify directives** — Ensure `'use client'` / `'use server'` are the first statement (no imports before them)
382-
4. **Test in isolation** — Create a minimal `<SandpackRSC>` with just `App.js` to rule out file interaction issues
383-
5. **Rebuild worker bundle** — After any changes to `.source.js` files: `node scripts/buildRscWorker.mjs`
384271

385272
### Development Commands
386273

387274
```bash
388275
node scripts/buildRscWorker.mjs # Rebuild worker bundle after source changes
389276
yarn dev # Start dev server to test examples
390-
yarn build # Full production build (includes worker)
391-
```
392-
393-
---
394-
395-
## Anti-Patterns
396-
397-
| Pattern | Problem | Fix |
398-
|---------|---------|-----|
399-
| `'use client'` in `App.js` | Makes entire app client-rendered, defeats RSC purpose | Keep `App.js` as server component; extract interactive parts to separate client files |
400-
| Hooks in server component | Runtime error — hooks not available in Worker | Move to `'use client'` component |
401-
| `import` before `'use client'` | Directive not detected (must be first statement) | Move `'use client'` to line 1 |
402-
| `package.json` in `<SandpackRSC>` | External dependencies not supported | Remove; use only React built-ins |
403-
| `window`/`document` in server file | Not available in Web Worker | Move to `'use client'` component |
404-
| Server component importing client component without directive | Client code executes in Worker and fails | Add `'use client'` to the client file |
405-
| Passing non-serializable props to client components | Flight protocol can only serialize JSON-compatible values + React elements + server references | Use serializable data; pass server actions for functions |
406-
| `async` client component | Client components cannot be async | Only server components can be `async` |
407-
| `<Sandpack>` instead of `<SandpackRSC>` | Standard Sandpack has no RSC support | Use `<SandpackRSC>` for RSC examples |
277+
```

src/components/MDX/Sandpack/templateRSC.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ export const templateRSC: SandpackFiles = {
9191
version: '0.0.0',
9292
main: '/src/index.js',
9393
dependencies: {
94-
react: '^19.2.4',
95-
'react-dom': '^19.2.4',
94+
react: '19.2.4',
95+
'react-dom': '19.2.4',
9696
},
9797
},
9898
null,

0 commit comments

Comments
 (0)