diff --git a/README.md b/README.md index 1aa5ff5..2b2f30a 100644 --- a/README.md +++ b/README.md @@ -1,204 +1,140 @@ -# @vue/repl +# KT Template Online Playground -Vue SFC REPL as a Vue 3 component. +`kt-template-online-playground` 是 KT Template Online 的在线编辑器。项目基于 `@vue/repl` 改造,负责编辑 Vue SFC 模板、预览运行效果、读取前台传入的组件信息,并在保存时截图上传 MinIO 后写入后端组件数据。 -## Basic Usage +## 技术栈 -**Note: `@vue/repl` >= 2 now supports Monaco Editor, but also requires explicitly passing in the editor to be used for tree-shaking.** +- Vue 3 + TypeScript +- Vite +- @vue/repl +- Monaco Editor / CodeMirror +- Axios +- MinIO 上传接口 +- pnpm -```ts -// vite.config.ts -import { defineConfig } from 'vite' -export default defineConfig({ - optimizeDeps: { - exclude: ['@vue/repl'], - }, - // ... -}) +## 功能概览 + +- 在线编辑 Vue 单文件组件。 +- 实时编译并在 iframe 预览运行结果。 +- 支持从 URL hash 恢复编辑器文件状态。 +- 读取 URL query 初始化组件 `id`、`name`、`type`、`componentType`。 +- 保存时自动截取预览区图片,上传到 MinIO,并把图片地址写入组件 `image` 字段。 +- 根据是否存在 `id` 自动调用新增或编辑接口。 + +## 目录结构 + +```text +src + api/ # axios 封装和组件/字典/MinIO 接口 + editor/ # 文件列表、编辑器容器、编辑器适配 + output/ # 预览、沙箱、SSR 输出 + monaco/ # Monaco 语言服务和资源加载 + codemirror/ # CodeMirror 编辑器 + template/ # 默认模板 + PlaygroundHeader.vue # 组件表单、截图上传、保存入口 + Repl.vue # 编辑器主体 + store.ts # REPL 文件状态、序列化和反序列化 + index.ts # 包导出入口 +test/main.ts # 本地 Playground 页面入口 ``` -### With CodeMirror Editor +## 环境变量 -Basic editing experience with no intellisense. Lighter weight, fewer network requests, better for embedding use cases. +仓库只提交 `.env.example`,真实 `.env.development` 和 `.env.production` 保留在本地。 -```vue - - - +```env +VITE_APP_API_BASE=/api +VITE_APP_PROXY=http://localhost:48085/ ``` -### With Monaco Editor +关键变量: -With Volar support, autocomplete, type inference, and semantic highlighting. Heavier bundle, loads dts files from CDN, better for standalone use cases. +| 变量 | 说明 | +| --- | --- | +| `VITE_APP_API_BASE` | 前端请求前缀,默认 `/api` | +| `VITE_APP_PROXY` | 后端服务地址,Vite dev server 会把 `/api` 代理到这里 | -```vue - +## 启动 - +项目 `.node-version` 为 `lts/*`。Windows 下如别名不可用,先用 `nvm ls` 查看已安装 LTS,再切到具体版本。 + +```bash +pnpm install +pnpm dev ``` -## Advanced Usage +常用命令: -Customize the behavior of the REPL by manually initializing the store. - -See [v4 Migration Guide](https://github.com/vuejs/repl/releases/tag/v4.0.0) - -```vue - - - +```bash +pnpm dev # 本地 Playground 页面 +pnpm typecheck # 类型检查 +pnpm build # 构建库产物 +pnpm build-preview +pnpm lint ``` -Use only the Preview without the editor +## URL 数据约定 -```vue - +前台跳转示例: - +```text +http://localhost:5173/?id=xxx&name=基础折线图&type=1&componentType=1#... ``` -
-Configuration options for resource links. (replace CDN resources) +## 保存流程 -```ts -export type ResourceLinkConfigs = { - /** URL for ES Module Shims. */ - esModuleShims?: string - /** Function that generates the Vue compiler URL based on the version. */ - vueCompilerUrl?: (version: string) => string - /** Function that generates the TypeScript library URL based on the version. */ - typescriptLib?: (version: string) => string +`PlaygroundHeader.vue` 是保存入口: - /** [monaco] Function that generates a URL to fetch the latest version of a package. */ - pkgLatestVersionUrl?: (pkgName: string) => string - /** [monaco] Function that generates a URL to browse a package directory. */ - pkgDirUrl?: (pkgName: string, pkgVersion: string, pkgPath: string) => string - /** [monaco] Function that generates a URL to fetch the content of a file from a package. */ - pkgFileTextUrl?: ( - pkgName: string, - pkgVersion: string | undefined, - pkgPath: string, - ) => string -} +1. 从 query 读取组件信息。 +2. 请求 `/dict/getDictByKey` 和 `/dict/getComponentDictByType` 初始化类型下拉。 +3. 通过当前 iframe 预览内容生成截图。 +4. 调用 `/minio/upload` 上传截图,获取返回的 `url`。 +5. 组装 `name`、`type`、`componentType`、`image`、`template`。 +6. 有 `id` 时调用 `/component/update`,没有 `id` 时调用 `/component/save`。 +7. 新增成功后把后端返回的 `id` 写回 query。 + +## 接口约定 + +接口集中在 `src/api`: + +- `request.ts`:axios 实例,统一处理 `code !== 200` 的错误。 +- `component.ts`:新增和编辑组件。 +- `dict.ts`:组件类型字典。 +- `minio.ts`:截图文件上传。 + +当前主要接口: + +| 方法 | 地址 | 用途 | +| --- | --- | --- | +| `GET` | `/dict/getDictByKey` | 查询一级类型 | +| `GET` | `/dict/getComponentDictByType` | 查询二级类型 | +| `POST` | `/minio/upload` | 上传预览截图 | +| `POST` | `/component/save` | 新增组件 | +| `POST` | `/component/update` | 编辑组件 | + +## 开发约定 + +- 保持 query 和 hash 分工,不要让 `store.serialize()` 覆盖 `location.search`。 +- 保存前必须先上传截图,`image` 字段使用 MinIO 返回的 URL。 +- 业务请求新增时统一放到 `src/api`,组件里调用封装后的函数。 +- 编辑器核心逻辑来自 `@vue/repl`,调整时优先保持原有 Store、Preview、Editor 分层。 + +## 轻量验证 + +常规改动优先执行: + +```bash +pnpm typecheck ``` -**unpkg** +涉及保存或预览交互时再启动开发服务检查明显报错: -```ts -const store = useStore({ - resourceLinks: ref({ - esModuleShims: - 'https://unpkg.com/es-module-shims@1.5.18/dist/es-module-shims.wasm.js', - vueCompilerUrl: (version) => - `https://unpkg.com/@vue/compiler-sfc@${version}/dist/compiler-sfc.esm-browser.js`, - typescriptLib: (version) => - `https://unpkg.com/typescript@${version}/lib/typescript.js`, - pkgLatestVersionUrl: (pkgName) => - `https://unpkg.com/${pkgName}@latest/package.json`, - pkgDirUrl: (pkgName, pkgVersion, pkgPath) => - `https://unpkg.com/${pkgName}@${pkgVersion}/${pkgPath}/?meta`, - pkgFileTextUrl: (pkgName, pkgVersion, pkgPath) => - `https://unpkg.com/${pkgName}@${pkgVersion || 'latest'}/${pkgPath}`, - }), -}) +```bash +pnpm dev ``` - -**npmmirror** - -```ts -const store = useStore({ - resourceLinks: ref({ - esModuleShims: - 'https://registry.npmmirror.com/es-module-shims/1.5.18/files/dist/es-module-shims.wasm.js', - vueCompilerUrl: (version) => - `https://registry.npmmirror.com/@vue/compiler-sfc/${version}/files/dist/compiler-sfc.esm-browser.js`, - typescriptLib: (version) => - `https://registry.npmmirror.com/typescript/${version}/files/lib/typescript.js`, - - pkgLatestVersionUrl: (pkgName) => - `https://registry.npmmirror.com/${pkgName}/latest/files/package.json`, - pkgDirUrl: (pkgName, pkgVersion, pkgPath) => - `https://registry.npmmirror.com/${pkgName}/${pkgVersion}/files/${pkgPath}/?meta`, - pkgFileTextUrl: (pkgName, pkgVersion, pkgPath) => - `https://registry.npmmirror.com/${pkgName}/${pkgVersion || 'latest'}/files/${pkgPath}`, - }), -}) -``` - -