前言#
最近新しい MacBook Air を購入しましたが、内蔵の「メモ」アプリがあり、なかなか良いと思いました。普段は日々の計画を立てるのに使えますが、最も不満なのはMarkdown をサポートしていないことです!そのため、毎回無意識に Markdown 構文を使おうとするととても気まずくなります。こんな感じで:
見た目がとても気まずく、スタイルもあまり美しくないので、ええ🤓👆、自分で DIY することにしました。やると決めたら、Electron、スタート!
架子搭好#
この部分についてはあまり多くを語りたくありません。主に Markdown をサポートするメモと機能の最適化を実現することに焦点を当てます。ここでは公式ドキュメントを直接見てください:https://www.electronjs.org/zh/docs/latest/tutorial/quick-start
功能实现#
需求分析:Markdown をサポートするメモ
自分たちが作成した要件に基づいて、簡単なフローチャートを作成します:
ここではサイズを制御するために、フレームワークを導入せず、直接 Electron を使って関連機能を実現します:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Markdown Notepad</title>
<style>
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;
}
</style>
</head>
<body>
<textarea id="markdown-input" placeholder="ここにMarkdownを入力..."></textarea>
<div id="markdown-preview"></div>
</body>
</html>
この時、上部に常にウィンドウバーが表示されることに気付きます。Mac のメモと比較すると、あまり優雅ではありません。この時、main.js(ウィンドウの作成とシステムイベントの処理を担当)を調整して、作成したウィンドウを修正できます:
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 は私たちの第一選択となりました。
npm install marked
renderer.js でフロントエンドのロジックを処理します:
mdInput.addEventListener('input', function () {
const renderedHtml = marked.parse(mdInput.value);
mdPreview.innerHTML = renderedHtml;
});
OK、HTML を少し修正して、機能が実現されたか見てみましょう:
よし、機能に問題はありません!成功裏にレンダリングされました!
进一步优化#
今使ってみると、まだ何かおかしいと感じませんか?左側と右側が分かれていて、全く優雅ではありません。そこで、編集とレンダリングの 2 つの状態を切り替えるボタンを作成しましょう:
<div id="app-container">
<textarea id="markdown-input" placeholder="ここにMarkdownを入力..."></textarea>
<div id="markdown-preview"></div>
<div class="buttons-container">
<button id="toggle-pin" class="toggle-button">📌 ピン留め切替</button>
<button id="toggle-preview" class="toggle-button">👌🏻 プレビュー</button>
</div>
</div>
フロントエンドのロジックは renderer.js に書き続け、このロジックを処理します:
togglePreviewBtn.addEventListener('click', () => {
isPreviewMode = !isPreviewMode; // プレビュー状態を直接切り替え
if (isPreviewMode) {
mdInput.style.display = 'none';
mdPreview.style.display = 'block';
togglePreviewBtn.textContent = '✏️ 編集';
} else {
mdInput.style.display = 'block';
mdPreview.style.display = 'none';
togglePreviewBtn.textContent = '👌🏻 プレビュー';
}
});
OK、機能が実現されました。細心の読者は、ここに「📌 ピン留め切替」ボタンが追加されたことに気付いたでしょう。便利なメモとして存在させるためには、当然、ピン留め機能を追加する必要があります。ここでは、Electron の重要な機能であるプロセス間通信 (IPC)を利用できます。
プロセス間通信 (IPC) は、Electron で機能豊富なデスクトップアプリケーションを構築するための重要な部分の一つです。主プロセスとレンダラープロセスは、Electron のプロセスモデルで異なる役割を持っているため、IPC は UI からネイティブ API を呼び出したり、ネイティブメニューから Web コンテンツの変更をトリガーしたりするための唯一の方法です。
ここでの主な考え方は、「ピン留め切替」機能がレンダリングプロセスでボタンクリックをリッスンし、ウィンドウのピン留め状態を切り替え、Electron の IPC メカニズムを介してメインプロセスにメッセージを送信し、メインプロセスが実際のピン留め操作を実行するというものです。以下は実際のコードです:
// 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 ? '📌 ピン留め切替' : '📄 紙として使用';
});
さらにスタイルを少し最適化し、Electron を実行して最終的な機能を確認しましょう:
これで、機能はすべて完成しました。
打包构建#
ここでは electron-builder を使用してパッケージングを行います。package.json に設定を追加するだけです:
"build": {
"appId": "com.yourdomain.memomark",
"mac": {
"category": "public.app-category.productivity",
"icon": "assets/MemoMark.icns" // あなたのロゴ
},
"dmg": {
"title": "MemoMark",
"icon": "assets/MemoMark.icns",
"window": {
"width": 600,
"height": 400
}
},
注意:Mac のロゴ形式は icns ですので、間違えないでください。
パッケージングコマンドを実行します:
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。ダウンロードして体験し、問題やプルリクエストを提起していただければ幸いです。この Markdown をサポートする Electron メモアプリがあなたの役に立つことを願っています。