feat: 添加 Mermaid 图表支持 - #45
Conversation
|
@lyimoexiao is attempting to deploy a commit to the Zhilu Sites Team on Vercel. A member of the Team first needs to authorize it. |
✅ Deploy Preview for zhilu-blog ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This PR adds Mermaid diagram support to the application, enabling rendering of flowcharts and diagrams directly from Markdown code blocks.
Changes:
- Created a new
remark-mermaidpackage to parse Mermaid code blocks in Markdown - Added a Vue component (
Mermaid.vue) to render Mermaid diagrams with theme support - Updated project configuration to include the new package in the build process
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-workspace.yaml | Added mermaid and remark-mermaid dependencies to the catalog |
| packages/remark-mermaid/tsconfig.json | TypeScript configuration for the new remark-mermaid package |
| packages/remark-mermaid/src/index.ts | Core plugin implementation that transforms Mermaid code blocks into custom nodes |
| packages/remark-mermaid/package.json | Package configuration for the remark-mermaid workspace package |
| package.json | Added dependencies and updated build script to include remark-mermaid |
| nuxt.config.ts | Registered the remark-mermaid plugin in the Nuxt configuration |
| content/previews/example.md | Added example Mermaid diagram demonstrating the feature |
| app/components/content/Mermaid.vue | Vue component for rendering Mermaid diagrams with dark/light theme support |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "devDependencies": { | ||
| "@zinkawaii/tsconfig": "catalog:framework", | ||
| "tsdown": "catalog:framework", | ||
| "typescript": "catalog:framework" | ||
| } |
There was a problem hiding this comment.
The remark-mermaid package lacks test dependencies and test scripts. Consider adding a test framework (like vitest) and test coverage for the plugin logic, particularly for theme detection and node transformation.
| if (!className) | ||
| return options.theme ?? 'default' | ||
|
|
||
| const isDark = className.includes('dark') || className.includes('night') |
There was a problem hiding this comment.
The theme detection logic is fragile and relies on substring matching. This could produce false positives (e.g., 'darkness' or 'nightly' would match). Consider using a more precise matching strategy or documented class name conventions.
| const isDark = className.includes('dark') || className.includes('night') | |
| const isDark = /\b(dark|night)\b/.test(className) |
| theme, | ||
| }) | ||
|
|
||
| const id = `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}` |
There was a problem hiding this comment.
Using Date.now() and Math.random() for ID generation could lead to collisions in rapid re-renders. Consider using a more reliable unique ID generator or a counter-based approach with a component-scoped prefix.
| const id = `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}` | |
| const id = `mermaid-${currentId}` |
| }) | ||
|
|
||
| const id = `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}` | ||
| container.value.innerHTML = `<div class="mermaid" id="${id}">${props.code}</div>` |
There was a problem hiding this comment.
Direct innerHTML assignment with user-provided code creates an XSS vulnerability. The props.code should be properly escaped or sanitized before being inserted into the DOM, or use textContent for text-only insertion.
| import { useDark } from '@vueuse/core' | ||
| import { computed, nextTick, onMounted, ref, watch } from 'vue' | ||
|
|
||
| type MermaidTheme = 'default' | 'base' | 'dark' | 'forest' | 'neutral' | 'null' |
There was a problem hiding this comment.
The MermaidTheme type includes 'null' as a string literal, but MermaidOptions in the remark plugin uses 'night' instead. These theme definitions should be consistent across both files. Consider extracting a shared type definition.
| type MermaidTheme = 'default' | 'base' | 'dark' | 'forest' | 'neutral' | 'null' | |
| type MermaidTheme = 'default' | 'base' | 'dark' | 'forest' | 'neutral' | 'night' |
|
目前这个方案实现有个问题:Mermaid 是客户端渲染的,当单页组件过多时会导致页面首屏卡顿。 |
|
我目前只能写到这了,只有 SPA 开发经验所以如果有哪些不好的地方请大佬指正下() |
✅ Deploy Preview for zhilu-blog ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
e0ce073 to
618dcca
Compare
packages/remark-mermaid: 解析 Markdown 中的 mermaid 代码块app/components/content/Mermaid.vue: Mermaid Vue 组件用于渲染content/previews/example.md: 添加 Mermaid 预览示例nuxt.config.ts: 导入 remark 解析器