打造一个 Markdown 编辑器:Electron 项目实战教程

📝 打造一个 Markdown 编辑器:Electron 项目实战教程

在现代桌面应用开发中,Electron 成为前端工程师开发跨平台工具的首选。本教程将通过一个完整示例,手把手带你构建一个功能完整的 Markdown 编辑器。


🎯 项目目标

实现一个支持以下功能的桌面 Markdown 编辑器:

  • 实时 Markdown 预览
  • 支持本地文件打开与保存
  • 自动同步编辑与预览内容
  • 跨平台运行(Windows/macOS/Linux)

📦 技术栈

  • Electron
  • Node.js + fs 模块
  • Marked(Markdown 转换库)
  • DOMPurify(防止 XSS)
  • HTML/CSS/JavaScript 原生开发(可拓展 Vue/React)

📁 项目结构

复制代码
markdown-editor/
├── main.js           # 主进程入口
├── preload.js        # 渲染与主进程通信桥梁
├── index.html        # 编辑器页面
├── renderer.js       # 渲染进程逻辑
├── style.css         # 页面样式
├── package.json

🧱 第一步:初始化项目

bash 复制代码
mkdir markdown-editor && cd markdown-editor
npm init -y
npm install electron marked dompurify

package.json 添加启动脚本:

json 复制代码
"scripts": {
  "start": "electron ."
}

🧠 第二步:主进程 main.js

js 复制代码
const { app, BrowserWindow, dialog, ipcMain } = require('electron');
const path = require('path');
const fs = require('fs');

function createWindow() {
  const win = new BrowserWindow({
    width: 1000,
    height: 700,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true
    }
  });
  win.loadFile('index.html');
}

app.whenReady().then(createWindow);

// 文件保存逻辑
ipcMain.handle('save-file', async (event, content) => {
  const { filePath } = await dialog.showSaveDialog({
    filters: [{ name: 'Markdown', extensions: ['md'] }]
  });
  if (filePath) fs.writeFileSync(filePath, content);
});

// 文件打开逻辑
ipcMain.handle('open-file', async () => {
  const { filePaths } = await dialog.showOpenDialog({
    filters: [{ name: 'Markdown', extensions: ['md'] }],
    properties: ['openFile']
  });
  if (filePaths[0]) return fs.readFileSync(filePaths[0], 'utf-8');
});

🌉 第三步:preload.js(暴露通信接口)

js 复制代码
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
  saveFile: (content) => ipcRenderer.invoke('save-file', content),
  openFile: () => ipcRenderer.invoke('open-file')
});

🧑‍🎨 第四步:HTML 页面 index.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Markdown Editor</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>
    <button id="open">📂 打开</button>
    <button id="save">💾 保存</button>
  </header>
  <main>
    <textarea id="editor" placeholder="输入 Markdown 内容..."></textarea>
    <div id="preview"></div>
  </main>
  <script src="renderer.js"></script>
</body>
</html>

🎨 第五步:CSS 样式 style.css

css 复制代码
body { margin: 0; font-family: sans-serif; display: flex; flex-direction: column; height: 100vh; }
header { padding: 10px; background: #282c34; color: white; display: flex; gap: 10px; }
main { flex: 1; display: flex; }
textarea, #preview { flex: 1; padding: 1rem; border: none; outline: none; font-size: 1rem; }
textarea { resize: none; }
#preview { background: #f7f7f7; overflow-y: auto; }

⚙️ 第六步:渲染逻辑 renderer.js

js 复制代码
const editor = document.getElementById('editor');
const preview = document.getElementById('preview');
const marked = require('marked');
const DOMPurify = require('dompurify');

editor.addEventListener('input', () => {
  const raw = marked.parse(editor.value);
  preview.innerHTML = DOMPurify.sanitize(raw);
});

document.getElementById('save').addEventListener('click', () => {
  window.electronAPI.saveFile(editor.value);
});

document.getElementById('open').addEventListener('click', async () => {
  const content = await window.electronAPI.openFile();
  if (content) {
    editor.value = content;
    const raw = marked.parse(content);
    preview.innerHTML = DOMPurify.sanitize(raw);
  }
});

🚀 启动项目

bash 复制代码
npm start

你将看到一个拥有基本 Markdown 编辑功能的桌面应用,支持打开 .md 文件,编辑后保存,预览区实时渲染内容。


🔧 可拓展功能建议

  • 添加文件拖拽上传功能
  • 使用 Vue/React 重构渲染层
  • 自动保存 & 恢复
  • 支持主题切换(浅色/暗色)
  • 导出 PDF/HTML

✅ 总结

通过本教程你掌握了:

  • 如何搭建一个完整的 Electron 应用;
  • 使用 ipcRendereripcMain 实现文件交互;
  • 利用 marked + DOMPurify 实现 Markdown 渲染与防注入;
  • 构建一个跨平台可用的 Markdown 编辑器。
相关推荐
_r0bin_4 小时前
前端面试准备-7
开发语言·前端·javascript·fetch·跨域·class
IT瘾君4 小时前
JavaWeb:前端工程化-Vue
前端·javascript·vue.js
zhang98800004 小时前
JavaScript 核心原理深度解析-不停留于表面的VUE等的使用!
开发语言·javascript·vue.js
拉不动的猪7 小时前
都25年啦,还有谁分不清双向绑定原理,响应式原理、v-model实现原理
前端·javascript·vue.js
狂炫一碗大米饭8 小时前
一文打通TypeScript 泛型
前端·javascript·typescript
exploration-earth10 小时前
本地优先的状态管理与工具选型策略
开发语言·前端·javascript
哈贝#11 小时前
vue和uniapp聊天页面右侧滚动条自动到底部
javascript·vue.js·uni-app
Lazy_zheng11 小时前
🚀 前端开发福音:用 json-server 快速搭建本地 Mock 数据服务
前端·javascript·vue.js
用户25191624271111 小时前
ES6之块级绑定
javascript
ZzMemory11 小时前
藏起来的JS(四) - GC(垃圾回收机制)
前端·javascript·面试