【TypeScript】デスクトップアプリ、作りたくね？

# はじめに
いや～しかしあっと言う間だよな

俺たち今年２６だぜ？

いや～しかしこの前の社内LT会も
めちゃめちゃ盛り上がったよな

あいつ目覚めたら ChatGPT解約してたらしいぜ？
笑えるよな

いや～俺たちホント幸せもんだよ

ChatGPTがあって

Claudeはまだ契約していないけど

プログラミングは楽しいし

悪くない

悪くない...

とは、思うんだ

けどさ

いや、 全然大した話じゃないんだけど

俺、お前に言わなくちゃ いけないことあるんだよね

そういやさ

LT会の帰り道 突如やってくるあの虚しさ

あれなんだろうね？

あれヤバくね？

胸...痛くね？

ごめん

どうでもいいか

いやぁ、話っつーのは...

TypeScriptでデスクトップアプリ、作りたくね？

熱い想い、コードに込めて届けたくね？

共に進もうぜ、未来への道を切り開こうぜ。

# 始めの一歩

Node.js、これはお前の旅の始まりだ

Node.jsを公式サイトからダウンロードして、迷わずインストールしろ

新しい世界への扉を開ける鍵、それがNode.jsだ

次に、プロジェクトディレクトリを作成する

俺たちの未来、ここから始まる

コマンドラインを開いて、叩け

```bash
mkdir electron-todo-app
cd electron-todo-app
npm init -y
```

これが、俺たちの骨組みだ

次に必要なパッケージをインストールする

ElectronとTypeScript、これが俺たちの剣と盾

```bash
npm install --save electron
npm install --save-dev typescript @types/node
```

TypeScriptの設定ファイルを作るんだ

tsconfig.jsonをプロジェクトのルートに作成して、以下の内容を追加しろ

```tsconfig.json
{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src"]
}
```

# コードに魂を込める

これから俺たちはTODOアプリを作るんだ

たまにはテキストファイル形式で保存なんかしてさ

エントリーポイントとなるファイルを作る

srcディレクトリを作成して、その中にmain.tsを作成だ

コードに命を吹き込む、その瞬間だ

```main.ts
import { app, BrowserWindow } from 'electron';
import * as path from 'path';

function createWindow(): void {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  });

  win.loadFile('index.html');
}

app.on('ready', createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

```

プリロードスクリプトは忘れちゃいけない

src/preload.tsを作成して、以下の内容を追加しろ

俺たちの声が聞こえるか？

```preload.ts
window.addEventListener('DOMContentLoaded', () => {
  console.log('Preload script loaded');
});
```

# 見た目も心も大事にしろ

俺たちはアプリの見た目を作る

HTMLファイルをプロジェクトのルートに作る

index.htmlを作って、この内容を追加だ

俺たちの情熱、ここに刻め

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>MOROHA TODO App</title>
</head>
<body>
  <h1>TODO App</h1>
  <ul id="todo-list"></ul>
  <input type="text" id="new-todo" placeholder="New TODO">
  <button id="add-todo">Add</button>
  <button id="save-todos">Save</button>
  <script src="renderer.js"></script>
</body>
</html>
```

TypeScriptが動きを加える

renderer.ts、同じディレクトリに作成したくね？

型を駆使して、未来を描け

```renderer.ts
interface Todo {
  text: string;
}

const todoList: HTMLElement = document.getElementById('todo-list')!;
const newTodoInput: HTMLInputElement = document.getElementById('new-todo') as HTMLInputElement;
const addTodoButton: HTMLButtonElement = document.getElementById('add-todo') as HTMLButtonElement;
const saveTodosButton: HTMLButtonElement = document.getElementById('save-todos') as HTMLButtonElement;

addTodoButton.addEventListener('click', () => {
  const todoText: string = newTodoInput.value.trim();
  if (todoText) {
    const li: HTMLLIElement = document.createElement('li');
    li.textContent = todoText;
    todoList.appendChild(li);
    newTodoInput.value = '';
  }
});

saveTodosButton.addEventListener('click', () => {
  const todos: Todo[] = [];
  todoList.querySelectorAll('li').forEach(li => {
    todos.push({ text: li.textContent! });
  });
  const blob: Blob = new Blob([JSON.stringify(todos, null, 2)], { type: 'application/json' });
  const url: string = URL.createObjectURL(blob);
  const a: HTMLAnchorElement = document.createElement('a');
  a.href = url;
  a.download = 'todos.json';
  a.click();
  URL.revokeObjectURL(url);
});
```

# すべてをつなげる

すべてをつなげる

ビルドして起動する

TypeScriptをコンパイル

俺たちの決意を形にする瞬間

```bash
npx tsc
```

ここまできたらpackage.jsonに以下のスクリプトを追加するんだ

革命起こす幕開けのファイル

```package.json
"scripts": {
  "start": "electron .",
  "build": "tsc"
}
```

そしたらアプリを起動しよう

ここまでの日々を情熱と呼ぶ

```bash
npm start
```

これで、俺たちはデスクトップアプリ開発者の仲間入りだ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1953297/88da66fb-995a-9e85-eae3-75df541d6cb3.png)


TypeScriptとElectronを使えば、可能性は無限大

やってみる価値はあるぜ

土台はできた、あとは、アイデア次第

TypeScriptの力を信じて、どんどんデスクトップアプリを作っていこうぜ

コードの一行一行に、俺たちの魂を込めようぜ

成功への道は、俺たちの手の中にある

勇気を出して、一歩踏み出そうぜ

TypeScriptの型が、俺たちの道しるべ

迷うな、進め、コードの先に未来が待ってる

生成AIに淘汰される未来に描き殴る

AIと協業するポジションを求めて

半径０ｍの世界を変える

革命起こす幕開けの

夜

# 終わりに

以上、MOROHA風味でお届けした、デスクトップアプリ開発の第一歩でした。

MOROHAさん、特に革命を最近よく聞いていて、超ファンです。

Electron使えば爆速でデスクトップアプリが作れました。

ここまで読んでいただきありがとうございました。