🎩 直接从代码块创建 CodeSandbox

在 Github 上查看

remark-codesandbox

🎩 一个用于直接从代码块创建 CodeSandboxremark 插件

npm version

在 CodeSandbox 上在线试用!(是的,我们在 CodeSandbox 内部演示 CodeSandbox,为什么不呢!?)

Edit remark-codesandbox demo

特性

  • 🔗 直接从代码块创建 CodeSandbox URL
  • ✨ 支持 3 种不同的模式metaiframebutton
  • 🚀 无需创建额外的文件夹或 package.json 文件
  • 🎉 支持 MDXGatsbyStorybook 文档docz 等...
  • 📦 支持引入您自己的自定义模板,甚至可以直接从同一个仓库中引入!
  • ⚡ 一行代码设置,高度可定制
  • 💪 非常适合库作者直接从文档中演示用法!

示例

安装

yarn add -D remark-codesandbox

入门

remark-codesandbox 导入到您的 remark 插件中。

const codesandbox = require('remark-codesandbox');

remark

remark().use(codesandbox, { mode: 'button' });

MDX

mdx(mdxCode, {
  remarkPlugins: [[codesandbox, { mode: 'button' }]],
});

Gatsby (gatsby-plugin-mdx)

使用 /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',
            },
          },
        ],
      },
    },
  ],
};

Storybook 文档

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)vuestatic...

代码块的内容将完全替换入口文件。因此,对于 new 模板,内容将完全替换 src/index.js 文件。请确保导入必要的包以使模板正常工作。

插件还提供了一些默认的别名reactnew 的别名。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 中获取沙箱的 idid 通常是沙箱 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.codesandboxUrlnode.data.hProperties.dataCodesandboxUrl 中。一个示例用法是在 UI 中自定义 CodeSandbox 按钮。

  • iframe:此模式将完全替换代码块,使用生成的沙箱 iframe 标签。iframe 带有一些默认查询参数,但您可以通过 iframeQuery 覆盖它们。

  • button:此模式将保留代码块原样,并在代码块后面立即附加一个CodeSandbox 按钮,如下所示。

    Edit React

query

默认情况下,除了附加到生成的 URL 的 module 键之外,不会有其他查询。您可以在此处的每个 URL 中自定义查询。但是,当 modeiframe 时,将预定义一组自定义查询。

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 clonecd

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