代码展示规范
本文档站统一用 Docusaurus + Prism 展示代码。分两类能力:
- 零依赖(已启用):普通围栏代码块的高级写法(标题 / 行号 / 高亮 / diff / 多语言 Tabs)、Mermaid 图。开箱即用,不需要装任何包。
- 需安装(升级路径):
@docusaurus/theme-live-codeblock(可编辑运行的代码块)、remark-code-import(从真实源码文件导入代码)。本沙箱禁止npm install,配置已写好,你只需在本地npm install后即可生效。
一、零依赖:把代码块写“优雅”
标题 + 行号
围栏信息串加 title="..." 与 showLineNumbers,右上角出现文件名,左侧出现行号:
```js title="examples/basic/rect.js" showLineNumbers
const rect = new ICE.ICERect({ left: 0, top: 0, width: 160, height: 90 });
ice.addChild(rect);
```
const rect = new ICE.ICERect({ left: 0, top: 0, width: 160, height: 90 });
ice.addChild(rect);
高亮指定行
{行号} 或 { 起-止} 高亮关键代码;{-起-止} 表示“除这些行外全部高亮”:
```js {2-3}
const a = 1;
const rect = new ICE.ICERect({ left: 0, top: 0, width: 160 });
ice.addChild(rect);
```
const a = 1;
const rect = new ICE.ICERect({ left: 0, top: 0, width: 160 });
ice.addChild(rect);
diff 片段
语言后加 diff,以 + / - 开头的行自动着色,适合展示“改动前后”:
```diff
- const rect = new ICE.ICERect({ width: 160 });
+ const rect = new ICE.ICERect({ left: 0, top: 0, width: 160, height: 90 });
```
- const rect = new ICE.ICERect({ width: 160 });
+ const rect = new ICE.ICERect({ left: 0, top: 0, width: 160, height: 90 });
多语言 Tabs
用 <Tabs> + <TabItem> 给同一段逻辑提供多语言视角(需 .mdx):
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="js" label="JavaScript" default>
```js
const ice = new ICE.ICE();
```
</TabItem>
<TabItem value="ts" label="TypeScript">
```ts
const ice: ICE.ICE = new ICE.ICE();
```
</TabItem>
</Tabs>
- JavaScript
- TypeScript
const ice = new ICE.ICE();
const ice: ICE.ICE = new ICE.ICE();
实时 渲染(本仓库特色)
普通代码块只展示文本;要“既看代码又看效果”,用本仓库封装的 <IceCanvas>(见核心概念 · 第一个实时示例 与图元)。它本质是一个 BrowserOnly 包裹的客户端组件,加载 static/ice-render.js 后即可在浏览器里跑真实 ICE 代码。
二、可编辑运行的代码块(live-codeblock)✅ 已启用
适合给读者一个能直接改、立刻看效果的 React/JSX 沙箱。@docusaurus/theme-live-codeblock 基于 react-live,纯前端、无服务端。
1. 安装:@docusaurus/theme-live-codeblock@3.10.2 已装入 dependencies(版本与 Docusaurus 对齐)。
2. 启用 —— themes 已加入 '@docusaurus/theme-live-codeblock';同时把 ice-render.js 以 defer 全局脚本加载,使 window.ICE 在任何页面都可用。
3. 作用域注入 ICE —— swizzle 了 @theme/ReactLiveScope,用 getter 延迟暴露 window.ICE,因此 jsx live 块里能直接写 ICE.ICERect / new ICE.ICE()(首屏前 window.ICE 可能未就绪,块内有 if (!window.ICE) return 兜底)。
4. 用法 —— 语言写 jsx live,title 可选。下面两个块就是真实可编辑示例,改一改右侧立刻重渲染:
React 片段
function Counter() { const [n, setN] = React.useState(0); return ( <button onClick={() => setN(n + 1)} style={{ padding: 8, fontSize: 16 }}> 点击了 {n} 次 </button> ); }
ICE 片段(直接操作内核)
下面这段在 live 块里创建了一个 ICE 实例并画了一个矩形——改 fillStyle 或尺寸,画布立刻重绘:
function IceDemo() { const ref = React.useRef(null); React.useEffect(() => { if (!window.ICE) return; const ice = new window.ICE.ICE(); ice.init(ref.current); ice.addChild( new window.ICE.ICERect({ left: 20, top: 20, width: 160, height: 100, radius: 12, fill: true, stroke: true, style: { fillStyle: '#4f8cff', strokeStyle: '#1f4fb0', lineWidth: 2 }, }) ); return () => ice.destroy(); }, []); return ( <canvas ref={ref} width={200} height={140} style={{ border: '1px solid #ccc', borderRadius: 8 }} /> ); }
用法细节
围栏语言写 jsx live 即可(可加 title):
```jsx live title="可编辑示例"
function Demo() {
return <button>点我</button>;
}
```
- 默认「内联模式」:代码块最后一行表达式被渲染(如上例的
<Counter />)。 - 需要多条语句 / 自己
render时,加noInline:```jsx live noInline,然后在代码里调用render(<Demo />)。 - 想让更多标识符进作用域(如某个自定义组件),swizzle
@theme/ReactLiveScope即可(本仓库已注入ICE)。
和
<IceCanvas>(见核心概念 · 第一个实时示例)的区别:那里用<IceCanvas>组件封装了加载 / 生命周期 /destroy,适合「展示一个固定示例」;这里的jsx live适合「让读者自己改代码看效果」。两者底层都是同一个 ICE 内核。