前言#
最近新しい 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 は、Markdown テキストを HTML に解析する強力な JavaScript ライブラリです。その利点には、高速で軽量であること、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 で機能豊富なデスクトップアプリケーションを構築するための重要な部分の 1 つです。主プロセスとレンダラープロセスは、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。ダウンロードして体験し、イシューや PR を提案していただければさらに嬉しいです。この Markdown をサポートする Electron メモアプリがあなたの役に立つことを願っています!