npm package: @sakitam-gis/vitepress-playground
Description: 为你的 vitepress 网站添加一个在线示例功能
Latest version: 1.2.0

## @sakitam-gis/vitepress-playground

为你的 vitepress 网站添加一个在线示例功能

## Feature

- 🚀 约定式示例编程
- 🔍 支持 .vue 单文件示例和代码块示例
- 🎨 自动化的 [Vue SFC Playground](https://play.vuejs.org/) 、 [stackblitz](https://stackblitz.com)、[codesandbox](https://codesandbox.io) 代码示例
- 💡 支持 markdown 中 importMap 配置

## Use

### Install

```bash
pnpm i @sakitam-gis/vitepress-playground
```

### Import

主要配置的有两个位置：

1. `.vitepress/config.ts` / `.vitepress/config.js` / `.vitepress/config.mts` / `.vitepress/config.mjs`

```ts
import { defineConfig } from 'vitepress';
import config from '@sakitam-gis/vitepress-playground/config';

export default defineConfig({
  extends: config,
  ... Your custom config
});
```

2. `.vitepress/theme/index.ts` / `.vitepress/theme/index.js`

```ts
import DefaultTheme from 'vitepress/theme';
import { SfcPlayground } from '@sakitam-gis/vitepress-playground';
import '@sakitam-gis/vitepress-playground/dist/style.css';

export default {
  ...DefaultTheme,
  enhanceApp({ app, router, siteData }) {
    app.component('SfcPlayground', SfcPlayground);
  },
} as any;
```

### Dev 

我们编写的示例基本如下：

```markdown
---
aside: false
importMap: {
  "plotty": "https://esm.sh/plotty",
  "geotiff": "https://esm.sh/geotiff@2.1.3",
}
---

## 使用 plotty 渲染 tiff 数据

<sfc-playground src="./test.vue" language="vue" title="plotty" desc="plotty渲染"></sfc-playground>
```

注意以上 markdown 片段中 `importMap` 必须配置在头部配置中，他的内容为本页面所有 `sfc-playground` 的依赖集合，你可以使用 `esm.sh` 或者其他替代
产品，并且这个配置只在 vitepress 的在线代码编辑器[Vue SFC Playground](https://play.vuejs.org/)有用。代码 playground 在 markdown 中表现形式为 `html` 片段，相关属性配置项如下：

| 属性字段                   | 作用                                                         | 默认值    | 样例                       |
| -------------------------- | ------------------------------------------------------------ | --------- | -------------------------- |
| src                        | 引用的 sfc 代码组件                                          | undefined |                            |
| language                   | 代码高亮语言格式                                             | vue       | vue                        |
| title                      | 代码示例的标题                                               | ''        | 按钮使用                   |
| desc                       | 代码示例描述                                                 | ''        | 这是一个简单的按钮使用示例 |
| enableIntersectionObserver | 对当前示例是否启用可视区优化（如果启用，代码示例不在浏览器可视区内那么不会进行渲染，这在一些 webgl 可视化的展示比较有用，能够提高页面的浏览体验） | true      | true                       |

除了单文件示例外，也支持代码片段示例，基本示例如下：

```vue:demo
<template>
  <div class="playground-content">
    这是一个示例 {{v}}
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue';

  const emits = defineEmits(['mount']);

  const v = ref(1);

  if (!import.meta.env.SSR) {
    console.log('not ssr', '非 ssr 环境需要执行，一般用于 build 时无法执行的代码片段包装');
  }

  if (import.meta.env.SSR) {
    console.log('ssr', 'ssr 环境需要执行');
  }

  emits('mount');
</script>

<style scoped>
  .playground-content {
    width: 100%;
    height: 450px;
  }
</style>
```

上述配置完成后，正常启动 vitepress 开发即可

![img.png](https://sakitam.oss-cn-beijing.aliyuncs.com/md-assets/2024/04/18-09-52-playground.png)

## Design

这里的设计思路很简单，正常情况下 markdown 文件都会被解析为内部标记，我们通过判断是否存在对应的示例标签来执行对应的解析逻辑。

这里的解析逻辑共有三种，分为两大类（code block 和 sfc），相关解析流程请查看下图：

![img.png](https://sakitam.oss-cn-beijing.aliyuncs.com/md-assets/2024/04/18-09-51-img.png)

### OnlineEditor

关于在线编辑器这里共支持了三种：[Vue SFC Playground](https://play.vuejs.org/) 、 [stackblitz](https://stackblitz.com)、[codesandbox](https://codesandbox.io)
其中前两种的支持比较完善，codesandbox目前由于限制个人用户草稿数目（Draft）和限制使用 `Sandbox` 可能会出现一些问题，有需要的话建议自行转为 `Devbox`.