remark-codesandbox
🎩 一个用于直接从代码块创建 CodeSandbox 的 remark 插件
在 CodeSandbox 上在线试用!(是的,我们在 CodeSandbox 内部演示 CodeSandbox,为什么不呢!?)
特性
- 🔗 直接从代码块创建 CodeSandbox URL
- ✨ 支持 3 种不同的模式:meta、iframe 和 button
- 🚀 无需创建额外的文件夹或
package.json
文件 - 🎉 支持 MDX、Gatsby、Storybook 文档、docz 等...
- 📦 支持引入您自己的自定义模板,甚至可以直接从同一个仓库中引入!
- ⚡ 一行代码设置,高度可定制
- 💪 非常适合库作者直接从文档中演示用法!
示例
reaviz
文档使用 Storybook 文档 和remark-codesandbox
构建。- 该项目的 测试用例。
安装
yarn add -D remark-codesandbox
入门
将 remark-codesandbox
导入到您的 remark 插件中。
const codesandbox = require('remark-codesandbox');
remark().use(codesandbox, { mode: 'button' });
mdx(mdxCode, {
remarkPlugins: [[codesandbox, { mode: 'button' }]],
});
使用 /gatsby
端点来使用 Gatsby 版本的插件。
module.exports = {
plugins: [
{
resolve: 'gatsby-plugin-mdx',
options: {
gatsbyRemarkPlugins: [
{
resolve: 'remark-codesandbox/gatsby',
options: {
mode: 'button',
},
},
],
},
},
],
};
Gatsby (gatsby-transformer-remark)
使用 /gatsby
端点来使用 Gatsby 版本的插件。
module.exports = {
plugins: [
{
resolve: 'gatsby-transformer-remark',
options: {
plugins: [
{
resolve: 'remark-codesandbox/gatsby',
options: {
mode: 'button',
},
},
],
},
},
],
};
config.module.rules.push({
test: /\.(stories|story)\.mdx$/,
use: [
{
loader: '@mdx-js/loader',
options: {
compilers: [createCompiler({})],
remarkPlugins: [[codesandbox, { mode: 'button' }]],
},
},
],
});
用法
为您的代码块添加一个特殊的元数据标签。
```js codesandbox=react
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello remark-codesandbox!</h1>,
document.getElementById('root')
);
```
就这样!
上面的示例将 mode
设置为 button
,会在代码块后面附加一个 CodeSandbox 按钮。点击它将打开生成的沙箱。太酷了!
还有其他模式和额外的配置,请参阅下面的 文档 以获取更多信息。
文档
Markdown 语法
将 codesandbox
元数据附加到代码块以启用 remark-codesandbox
。此处的值为沙箱的 id
。
```js codesandbox=new
// ...
```
有一组默认的官方沙箱模板,您可以在 此处 找到列表。一些示例是 new
(react)、vanilla
(parcel)、vue
、static
...
代码块的内容将完全替换入口文件。因此,对于 new
模板,内容将完全替换 src/index.js
文件。请确保导入必要的包以使模板正常工作。
插件还提供了一些默认的别名。react
是 new
的别名。react-component
也是 new
的别名,但将入口更改为 src/App.js
。这样您就可以在代码块中只导出一个 React 组件。
```js codesandbox=react-component
import React from 'react';
export default function App() {
return <h1>Hello remark-codesandbox!</h1>;
}
```
也可以使用任何现有的沙箱。只需从 URL 中获取沙箱的 id
。id
通常是沙箱 URL 的最后约 5 个随机字符。还支持从 Github 导入的沙箱,id
通常是沙箱预览 URL 的子域(约 10 个随机字符)。
```js codesandbox=mqpp1d4r0
// ...
```
想要使用自定义模板并将其版本控制在同一个仓库中?使用 file:
模式直接从文件系统加载模板!以下代码将从相对于 markdown 文件的路径 ./templates/vanilla-console
加载模板。文件模板是包含至少一个 package.json
文件的目录。
与其他示例一样,代码块的内容将替换模板中的入口文件。
```js codesandbox=file:./templates/vanilla-console
console.log('this code will replace the entry file content');
```
路径太长每次都输入很麻烦?考虑将其创建为 自定义模板。这也是推荐的方式!
专业提示:您可以在 codesandbox.io/s 上直接创建文件模板,并通过在菜单栏中选择“文件”->“导出为 ZIP”来下载它们。将其解压到某个地方,然后... 瞧!您就获得了一个文件模板!
查询参数
也可以通过附加查询参数来自定义 URL。只需将它们附加到沙箱 ID 后面即可。所有 选项 都允许使用。
```js codesandbox=new?codemirror=1&fontsize=12
// ...
```
您可以设置一些特殊的查询参数。以下所有特殊查询参数都不会传递到生成的 CodeSandbox URL,因为它们不受官方支持。
entry
引入了一个特殊的查询参数 entry
以允许您使用代码块的内容覆盖特定文件。
```js codesandbox=new?entry=src/App.js
// Override `src/App.js` rather than the default `src/index.js` with this contents of the code block
```
overrideEntry
默认情况下,代码块中的内容将覆盖入口文件中的所有内容。您可以通过设置特殊的查询参数 overrideEntry
来更改此行为。
将 overrideEntry
设置为一系列行号以指定您希望代码块覆盖入口文件的哪一部分。以下示例将使用代码块中的内容替换 react
模板(src/index.js
)的入口文件从第 4 行到第 12 行的内容。
```js codesandbox=react?overrideEntry=4-12
ReactDOM.render(
<h1>Hello remark-codesandbox!</h1>,
document.getElementById('root')
);
```
使用此技巧,您可以避免将不相关的代码传递到代码块中,以便读者可以专注于真正重要的事项。
有一个方便的快捷方式,只需指定起始行而无需指定结束行,即可替换从特定行号开始的整个入口文件,而无需知道其长度。
```js codesandbox=react?overrideEntry=4-
ReactDOM.render(
<h1>Hello remark-codesandbox!</h1>,
document.getElementById('root')
);
```
如果您想按原样使用模板而不使用代码块中的任何内容,请添加 ?overrideEntry=false
查询字符串
```js codesandbox=file:./templates/vanilla-console?overrideEntry=false
// This code will not be added to the sandbox
```
style
您还可以覆盖在 iframe 模式下使用的默认样式。
```js codesandbox=react?style=height:1000px
// The generated iframe will have height of 1000px instead of the default 500px
```
您可以传递多个用 ;
分隔的样式。所有样式将合并并覆盖默认样式(width:100%; height:500px; border:0; border-radius:4px; overflow:hidden;
)。
```js codesandbox=react?style=height:1000px;width:600px;
// The result style will be: "width:600px; height:1000px; border:0; border-radius:4px; overflow:hidden;"
```
选项
插件接受一组具有以下默认值的选项
{
remarkPlugins: [
codesandbox,
{
// Can be one of `meta`, `iframe`, or `button`
mode: 'meta',
// The query here will be appended to the generated url for every sandbox. Can be `string`, `object`, `URLSearchParams` instance, or `undefined`
query:
mode === 'iframe'
? {
fontsize: '14px',
hidenavigation: 1,
theme: 'dark',
}
: undefined,
// Define custom templates or override existing ones
customTemplates: {},
// Whether to automatically deploy code blocks via CodeSandbox API
autoDeploy: false,
},
];
}
mode
-
meta
:生成 CodeSandbox URL 并将其存储在 AST 中。此模式本身不会对 markdown 产生任何视觉变化,它对于其他插件或用户介入并对沙箱 URL 执行任何操作很有用。URL 将存储在node.data.codesandboxUrl
和node.data.hProperties.dataCodesandboxUrl
中。一个示例用法是在 UI 中自定义 CodeSandbox 按钮。 -
iframe
:此模式将完全替换代码块,使用生成的沙箱 iframe 标签。iframe 带有一些默认查询参数,但您可以通过iframeQuery
覆盖它们。 -
button
:此模式将保留代码块原样,并在代码块后面立即附加一个CodeSandbox 按钮,如下所示。
query
默认情况下,除了附加到生成的 URL 的 module
键之外,不会有其他查询。您可以在此处的每个 URL 中自定义查询。但是,当 mode
为 iframe
时,将预定义一组自定义查询。
query =
mode === 'iframe'
? {
fontsize: '14px',
hidenavigation: 1,
theme: 'dark',
}
: undefined;
您可以通过将 query
传递给选项来覆盖它们。请注意,传递的对象将替换默认对象,如果您想保留默认查询,请确保再次包含它。
customTemplates
定义要在代码块中使用的自定义模板。期望一个对象,其中键是模板 ID,值是模板信息。
模板信息是一个具有以下接口的对象。
interface TemplateInfo {
extends: string;
entry?: string;
query?: string | { [key: string]: string } | URLSearchParams;
files?: { [filePath: string]: { content: string | Object } };
}
extends
:为了使自定义模板的定义更容易,插件接受一个extends
键,允许您扩展任何现有模板。该值可以是任何 CodeSandbox ID、file:
路径或任何其他自定义模板 ID。如果使用file:
路径,建议使用绝对路径。与代码块中定义的相对路径相反,相对路径相对于process.cwd()
。entry
:要在模板中显示的入口文件,它也是代码块将替换到的文件。允许用户使用相同的模板/沙箱并使用不同的文件进行覆盖。query
:要附加到生成的 URL 的查询参数。它将合并并覆盖上面options.query
中的键。但是,它将被代码块元数据中内联定义的查询合并并覆盖。files
:要合并和覆盖现有文件的其他文件。签名遵循 官方 API。建议尽可能在extends
字段中使用file:
路径,因为它更容易管理和版本控制。
以下是默认的自定义模板。
{
// Alias `react` to `new`
react: {
extends: 'new',
},
// Alias `react-component` to `new`, but also override `entry` to `src/App.js`
'react-component': {
extends: 'new',
entry: 'src/App.js',
},
}
autoDeploy
默认情况下,URL 是在本地生成的,无需调用 官方 API。只有当用户点击按钮或查看 iframe 时才会调用 API。这是通过在本地手动构造 parameters
并通过 lz-string
压缩它们来完成的。请注意,有一个 一般准则 是将 URL 保持在 2000 个字符以内,较长的 URL 在某些浏览器中可能无法工作。
您可以通过将 true
传递给 autoDeploy
来绕过此限制。生成更短的 URL,并在 URL 中包含唯一的 codesandbox_id
。缺点是生成 URL 需要更多时间。
一个常见的做法是在生产环境中(或当结果 URL 对您支持的浏览器来说太长时)将其设置为 true
,而在开发时将其保留为 false
以加快重新加载速度。
{
autoDeploy: process.env.NODE_ENV === 'production';
}
贡献
运行 git clone
并 cd
。
yarn # Install dependencies
yarn test # Run tests
yarn example # Run build on all examples
yarn bump [patch|minor|major] # Bump version of remark-codesandbox
yarn release # Publish remark-codesandbox to npm
许可证
MIT