mcpField
D
docs-rsc-sandpack

docs-rsc-sandpack

github.com/reactjs开发11.8k62 次安装1 天前更新
代码仓库

关于 docs-rsc-sandpack

面向 React 文档作者的 RSC Sandpack 模式指南,说明如何编写和组织 React Server Components 示例,并涵盖服务端、客户端组件及 Server Functions 的规则。

主要功能

  1. 01说明服务端与客户端文件指令
  2. 02介绍异步 Server Components 与 Suspense
  3. 03展示 Server Functions 模式
  4. 04规定入口文件与依赖限制

适用场景

  1. 01为文档添加 RSC 交互示例
  2. 02排查 Sandpack RSC 文件结构问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/reactjs/react.dev --skill docs-rsc-sandpack

安装后在 Claude Code 中输入/docs-rsc-sandpack确认已加载。

详细介绍

RSC Sandpack 模式

有关通用 Sandpack 约定(代码风格、命名、文件命名、行高亮、隐藏文件、CSS 指南),请参阅 /docs-sandpack。此技能仅介绍 RSC 特有的模式。

快速入门模板

最精简的单文件 <SandpackRSC> 示例:

<SandpackRSC>

` ` `js src/App.js
export default function App() {
  return <h1>Hello from a Server Component!</h1>;
}
` ` `

</SandpackRSC>

与 <Sandpack> 的区别

特性<Sandpack><SandpackRSC>
执行模型所有代码都在 iframe 中运行服务端代码在 Web Worker 中运行,客户端代码在 iframe 中运行
'use client' 指令忽略(所有内容都是客户端代码)必须使用此指令标记客户端组件
'use server' 指令不支持标记可从客户端调用的服务端函数
async 组件不支持支持(服务端组件可以是异步的)
外部依赖支持通过 package.json 添加不支持(仅支持 React 和 react-dom)
入口点带有 export default 的 App.js带有 export default 的 src/App.js
组件标签<Sandpack><SandpackRSC>

文件指令

根据文件顶部的指令对文件进行分类:

指令运行位置规则
(无)Web Worker(服务端)默认情况。可以是 async。可以导入其他服务端文件。不能使用 Hook、事件处理程序或浏览器 API。
'use client'Sandpack iframe(浏览器)必须是第一条语句。可以使用 Hook、事件处理程序和浏览器 API。不能是 async。不能导入服务端文件。
'use server'Web Worker(服务端)标记服务端函数。可用于模块级别(所有导出都是操作)或函数级别。可通过属性或表单 action 从客户端调用。

常见模式

1. 服务端 + 客户端组件
<SandpackRSC>

` ` `js src/App.js
import Counter from './Counter';

export default function App() {
  return (
    <div>
      <h1>Server-rendered heading</h1>
      <Counter />
    </div>
  );
}
` ` `

` ` `js src/Counter.js
'use client';

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  );
}
` ` `

</SandpackRSC>
2. 带 Suspense 的异步服务端组件
<SandpackRSC>

` ` `js src/App.js
import { Suspense } from 'react';
import Albums from './Albums';

export default function App() {
  return (
    <Suspense fallback={<p>Loading...</p>}>
      <Albums />
    </Suspense>
  );
}
` ` `

` ` `js src/Albums.js
async function fetchAlbums() {
  await new Promise(resolve => setTimeout(resolve, 1000));
  return ['Abbey Road', 'Let It Be', 'Revolver'];
}

export default async function Albums() {
  const albums = await fetchAlbums();
  return (
    <ul>
      {albums.map(album => (
        <li key={album}>{album}</li>
      ))}
    </ul>
  );
}
` ` `

</SandpackRSC>
3. 服务端函数(操作)
<SandpackRSC>

` ` `js src/App.js
import { addLike, getLikeCount } from './actions';
import LikeButton from './LikeButton';

export default async function App() {
  const count = await getLikeCount();
  return (
    <div>
      <p>Likes: {count}</p>
      <LikeButton addLike={addLike} />
    </div>
  );
}
` ` `

` ` `js src/actions.js
'use server';

let count = 0;

export async function addLike() {
  count++;
}

export async function getLikeCount() {
  return count;
}
` ` `

` ` `js src/LikeButton.js
'use client';

export default function LikeButton({ addLike }) {
  return (
    <form action={addLike}>
      <button type="submit">Like</button>
    </form>
  );
}
` ` `

</SandpackRSC>

文件结构要求

入口点
  • 必须有 src/App.js 作为主入口点
  • 必须包含 export default(函数组件)
  • 不区分大小写的回退:src/app.js 也可使用
自动注入的基础设施文件

这些文件由 sandpack-rsc-setup.ts 自动注入,绝不能包含在 MDX 中:

文件用途
/src/index.js引导 RSC 流程
/src/rsc-client.js客户端桥接层——创建 Worker,使用 Flight 流
/src/rsc-server.js将预打包的 Worker 运行时封装为 ES 模块
/node_modules/__webpack_shim__/index.js最精简的 webpack 兼容层
/node_modules/__rsdw_client__/index.js作为本地依赖的 react-server-dom-webpack/client
不支持外部依赖

<SandpackRSC> 不支持外部 npm 包。仅提供 react 和 react-dom。RSC 示例中不要包含 package.json。


架构参考

三层架构
react.dev page (Next.js)
  ┌─────────────────────────────────────────┐
  │  <SandpackRSC>                          │
  │  ┌─────────┐  ┌──────────────────────┐  │
  │  │ Editor  │  │ Preview (iframe)     │  │
  │  │ App.js  │  │ Client React app     │  │
  │  │ (edit)  │  │ consumes Flight      │  │
  │  │         │  │ stream from Worker   │  │
  │  └─────────┘  └──────────┬───────────┘  │
  └───────────────────────────┼─────────────┘
                              │ postMessage
  ┌───────────────────────────▼─────────────┐
  │  Web Worker (Blob URL)                  │
  │  - React server build (pre-bundled)     │
  │  - react-server-dom-webpack/server      │
  │  - webpack shim                         │
  │  - User server code (Sucrase → CJS)    │
  └─────────────────────────────────────────┘
关键源文件
文件用途
src/components/MDX/Sandpack/sandpack-rsc/RscFileBridge.tsx监控 Sandpack;向 iframe 发送原始文件
src/components/MDX/Sandpack/SandpackRSCRoot.tsxSandpackProvider 设置、自定义打包器 URL、UI 布局
src/components/MDX/Sandpack/templateRSC.tsRSC 模板文件
.../sandbox-code/src/__react_refresh_init__.jsReact Refresh 垫片
.../sandbox-code/src/rsc-server.jsWorker 运行时:模块系统、Sucrase 编译、renderToReadableStream()
.../sandbox-code/src/rsc-client.source.js客户端桥接:创建 Worker、文件分类、消费 Flight 流
.../sandbox-code/src/webpack-shim.js精简的 __webpack_require__ / __webpack_module_cache__ 垫片
.../sandbox-code/src/worker-bundle.dist.js预打包的 IIFE(生成文件):React server + RSDW/server + Sucrase
scripts/buildRscWorker.mjsesbuild 脚本:将 rsc-server.js 打包到 worker-bundle.dist.js

构建系统

重新构建 Worker 包

修改 rsc-server.js 或 webpack-shim.js 后:

node scripts/buildRscWorker.mjs

这会使用 esbuild,并设置:

  • format: 'iife'、platform: 'browser'
  • conditions: ['react-server', 'browser'](启用 React server 导出条件)
  • minify: true
  • 在输出内容前添加 webpack-shim.js
Raw-Loader 配置

在 templateRSC.js 中,文件会通过 !raw-loader 作为原始字符串加载。

这些字符串是必需的,用于将文件作为本地文件提供给 Sandpack(跳过 Sandpack 打包)。

开发命令
node scripts/buildRscWorker.mjs   # Rebuild worker bundle after source changes
yarn dev                           # Start dev server to test examples

评论

支持 Markdown