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

发布于:2025-05-10 ⋅ 阅读:(13) ⋅ 点赞:(0)

📝 打造一个 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

🧱 第一步:初始化项目

mkdir markdown-editor && cd markdown-editor
npm init -y
npm install electron marked dompurify

package.json 添加启动脚本:

"scripts": {
  "start": "electron ."
}

🧠 第二步:主进程 main.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(暴露通信接口)

const { contextBridge, ipcRenderer } = require('electron');

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

🧑‍🎨 第四步:HTML 页面 index.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

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

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);
  }
});

🚀 启动项目

npm start

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


🔧 可拓展功能建议

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

✅ 总结

通过本教程你掌握了:

  • 如何搭建一个完整的 Electron 应用;
  • 使用 ipcRendereripcMain 实现文件交互;
  • 利用 marked + DOMPurify 实现 Markdown 渲染与防注入;
  • 构建一个跨平台可用的 Markdown 编辑器。

网站公告

今日签到

点亮在社区的每一天
去签到