要是实在不知道要干什么,那就喝两杯思路就来了!

导航菜单

从想法到上线一个Markdown演示项目

从想法到上线:一个 Markdown 演示项目是怎么落地的

本文梳理本项目从动机、选型、实现到迭代与部署的完整路径,适合作为技术博客或复盘材料;细节以当前仓库为准。


一、想法从哪来

目标很朴素:做一套可演示的 Markdown 文档小应用——能建文档、改文档、在浏览器里预览渲染效果,并能和真实后端打通,而不是纯静态 Demo。

由此拆出几条明确需求:

  1. 列表:分页展示、按标题筛选、新建入口、单条删除。

  2. 编辑:双栏——左侧 Markdown 源码、右侧实时预览;支持新建与保存。

  3. 预览:只读页,展示已保存文档的渲染结果。

  4. 接口:与后端约定统一的 JSON 信封(成功/失败、detailtotal 等),与仓库内 docs/mdinfo.js 等脚本语义一致。

一句话:前端负责体验与渲染,数据与持久化交给服务端。


二、技术选型(为什么这样选)

  • React 18 + TypeScript:组件化与类型约束适合中长期维护;生态成熟。

  • Vite:开发态冷启动与 HMR 快,生产构建清晰。

  • React Router:路由与「列表 / 编辑 / 预览」三页结构天然匹配。

  • react-markdown + remark/rehype 插件:GFM、换行、emoji、frontmatter 等;代码块用 react-syntax-highlighter 做高亮。

  • 样式:CSS Modules,避免全局污染,与现有设计变量(如 --app-accent)易对齐。

刻意没有上的:重型 UI 组件库、全局状态库——当前数据流以页面内状态 + 接口为主,复杂度可控。


三、信息架构与路由

  • /:文档列表(搜索、分页、新建、删除、编辑/预览入口)。

  • /edit/:id:编辑;id 为 new 时表示新建,保存成功后 replace 到真实 id。

  • /preview/:id:预览;未保存的 new 无法预览,需先落库。

路由与 AppShell(顶栏 + 主内容区)组合,保证全站布局一致。


四、核心实现要点

4.1 接口层(src/api/mdinfo.ts

统一封装 fetch:列表、按 id 查询、创建、更新、删除;解析后端 JSON 信封;默认使用协议相对地址//host/...),在浏览器里随当前页面协议解析为 http 或 https,并支持通过 VITE_MDINFO_API_BASE 覆盖为完整 URL 或同源相对路径(便于网关反代、减轻跨域问题)。

4.2 编辑页

  • 双栏 grid 布局;源码区 textarea、预览区 MarkdownPreview

  • 为控制一屏内滚动(避免整页跟着滚),对 main + pageFill + split + 面板做了 flex + min-height + overflow 约束,并在 网格行上使用 minmax(0, 1fr),避免内容把高度撑破。

  • 顶栏「返回列表」与「文档 ID」通过 Portal 注入全局顶栏,与列表页工具条区域统一。

4.3 预览页

只读拉取单条文档后渲染;同样处理高度与内部滚动,避免长文把整页顶上去。

4.4 部署与路径

  • 通过 vite.config.ts 的 base 与 VITE_BASE:生产构建默认子路径 /markdown(可按需改为根路径或环境变量);

  • BrowserRouter 的 basename 与 import.meta.env.BASE_URL 对齐,保证静态资源与前端路由同源前缀一致


五、迭代中修过的「真实问题」(节选)

  1. 分页:最后一页删掉最后一条后,若仍请求旧页码会得到空列表;在 total 更新后用「总页数」对当前页做 clamp,避免停在空页。

  2. 删除确认:用自研 ConfirmDialog 替代 window.confirm,交互与样式对齐常见组件库习惯(如遮罩、主次按钮、危险操作色)。

  3. 平板布局:编辑页标题与保存按钮在窄屏下换行;通过 flex + nowrap + 输入框 min-width: 0 等方式收紧一行展示。

  4. Git 与远程:初始化仓库并关联 Codeup SSH 地址,便于持续交付。


六、文档与知识沉淀(仓库内)

除 README 外,在 docs/ 下陆续补充了与工程无关但团队常用的专题稿,便于对内分享或对外发博客:

  • 前端性能验证清单、缓存体系、安全要点、技术选型框架;

  • Vue 2/3、Vue 与 React 对比、面试高频算法等(偏独立长文)。

这些与业务代码解耦,不阻塞发版。


七、上线与协作

  • 构建npm run build,产物按 base 生成带前缀的 index.html 与 assets

  • 静态托管 / Nginx:需把子路径指到构建目录,并对 SPA 做 fallback 到 index.html;若走反向代理,接口与 HTML 的缓存策略应分开(HTML 不宜长缓存)。

  • 协作:远程仓库拉取后,本地配置 .env 中的 VITE_BASEVITE_MDINFO_API_BASE 与线上一致。

  • 地址线上地址


八、已知边界与后续方向

  • Markdown 渲染:当前管线含 rehype-raw 时,不可信 HTML 会进 DOM;生产环境应限制来源或加 sanitize,或关闭 raw。

  • 流式预览:若需「大文档分段输出」,需单独流式接口与网关 关闭缓冲 配合,前端再消费 ReadableStream——这是独立阶段,未在首版实现。


九、小结

本项目是从「能用的 Markdown 演示」出发,用 React + Vite + 约定式接口 快速闭环;在真实部署路径、跨域与协议、一屏布局、分页与交互细节上做了多轮打磨,并辅以 文档化 沉淀。若你也在做类似小而全的演示,希望这条从想法到落地的路径能帮你少踩坑、多留记录。

发表评论