プログラム解説
1. プロジェクト概要
Electron + React + TypeScript で構築された、デスクトップ向け小説執筆支援アプリケーション(novelaid)。 エクスプローラー、履歴管理(Git)、AI支援(LM Studio等)を統合した執筆環境を提供します。
2. 技術スタック
- Core: Electron
- Frontend: React 19
- Language: TypeScript
- Styles: CSS (Vanilla CSS)
- Icons: Lucide React
3. ディレクトリ構造
src/main: Electronのメインプロセスmain.ts: エントリーポイント。IPCリスナー設定、ウィンドウ管理。launcher.ts: 最近使ったプロジェクトのJSON保存・読み込み。git/:simple-gitを使用したGit操作の抽象化。ai/: 各種AIプロバイダー(Google Gemini, OpenAI, LM Studio)のファクトリーと実装。preload.ts: レンダラーに公開するAPI定義。
src/renderer: レンダラープロセス(React)App.tsx: ルーティング(Library vs Editor)と全グローバルContextの配置。contexts/: アプリ全体の共通状態管理。SettingsContext.tsx: 設定の永続化と、設定画面の制御。GitContext.tsx: Gitのステータスと履歴の保持。PanelContext.tsx: 両サイドパネルの表示管理。
layouts/MainLayout.tsx: 執筆画面のメインレイアウト。components/: UIコンポーネント。機能ごとにフォルダ分け。
4. データフローとアーキテクチャ
状態管理
本アプリでは React Context を活用して機能を疎結合に保っています。
- 各機能(Git, AI等)は専用の Context を通じて React コンポーネントに機能を提供します。
- データの変更(保存、設定更新等)はメインプロセス側の IPC ハンドラーを呼び出すことで実行されます。
IPC通信
src/main/preload.ts で定義された electronHandler を通じて通信します。
主要な機能群は以下の通りです:
fs:*: ファイルシステムの操作。git:*: リポジトリ操作。ai:*: 生成AIの利用(メッセージ送受信、ストリーミング)。recent:*: プロジェクト履歴。
5. 開発の基本フロー
- メインプロセスの機能追加:
src/main/配下にロジックを実装し、main.tsで IPC ハンドラーを登録。 - Preload定義:
src/main/preload.tsにチャンネルを追加。 - Context / Component の実装: レンダラー側で
window.electron.ipcRendererを呼び出す処理を実装。
データおよび設定の構造、参照範囲等
将来的なユーザープラグインからのアクセスも考慮して検討する。
- アプリケーション設定
- アプリケーションレベルの設定。
- 永続化が必要な場合、標準的なアプリケーション設定の保存場所に保存される
- プロジェクト設定
- 永続化が必要な場合、プロジェクト(フォルダー)内の
.novelaidディレクトリ内に保存される。
- 永続化が必要な場合、プロジェクト(フォルダー)内の
の区分は必要
ファイル保存する場合の名称などの検討。
一般的に、settings.json、または、config.jsonのように設定ファイルを保存するが、この区別は?
session.jsonやstate.jsonもあったほうが良さそう。
config.json- 主にアプリケーション設定で半固定値に近いもの
settings.json- ユーザー設定など、設定画面で変更するもの
session.json- 最後に開いたプロジェクト名やファイル名等
state.json- ウィンドウサイズとか?
- そこそこ頻繁に変わる情報
それぞれ、アプリケーションレベルとプロジェクトレベルの区分で保持。
useRefで保持すればレンダリングには影響しない。
これらは、main側で永続化した方が良いかも。
アプリケーションレベル
config.json
settings.json
- テーマ
- AI関連
session.json
- 最後に読み込んだプロジェクトのパス
//TODO 履歴はどうする?
state.json
プロジェクトレベル
config.json
settings.json
多くはアプリケーション設定で良い。
プロジェクト固有の設定を追加する場合、固有設定使用有無のフラグを用意する。
- テーマ
- 基本的にはアプリケーションレベルのテーマで良い
- プロジェクト用のテーマを使用するかの設定を用意する?
プロジェクト毎で分ける設定は何がある? プラグイン機構を導入した場合は使用するプラグインの設定など?
session.json
- 開いているドキュメントのパス等?
state.json
現状の構造
読み書きはmain側。 main側のStrageServiceで管理している。
例えばプロジェクト履歴の部分。 ProjectLauncher.tsxにRecentProjectの定義。 recent:getでmain側から取得。 mainのlauncher側にもRecentProjectの定義がある。
構造については再検討、リファクタリングの必要がありそう。
Context
現在のContext、Providerとしての階層構造
<Router>
<AppProvider>
<ThemeProvider>
<SettingsProvider>
<GitContextProvider>
<PanelProvider>
<MetadataProvider>
<AIContextProvider>
<DocumentProvider>
<AppRoutes />
</DocumentProvider>
</AIContextProvider>
</MetadataProvider>
</PanelProvider>
</GitContextProvider>
</SettingsProvider>
</ThemeProvider>
</AppProvider>
</Router>
ソフトの流れ
//TODO 起動からの処理を記載
開発中のみの機能
開発ツールは開発中のみ起動時に表示されます。 //TODO どこで切り替えている?
開発ツールのトグルメニューも開発中のみの機能となっています。
//src/main/menu.ts
const subMenuView =
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
? subMenuViewDev
: subMenuViewProd;
でメニュー自体を切り替えています。
## アイコンの作成
npx electron-icon-builder --input=1024x1024.png --output=./dst/
で1つのpngから作成できる。 assetsの該当ファイルを差し替えれば良い? icon.svgは使用されない? svgから1024x1024のpngを作成するのが実際には良いかも。