用Electron来做一个支持markdown的便笺吧！

前言

最近换了台 MacBook Air，发现内置了一个 “便笺” 的 app，感觉蛮不错的，平时可以用来做个每日计划啥的，但最让我不满意的一个点就是不支持 markdown！导致每次下意识的去使用 markdown 语法的时候就很别扭，类似这样：

看着就很别扭，加上样式也不算很美观，诶🤓👆，不如自己 DIY 一个？说干就干，Electron，启动！

架子搭好

这部分不愿意过多的去说，咱主要还是以实现这个支持 markdown 的便笺和优化功能为主，这里直接看官方文档即可：https://www.electronjs.org/zh/docs/latest/tutorial/quick-start

功能实现

需求分析：支持 markdown 的便笺

根据我们自己给自己创建的需求，来做个简单的流程图：

graph TD; A[便笺外观搭建] --> B[引入markdown解析库]; B --> C[优化展示效果];

这里为了控制大小，就不要再引入框架了，直接使用 electron 来实现相关功能就行：

Copy






Markdown Notepad

body {
display: flex;
height: 100vh;
margin: 0;
font-family: Arial, sans-serif;
}

#markdown-input,
#markdown-preview {
flex: 1;
padding: 20px;
box-sizing: border-box;
height: 100%;
overflow-y: auto;
}

#markdown-input {
border-right: 1px solid #ddd;
}

#markdown-preview {
padding-left: 40px;
}










这时候我们注意到，上方一直会有一个窗口栏在那，相比较 Mac 上的便笺来说，显得就很不优雅，这时候就可以通过调整 main.js（负责创建窗口和处理系统事件）来修改我们创建的窗口：

Copy
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');

let win; // 修改变量名以符合下文使用

function createWindow() {
// 创建一个无边框的浏览器窗口
win = new BrowserWindow({
width: 320,
height: 320,
frame: false, // 设置窗口无边框
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
}
});

通过设置BrowserWindow中的 frame 属性，便可以让窗口边框消失了

接下来，让我们进入下一步，即引入解析 Markdown 语法的库。在这里，我们选择了 Marked。Marked 是一个功能强大的 JavaScript 库，它可以将 Markdown 文本解析为 HTML。它的优点包括速度快，轻量级，同时它支持 Github 风格的 Markdown 语法，也支持自定义渲染。这些优点使得 Marked 成为我们的首选。

Copy
npm install marked

让我们在 renderer.js 中处理一下前端逻辑：

Copy
mdInput.addEventListener('input', function () {
const renderedHtml = marked.parse(mdInput.value);
mdPreview.innerHTML = renderedHtml;
});

OK，再稍微修改一下 HTML，让我们来看看，功能是不是实现了：

好了，功能没问题！成功渲染！

进一步优化

现在用着是不是感觉还是不太对劲？这样子左侧一块，右侧一块的，一点都不优雅，那让我们来修改一下，做个按钮来切换编辑和渲染这两个状态：

Copy




📌 Toggle Pin
👌🏻 Preview



将前端逻辑仍然写在 renderer.js 中，在处理这个逻辑：

Copy
togglePreviewBtn.addEventListener('click', () => {
isPreviewMode = !isPreviewMode; // 直接切换预览模式状态
if (isPreviewMode) {
mdInput.style.display = 'none';
mdPreview.style.display = 'block';
togglePreviewBtn.textContent = '✏️ Edit';
} else {
mdInput.style.display = 'block';
mdPreview.style.display = 'none';
togglePreviewBtn.textContent = '👌🏻 Preview';
}
});

OK，功能实现，相信细心的读者已经发现了这里还多了一个 “**📌 Toggle Pin”** 的按钮，既然要让他作为便利贴的存在，那自然要给他置顶的功能咯，这里便可以利用 Electron 的一个重要功能 ——进程间通信 (IPC)

进程间通信 (IPC) 是在 Electron 中构建功能丰富的桌面应用程序的关键部分之一。 由于主进程和渲染器进程在 Electron 的进程模型具有不同的职责，因此 IPC 是执行许多常见任务的唯一方法，例如从 UI 调用原生 API 或从原生菜单触发 Web 内容的更改。

这里我们主要的思路是："Toggle Pin" 功能通过渲染进程监听按钮点击，切换窗口置顶状态，并通过 Electron 的 IPC 机制发送消息给主进程，由主进程执行实际的置顶操作，下面是实际代码：

Copy
// main.js

const { app, BrowserWindow, ipcMain } = require('electron');

//.....

// 监听从渲染进程发来的toggle-pin消息
ipcMain.on('toggle-pin', (event, shouldPin) => {
if (win) {
win.setAlwaysOnTop(shouldPin); // 设置窗口是否置顶
}
});

// renderer.js
togglePinBtn.addEventListener('click', () => {
isWindowPinned = !isWindowPinned;
ipcRenderer.send('toggle-pin', isWindowPinned);
togglePinBtn.textContent = isWindowPinned ? '📌 Toggle Pin' : '📄 Just Paper';
});

再让我们来稍微的优化一下样式，运行 Electron 看看最终功能：

至此，功能已经全部完成

打包构建

这里我们使用 electron-builder 来进行打包，在 package.json 中配置一下既可：

Copy
"build": {
"appId": "com.yourdomain.memomark",
"mac": {
"category": "public.app-category.productivity",
"icon": "assets/MemoMark.icns" // 你的logo
},
"dmg": {
"title": "MemoMark",
"icon": "assets/MemoMark.icns",
"window": {
"width": 600,
"height": 400
}
},

注意，Mac 端的 logo 格式为 icns，别弄错了哦～

运行打包构建命令：

Copy
npm run dist

打包成功！安装之后便可以在本地使用自己开发的 Electron 应用了～

总结和一些小遗憾

在选择用于构建桌面应用的框架时，不仅需要考虑其功能性，还需要考虑其性能、运行时大小、开发经验等因素。以下是 Electron 和 Tauri 的详细对比：

| Electron | Tauri
体积 | Electron 的最小可执行文件体积约为 50MB，这是由于它依赖于完整的 Chromium 和 Node.js 运行时。 | Tauri 的一个显著优势是其小巧的体积。一个基本的 Tauri 应用的体积在几百 KB 到 1-2MB 之间。
速度 | Electron 的速度受到其大体积的影响，因为需要加载完整的 Chromium 和 Node.js 运行时。 | Tauri 由 Rust 编写，因此运行速度快，启动时间短。
安全性 | Electron 的安全性取决于开发者如何使用它。不当使用可能导致安全漏洞，例如在渲染器进程中直接使用 Node.js API。 | Tauri 的设计理念是安全优先，它采用了一种严格的安全模型，包括禁止直接从渲染器访问 Node.js API。
社区 | Electron 由 GitHub 开发，拥有大量的用户和成熟的社区。它有大量的文档和教程。 | Tauri 是一个相对较新的项目，其社区正在快速发展，但目前仍不如 Electron 成熟。
兼容性 | Electron 支持 Windows、macOS 和 Linux。 | Tauri 也支持 Windows、macOS 和 Linux。
开发经验 | Electron 支持 HTML、CSS 和 JavaScript，因此前端开发者可以很快上手。 | Tauri 允许使用任何可以编译成静态 HTML、CSS 和 JavaScript 的前端框架，因此它对前端开发者来说是非常灵活的。
内存使用 | Electron 的内存使用较高，因为每个 Electron 应用都需要运行自己的 Chromium 和 Node.js 实例。 | Tauri 的内存使用相对更低，因为它不依赖于重量级的运行时环境。

就我实现的这个支持 markdown 的便笺，大小便已经达到了 237mb（当然也可能是我没有进行优化），如果用 Tauri 的话，大小或许会控制的更好，这也是这个项目最大的遗憾了

如果你对这个项目感兴趣，或许你可以点进去看看https://github.com/isolcat/MemoMark，
如果能够下载下来体验一下，提 issues 或者 pr 就更好了，希望这款支持 markdown 的 Electron 便笺应用能够帮助到你～