@rspress/plugin-playground

提供一个可实时编辑的 Playground 以预览 mdx 文件代码块中的组件。

安装

npm
yarn
pnpm
bun
npm add @rspress/plugin-playground -D

使用

引入插件

首先在配置文件中写入以下的配置:

rspress.config.ts
import { defineConfig } from 'rspress/config';
import { pluginPlayground } from '@rspress/plugin-playground';

export default defineConfig({
  plugins: [pluginPlayground()],
});
注意

此插件会将 markdown.mdxRs 配置为 false,未来 Rspress 团队会将该插件移植到 Rust 版本的编译器中。

内部组件

提示

建议使用 js 或 jsx 编写示例代码,避免编辑器中出现 ts 类型报错问题。

内部组件的组件代码声明在 mdx 文件内。支持 jsx 或 tsx。你可以在 mdx 文件中声明如下的代码块:

```jsx
import React from 'react';

function App() {
  return <div>Hello World</div>;
}

export default App;
```

另外,你可以通过 direction 参数,指定编辑器与预览区域的布局;支持 horizontalvertical

```jsx direction=vertical
import React from 'react';

function App() {
  return <div>Hello World</div>;
}

export default App;
```

值得注意的是,你需要将组件作为 default 导出,Rspress 会自动渲染这个组件。

但是如果你想保留代码块的样式,而不是将其作为组件渲染,你可以添加 pure 标识符来指定,使用方式如下:

```tsx pure
import React from 'react';

function App() {
  return <div>Hello World</div>;
}

export default App;
```

如果你配置了 defaultRenderMode'pure',那么默认情况下,Rspress 将不会渲染这个组件,而是将其作为代码块来渲染。这种情况下,如果需要将某个代码块渲染为组件,可以通过添加 playground 标识符来指定,使用方式如下:

```tsx playground
function App() {
  return <div>Hello World</div>;
}
export default App;
```
提示

需要保证文档为 .mdx 结尾的文件。

外部组件

除了将组件代码写在 mdx 文件的代码块中,你还可以将组件代码写在外部文件中,然后在 mdx 文件中通过 code 标签引入。比如

example.mdx
<code src="./Demo.jsx" />
Demo.jsx
import React from 'react';

export default function App() {
  return <div>Hello World</div>;
}

同样的,外部组件也支持 direction 属性:

example.mdx
<code src="./Demo.jsx" direction="vertical" />

外部组件中同样需要将组件作为 default 导出。而通过 code 标签的 src 属性,你可以指定外部组件的路径,该插件同时支持相对路径以及别名路径(alias)。

对于某些比较复杂的组件,这种外部组件的使用方式会更加方便。

定义整个页面中的布局

可以在 frontmatter 中编写 playgroundDirection,来定义整个页面中编辑器与预览区域的布局。

example.mdx
---
title: 标题
playgroundDirection: horizontal
---

优先级:直接定义在预览区域上 > 页面定义 > 配置中定义。

配置

这个插件接受一个对象参数,类型如下:

interface PlaygroundOptions {
  render: string;
  include: Array<string | [string, string]>;
  // 定义默认的 playground 布局(横向/纵向)
  defaultDirection: 'horizontal' | 'vertical';
  // 定义横向布局下,编辑器所处的位置(左侧/右侧)
  editorPosition: 'left' | 'right';
  // @babel/standalone 的 CDN 地址
  babelUrl: string;
  // 默认编辑器(monaco)部分配置
  monacoLoader: Parameters<typeof loader.config>[0];
  monacoOptions: MonacoEditorProps['options'];
}
注意

monacoLoadermonacoOptions 内部会被序列化为 JSON,因此不支持部分数据类型,如函数、循环引用的对象。

render

你可以自定义 render 文件,用于渲染 Playground;请注意,文件名必须为 Playground.(jsx?|tsx?)

pluginPlayground({
  render: '/path/to/render/Playground.tsx',
});

在自定义 Playground 中,你可以直接引用原始的编辑器和渲染器,以及通过 _rspress_playground_imports 引用提前打包好的依赖:

import getImport from '_rspress_playground_imports';
import { Runner, Editor } from '@rspress/plugin-playground/web';

可以参考自带的 Playground.tsx 进行自定义;

include

默认情况下,该插件会自动扫描所有 demo 中的 import 语句;demo 中没有使用到的依赖,在 Playground 中也无法使用;如果希望将其他依赖加入到 Playground 中,可以使用 include 参数:

pluginPlayground({
  include: [
    // 增加 dayjs 依赖
    'dayjs',
    // 增加包名为“my-package”,实际指向“/path/to/package/index.js”的依赖
    ['my-package', '/path/to/package/index.js'],
  ],
});

babelUrl

Playground 使用 @babel/standalone 对演示代码进行编译,默认从 cdnjs.com 加载。

你可以修改为其他 CDN 提供的 URL,例如 unpkg、jsdelivr 等。

monacoLoader

配置 monaco-loader 相关行为。默认从 cdnjs.com 加载。

你可以修改为其他 CDN 提供的 URL,例如 unpkg、jsdelivr 等。

完整文档可见 suren-atoyan/monaco-loader

monacoOptions

配置 monaco editor,对应 IStandaloneEditorConstructionOptions

defaultRenderMode

支持用户配置没有主动声明 pureplayground 标识符的内部代码块的默认行为,默认为 playground

  • pure: 渲染为普通代码块
  • playground: 渲染为 Playground 组件