效果展示:https://md.hubly.top/editor.html

项目初衷

作为一个经常使用Markdown写作,并需要多平台发布的内容创作者,我经常面临两个痛点:一是需要将.md文件快速转换为Word、PDF等格式;二是为不同平台调整排版耗时耗力。上周末,我决定用一天时间,尝试构建一个轻量工具来解决这些问题。

技术栈选择

  • 后端:Node.js + Express

  • 前端:原生JavaScript (Vanilla JS)

  • 构建工具:无(追求极简)

  • 部署:准备托管在静态CDN平台

  • 开发时间:1天

选择这个技术栈主要基于:

  1. 快速启动:Node.js环境搭建简单,Express框架轻量且熟悉

  2. 零依赖:前端坚持用原生JS,避免框架学习成本和打包复杂度

  3. 功能聚焦:核心是格式转换和排版,不需要复杂SPA

系统架构

后端设计(Express应用)

// 核心路由结构
app.post('/convert', handleConversion); // 处理格式转换
app.get('/themes', getThemes); // 获取主题列表
app.post('/preview', generatePreview); // 生成排版预览

关键技术点

  1. 文件处理:使用multer中间件处理.md文件上传

  2. 格式转换管道

    • HTML转换:marked.js库解析Markdown

    • PDF生成:puppeteer无头浏览器渲染HTML后截图

    • Word文档:基于HTML生成.docx文件结构

    • PNG导出:Canvas渲染+html2canvas库

  3. 主题系统:CSS样式表预置,通过API动态切换

前端实现(原生JS)

// 核心模块组织
class MDtoEditor {
    constructor() {
        this.editor = document.getElementById('editor');
        this.themeManager = new ThemeManager();
        this.converter = new FormatConverter();
    }
    
    // 主题切换
    switchTheme(themeName) {
        // 动态加载CSS,修改内联样式
    }
    
    // 内容导出
    exportFormat(format) {
        // 调用后端API,处理返回结果
    }
}

DOM操作优化

  • 使用事件委托减少监听器数量

  • 防抖处理实时预览更新

  • 虚拟滚动处理长文档

开发时间线(一天实战)

上午 9:00-12:00:搭建基础框架

  • 初始化Express项目

  • 配置基本路由和中间件

  • 实现Markdown到HTML的基础转换

  • 创建前端基础界面(编辑器区域+控制面板)

下午 13:00-17:00:核心功能开发

  • 实现四种格式导出功能(HTML/Word/PDF/PNG)

  • 开发主题系统:5套公众号主题+5套知乎主题

  • 实现实时预览功能

  • 添加深色/浅色模式切换

晚上 18:00-21:00:优化与测试

  • 移动端适配响应式布局

  • 数据本地存储(localStorage)

  • 错误处理和用户反馈

  • 基础样式美化

关键技术决策与解决方案

1. 纯前端VS服务端渲染

决策:混合模式

  • 格式转换需要服务端(特别是PDF生成)

  • 主题切换和实时预览完全在前端

  • 减少服务端压力,提升响应速度

2. 主题系统实现

/* 主题CSS变量系统 */
:root[data-theme="geek"] {
    --primary-color: #2d3748;
    --code-bg: #1a202c;
    --font-family: 'SF Mono', monospace;
}

通过修改data-theme属性,一键切换所有样式变量。

3. 文件导出优化

  • PDF导出使用缓存,避免重复生成

  • PNG导出支持分辨率选择

  • 批量导出时使用队列处理

4. 数据安全策略

  • 所有转换在内存中完成,不存储用户文件

  • 支持离线使用(基础编辑功能)

  • 可选加密传输(未来版本)

遇到的挑战与解决

挑战1:PDF中文支持

问题:默认配置下中文显示乱码 解决方案

  • 嵌入中文字体到PDF生成环境

  • 配置puppeteer字体参数

  • 提供字体回退机制

挑战2:移动端体验

问题:编辑器在手机上操作不便 解决方案

  • 定制移动端虚拟键盘处理

  • 底部固定操作栏

  • 手势支持(滑动切换主题)

挑战3:一天内完成

策略

  • 功能优先级排序(核心转换 > 高级排版)

  • 使用现成库解决复杂问题(不重复造轮子)

  • 最小可行产品思维,先完成再完善

性能优化

  1. 懒加载:主题CSS按需加载

  2. 缓存策略:转换结果临时缓存

  3. Worker支持:大文件处理放在Web Worker

  4. 代码分割:按功能模块动态加载

部署配置

// Express静态文件服务
app.use(express.static('public', {
    maxAge: '1d',
    setHeaders: (res, path) => {
        if (path.endsWith('.html')) {
            res.setHeader('Cache-Control', 'no-cache');
        }
    }
}));

计划部署到CDN平台,利用边缘计算加速访问。

未来可能的扩展

  1. 插件系统:允许自定义转换器和主题

  2. 协作编辑:实时多人编辑支持

  3. API开放:提供RESTful API供其他系统集成

  4. 桌面应用:基于Electron打包

开发心得

一天内完成这个项目,验证了“小步快跑”的开发理念。关键技术选择上,Node.js + Express提供了足够的后端能力,原生JavaScript避免了框架复杂度,让注意力集中在核心功能上。

最大的收获是:在时间约束下,必须做出明确的技术取舍。例如,放弃实时协同编辑、简化用户系统、优先保证核心转换的稳定性。这些决策让项目在一天内从想法变为可用产品。

项目开源地址:欢迎访问GitHub仓库查看完整代码和技术实现细节。


技术栈:Node.js 20.x, Express 5.x, Vanilla JS
开发时长:约12小时

如果你对某个技术实现细节感兴趣,欢迎在评论区讨论。代码已开源,适合作为学习Express和原生JS的参考项目。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐