0. 前置き
IT 業界では JavaScript を実行するのに JavaScript をコーディングしません。
その代わり、TypeScript を使用して JavaScript のコードを生成します。
JavaScript の型付けを厳密にしたのが TypeScript で、JavaScript のスーパーセット (上位互換) になっています。
型付けが動的なのがスクリプト言語の長所のはずなのに、JavaScript はそのままだと引き起こされる不具合が致命傷になるらしい。
プログラミング言語のソースコードを入力して、別のプログラミング言語のソースコードを出力するプログラムのことをトランスコンパイラと呼びます。
ちなみに、最初期の C++ は、C のソースコードを出力していました。
世界のプログラミング言語の人気順は以下で、TypeScript は上位になっています。
コーディングの作法を教えるより、型チェックで制限をかけるほうが合理的なんだね…。
- GitHub Octoverse (2025) --- 世界第 1 位 (約 105 万人の増加)
- Programming, scripting, and markup languages --- 世界第 6 位
- Top 14 programming languages for 2026 --- 世界第 8 位。
本稿では、TypeScript を使用して SPA (Single Page Application) を作成します。
TypeScript は業務で使用する*1ので、業務を想定して Linux (WSL2*2) で TypeScript を動作させます。
仕組みを単純化するため React.js や Next.js は使用しません。
Linux は WSL2 の標準ディストリビューションである Ubuntu を使用します。
*1業務は Linux の Docker が前提なので、Windows だけで作成した .ts では差異が生じてしまいます。
*2WSL1 で致命的だった欠陥が、WSL2 ではかなり改善されています。
1. WSL2 のインストール
1-1. WSL2 の実行許可を確認する。
管理者でターミナルを開き WSL2 の実行可否を確認する。1-2. WSL2 に Ubuntu をインストールする。
*3False の場合は BIOS の設定を確認し、Intel VT-x や VT-d, SVM Mode や AMD-V を Enabled にすること。
− □ × >_ 管理者: Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # Windows のバージョンが 19041 以上か確認する (Windows10 20H1 以降なら OK) PS C:\> [Environment]::OSVersion.Version.Build ⏎ 26200 ← Windows11 25H2 の場合 (ビルド番号が 19041 以上なので OK) PS C:\> # wsl コマンドを実行できるか確認する*3 PS C:\> (Get-ComputerInfo)."HyperVisorPresent" ⏎ True ← True があること PS C:\> exit ⏎
KVM なら CPU の設定を見直すこと。(XML に cpu mode='host-model' "親 CPU からの引継ぎ" があること)
インストール可能な WSL は 1 と 2 が存在する。
Windows のビルド番号が 19041 以上ならデフォルトで WSL2 になるが、ここでは強制する。
インストールする Ubuntu のバージョンは、ポイントリリース*4が 1 以上のものを選択する。
*4Ubuntu のバージョンは YY.MM.R となっており、R (ポイントリリース) が 1 以上で安定する慣例がある。
− □ × >_ 管理者: Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # WSL2 をインストールし、バージョンを 2 に固定する PS C:\> wsl --update ⏎ PS C:\> wsl --set-default-version 2 ⏎
PS C:\> # Ubuntu 24.04 をインストールする PS C:\> wsl --install -d Ubuntu-24.04 ⏎ ダウンロードしています: Ubuntu 24.04 LTS インストールしています: Ubuntu 24.04 LTS ディストリビューションが正常にインストールされました。'wsl.exe -d Ubuntu-24.04' を使用して起動できます Ubuntu-24.04 を起動しています... Provisioning the new WSL instance Ubuntu-24.04 This might take a while... Create a default Unix user account: who ⏎ ← Ubuntu 用のユーザ名を入力する New password: password ⏎ ← パスワードを入力する Retype new password: password ⏎ ← パスワードを入力する (確認) passwd: password updated successfully To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details. PS C:\> # Ubuntu のバージョンを確認する who@pc:/mnt/c/Users/who$ cat /etc/os-release ⏎ PRETTY_NAME="Ubuntu 24.04.4 LTS" ← 24.04.4 LTS がインストールされた NAME="Ubuntu" VERSION_ID="24.04" VERSION="24.04.4 LTS (Noble Numbat)" VERSION_CODENAME=noble ID=ubuntu ID_LIKE=debian HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" UBUNTU_CODENAME=noble LOGO=ubuntu-logo who@pc:/mnt/c/Users/who$ # Ubuntu のホスト名を変更する (必要なら) who@pc:/mnt/c/Users/who$ # ここではホスト名を pc にしている who@pc:/mnt/c/Users/who$ # 設定を変更したあとは必ず wsl --shutdown を実行すること who@pc:/mnt/c/Users/who$ sudo bash -c "cat << 'EOF' >> /etc/wsl.conf [network] hostname = pc generateHosts = false EOF" ⏎ who@pc:/mnt/c/Users/who$ sudo bash -c "echo '127.0.0.1 pc' >> /etc/hosts" ⏎ who@pc:/mnt/c/Users/who$ exit ⏎ logout PS C:\> wsl --shutdown ⏎ PS C:\> exit ⏎
Ubuntuを入手するを確認して、R が 1 以上になっていない場合はひとつ前 (YY - 2) のバージョンを選択する。
分かりにくいことに、WSL でインストールするバージョンに R を指定することができない。
本稿の記述時点では、まだ 26.04.1 がリリースされていないため 24.04 を指定している。
2. NVM と Node.js のインストール
TypeScript は Node.js を使用して作成されている。
Node.js は更新頻度が高いので複数のバージョンを用意し、切り替えて使用する必要がある。
これを実現させるために NVM (Node Version Manager) をインストールした後に Node.js をインストールする。
NVM は公式の最新版ページの Assets から「Source code (tar.gz)」をダウンロード&インストールする。
今回は v0.40.4.tar.gz だった。
Node.js は NVM を使用してインストールする。
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # WSL2 の Ubuntu に入る PS C:\> wsl ~ ⏎ To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details. Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.6.87.2-microsoft-standard-WSL2 x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/pro System information as of Sat Mar 28 21:40:40 JST 2026 System load: 0.4 Processes: 35 Usage of /: 0.2% of 1006.85GB Users logged in: 1 Memory usage: 11% IPv4 address for eth0: 172.29.85.123 Swap usage: 0% * Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s just raised the bar for easy, resilient and secure K8s cluster deployment. https://ubuntu.com/engage/secure-kubernetes-at-the-edge This message is shown once a day. To disable it please create the /home/who/.hushlogin file. who@pc:~$ pwd ⏎ /home/who
who@pc:~$ # NVM の最新版をダウンロードする (最新版は公式ページを参照) who@pc:~$ curl -O -L https://github.com/nvm-sh/nvm/archive/refs/tags/v0.40.4.tar.gz ⏎ % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 352k 0 352k 0 0 492k 0 --:--:-- --:--:-- --:--:-- 6531k who@pc:~$ # ダウンロードした最新版からインストーラを取り出す who@pc:~$ tar xzf v0.40.4.tar.gz nvm-0.40.4/install.sh ⏎ who@pc:~$ # NVM をインストールする who@pc:~$ bash ./nvm-0.40.4/install.sh ⏎ => Downloading nvm from git to '/home/who/.nvm' => Cloning into '/home/who/.nvm'... remote: Enumerating objects: 423, done. remote: Counting objects: 100% (423/423), done. remote: Compressing objects: 100% (350/350), done. remote: Total 423 (delta 59), reused 187 (delta 45), pack-reused 0 (from 0) Receiving objects: 100% (423/423), 413.40 KiB | 1.79 MiB/s, done. Resolving deltas: 100% (59/59), done. * (HEAD detached at FETCH_HEAD) master => Compressing and cleaning up git repository => Appending nvm source string to /home/who/.bashrc => Appending bash_completion source string to /home/who/.bashrc => Close and reopen your terminal to start using nvm or run the following to use it now: export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion who@pc:~$ # .bashrc を現在環境へ反映させる (今回だけ。次回からは不要) who@pc:~$ . ~/.bashrc ⏎ who@pc:~$ echo $NVR_DIR ⏎ /home/who/.nvm who@pc:~$ nvm --version ⏎ 0.40.4
who@pc:~$ # Node.js をインストールする who@pc:~$ nvm install --lts ⏎ Installing latest LTS version. Downloading and installing node v24.14.1... Downloading https://nodejs.org/dist/v24.14.1/node-v24.14.1-linux-x64.tar.xz... ############################################################################################# 100.0% Computing checksum with sha256sum Checksums matched! Now using node v24.14.1 (npm v11.11.0) Creating default alias: default -> lts/* (-> v24.14.1 *) who@pc:~$ # Node.js のバージョンを確認する who@pc:~$ node -v ; npm -v ; npx -v ⏎ v24.14.1 ← Node.js のバージョン 11.11.0 ← npm のバージョン 11.11.0 ← npx のバージョン who@pc:~$ exit ⏎ logout PS C:\> exit ⏎
3. プロジェクトディレクトリの作成と TypeScript のインストール
*5インストールする npm パッケージは、JavaScript 実行時の要/不要を選択可能。
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # WSL2 の Ubuntu に入る PS C:\> wsl ~ ⏎ who@pc:~$ # プロジェクトディレクトリを作成し、Node.js 用に初期化する who@pc:~$ mkdir -p ./ts/hello/ ⏎ who@pc:~$ cd ./ts/hello/ ⏎ who@pc:~/ts/hello/$ npm init -y ⏎ Wrote to /home/who/ts/hello/package.json: { "name": "hello", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "type": "commonjs" } who@pc:~/ts/hello/$ # モジュール管理を ES Modules にする who@pc:~/ts/hello/$ sed -i 's/"type": "commonjs"/"type": "module"/' package.json ⏎ who@pc:~/ts/hello/$ # TypeScript 本体をインストールする*5 who@pc:~/ts/hello/$ npm install typescript --save-dev ⏎ added 1 package, and audited 2 packages in 10s found 0 vulnerabilities who@pc:~/ts/hello/$ # TypeScript のバージョンを確認する (tsc = TypeScript Compiler) who@pc:~/ts/hello/$ npx tsc -v ⏎ Version 6.0.2
who@pc:~/ts/hello/$ # TypeScript の設定ファイルを作成する (./tsconfig.json) who@pc:~/ts/hello/$ npx tsc --init ⏎ who@pc:~/ts/hello/$ # rootDir, outDir を有効化する who@pc:~/ts/hello/$ sed -i 's@// "rootDir":@"rootDir":@' ./tsconfig.json ⏎ who@pc:~/ts/hello/$ sed -i 's@// "outDir":@"outDir":@' ./tsconfig.json ⏎ who@pc:~/ts/hello/$ mkdir -p ./src/ ./dist/ ⏎
who@pc:~/ts/hello/$ # ソースファイルを作成し、トランスコンパイルする (.ts -> .js) who@pc:~/ts/hello/$ echo 'let message: string = "Hello, TypeScript"; console.log(message);' > ./src/hello.ts ⏎ who@pc:~/ts/hello/$ npx tsc ⏎ who@pc:~/ts/hello/$ cat ./dist/hello.js ⏎ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); let message = "Hello, TypeScript"; console.log(message); //# sourceMappingURL=hello.js.map who@pc:~/ts/hello/$ # 生成された .js ファイルを実行する who@pc:~/ts/hello/$ node ./dist/hello.js ⏎ Hello, TypeScript who@pc:~/ts/hello/$ exit ⏎ logout PS C:\> exit ⏎
TypeScript は変換器 (.ts → .js) であり、.js の実行時は不要なので --save-dev を指定する。
--save : 実行時に TypeScript を含める。(デフォルト)
--save-dev : 実行時に TypeScript を含めない。
4. じゃんけんサーバの作成と実行
4-1. じゃんけんサーバを TypeScript で作成し、Node.js で実行する。
4-2. じゃんけんサーバをアクセスする。*6index.html 等の静的コンテンツを返す指定。
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # WSL2 の Ubuntu に入る PS C:\> wsl ~ ⏎ who@pc:~$ # プロジェクトディレクトリを作成し、TypeScript 用に初期化する who@pc:~$ mkdir -p ./ts/janken/ ⏎ who@pc:~$ cd ./ts/janken/ ⏎ who@pc:~/ts/janken/$ npm init -y ⏎ who@pc:~/ts/janken/$ sed -i 's/"type": "commonjs"/"type": "module"/' package.json ⏎ who@pc:~/ts/janken/$ npm install typescript --save-dev ⏎ who@pc:~/ts/janken/$ npx tsc -init ⏎ who@pc:~/ts/janken/$ sed -i 's@// "rootDir":@"rootDir":@' ./tsconfig.json ⏎ who@pc:~/ts/janken/$ sed -i 's@// "outDir":@"outDir":@' ./tsconfig.json ⏎ who@pc:~/ts/janken/$ mkdir -p ./src/ ./dist/ ⏎
who@pc:~/ts/janken/$ # 軽量 Web サーバフレームワークをインストールする who@pc:~/ts/janken/$ npm install express --save ⏎ who@pc:~/ts/janken/$ npm install @types/express --save-dev ⏎
who@pc:~/ts/janken/$ # じゃんけんサーバを作成する who@pc:~/ts/janken/$ cat > ./src/player.ts << EOF import express, { type Request, type Response } from 'express'; const app = express(); app.use('/', express.static('./public')); // <-- これはあとで使う*6 const MY_NAME = process.env.MY_NAME || 'unknown'; const host = process.env.HOST || '0.0.0.0'; const port = Number(process.env.PORT) || 8080; const quiet = process.env.QUIET || false; app.get('/hand', (req: Request, res: Response) => { const remoteAddr = req.socket.remoteAddress const remotePort = req.socket.remotePort // ランダムに手を選択する const hands = ['R', 'P', 'S']; const hand = hands[Math.floor(Math.random() * hands.length)]; if (! quiet) console.log(\`[Hand Requested] From: \${remoteAddr}:\${remotePort} -> Selected: \${hand}\`); // JSONでレスポンスを返す res.json({ name: MY_NAME, hand: hand }); }); app.listen(port, host, () => { if (! quiet) { console.log(\`--------------------------------------------------\`); console.log(\`Janken Server (Express) started on \${host}:\${port}\`); console.log(\`Environment MY_NAME: \${MY_NAME}\`); console.log(\`--------------------------------------------------\`); } }); EOF ⏎ who@pc:~/ts/janken/$ # トランスコンパイルする who@pc:~/ts/janken/$ npx tsc ⏎
who@pc:~/ts/janken/$ # じゃんけんサーバを実行する who@pc:~/ts/janken/$ MY_NAME=jp1 node ./dist/player.js ⏎ -------------------------------------------------- Janken Server (Express) started on 0.0.0.0:8080 Environment MY_NAME: jp1 -------------------------------------------------- [Hand Requested] From: 127.0.0.1:56734 -> Selected: P ^C ← 停止は をタイプする (下記 4-2 を実行後) who@pc:~/ts/janken/$ exit ⏎ logout PS C:\> exit ⏎
上記 4-1 と別のターミナルウィンドウで作業する。
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # Web アクセスする PS C:\> curl.exe http://localhost:8080/hand ⏎ {"name":"jp1","hand":"P"} PS C:\> exit ⏎
5. MC クライアントの作成と実行
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # WSL2 の Ubuntu に入る PS C:\> wsl ~ ⏎ who@pc:~/ts/janken/$ # MC クライアントを作成する who@pc:~/ts/janken/$ cat > ./src/mc.ts << EOF import { type Request, type Response } from 'express'; // 指定秒数を待つ関数 const sleep = (ms: number) => new Promise(res => setTimeout(res, ms)); const nodes = [ 'http://localhost:8081/hand', 'http://localhost:8082/hand', 'http://localhost:8083/hand', ]; const results: Record<string, number> = { 'jp1': 0, 'jp2': 0, 'jp3': 0 }; // 判定ロジック function judge(h_a: string, h_b: string, h_c: string): string[] { const handsSet = new Set([h_a, h_b, h_c]); if (handsSet.size === 3) return []; // グー、チョキ、パー全部 if (handsSet.size === 1) return []; // あいこ const winMap: Record<string, string> = { 'R': 'S', // グーはチョキに勝つ 'S': 'P', // チョキはパーに勝つ 'P': 'R', // パーはグーに勝つ }; // 勝った手を判別する const handsArray = Array.from(handsSet); const h1 = handsArray[0]; const h2 = handsArray[1]; const winnerHand = winMap[h1!] === h2 ? h1 : h2; const winners: string[] = []; if (h_a === winnerHand) winners.push('jp1'); if (h_b === winnerHand) winners.push('jp2'); if (h_c === winnerHand) winners.push('jp3'); return winners; } // メインルーチン(async 関数にする必要がある) async function main() { console.log("Waiting for players to start..."); await sleep(3000); for (let i = 0; i < 10; i++) { process.stdout.write(\`Round \${(i + 1).toString().padStart(2)}: \`); try { // 3人から同時に「手」を取得(並列リクエスト) const responses = await Promise.all( nodes.map( url => fetch(url).then(r => r.json() as Promise<{ hand: string }>) )); const h_a = responses[0]!.hand; const h_b = responses[1]!.hand; const h_c = responses[2]!.hand; const winners = judge(h_a, h_b, h_c); winners.forEach(w => { if (results[w] !== undefined) results[w]++; }); console.log(\`jp1:\${h_a}, jp2:\${h_b}, jp3:\${h_c} -> 勝ち: [\${winners.join(', ')}]\`); } catch (e) { console.log(\`Error: \${e}\`); } } console.log('-----'); console.log('結果:', results); } main(); EOF ⏎ who@pc:~/ts/janken/$ # トランスコンパイルする who@pc:~/ts/janken/$ npx tsc ⏎ who@pc:~/ts/janken/$ # じゃんけんプレイヤーを 3 つ起動する who@pc:~/ts/janken/$ MY_NAME=jp1 PORT=8081 QUIET=true node ./dist/player.js & ⏎ who@pc:~/ts/janken/$ MY_NAME=jp2 PORT=8082 QUIET=true node ./dist/player.js & ⏎ who@pc:~/ts/janken/$ MY_NAME=jp3 PORT=8083 QUIET=true node ./dist/player.js & ⏎ who@pc:~/ts/janken/$ # MC クライアントを実行する who@pc:~/ts/janken/$ node ./dist/mc.js ⏎ Waiting for players to start... Round 1: jp1:S, jp2:P, jp3:S -> 勝ち: [jp1, jp3] Round 2: jp1:R, jp2:P, jp3:R -> 勝ち: [jp2] Round 3: jp1:S, jp2:R, jp3:S -> 勝ち: [jp2] Round 4: jp1:S, jp2:S, jp3:S -> 勝ち: [] Round 5: jp1:P, jp2:R, jp3:R -> 勝ち: [jp1] Round 6: jp1:P, jp2:P, jp3:S -> 勝ち: [jp3] Round 7: jp1:R, jp2:R, jp3:R -> 勝ち: [] Round 8: jp1:S, jp2:S, jp3:S -> 勝ち: [] Round 9: jp1:S, jp2:R, jp3:P -> 勝ち: [] Round 10: jp1:P, jp2:R, jp3:P -> 勝ち: [jp1, jp3] ----- 結果: { jp1: 3, jp2: 2, jp3: 3 } who@pc:~/ts/janken/$ # じゃんけんプレイヤーを 3 つ停止する (ポートを使用しているそれぞれのタスク) who@pc:~/ts/janken/$ fuser -k 8081/tcp 8082/tcp 8083/tcp ⏎ 8081/tcp: 2146 8082/tcp: 2153 8083/tcp: 2160 who@pc:~/ts/janken/$ exit ⏎ logout PS C:\> exit ⏎
6. 再表示を伴う画面更新
6-1. じゃんけんするページを静的に作成する。
6-2. じゃんけんページを表示する。
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # WSL2 の Ubuntu に入る PS C:\> wsl ~ ⏎ who@pc:~$ cd ./ts/janken/ ⏎ who@pc:~/ts/janken/$ # じゃんけんプレイヤーに index.html を仕込む (*6を利用する) who@pc:~/ts/janken/$ mkdir -p ./public/ ⏎ who@pc:~/ts/janken/$ cat > ./public/index.html << EOF <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Janken Player Status</title> </head> <body> <h1>Janken Player Status</h1> <iframe src="/hand" width=300 height=80></iframe> <hr> <p>ブラウザの 🗘 (更新ボタン) を押してください。</p> </body> </html> EOF ⏎ who@pc:~/ts/janken/$ # じゃんけんプレイヤーをひとつだけ起動する who@pc:~/ts/janken/$ node ./dist/player.js ⏎ -------------------------------------------------- Janken Server (Express) started on 0.0.0.0:8080 Environment MY_NAME: unknown -------------------------------------------------- [Hand Requested] From: 127.0.0.1:56996 -> Selected: R ^C ← 停止は をタイプする (下記 6-2 を実行後) who@pc:~/ts/janken/$ exit ⏎ logout PS C:\> exit ⏎
http://localhost:8080/ をブラウザでアクセスすると、上記 6-1 で作成した index.html が表示される。
<iframe> を使用しているためブラウザは GUI である必要がある。
ブラウザのリロードボタンをクリックすると、
じゃんけんプレイヤーがアクセスされることにより、<iframe> の中が更新される。
7. サーバとクライアントを開発
7-1. 定義ファイルの分割とクライアント用 TypeScirpt のトランスコンパイルを実行する
7-2. じゃんけんページを表示する。*7 tsconfig にモジュール指定を記述すると HTML に type="module" が必要となる。
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # WSL2 の Ubuntu に入る PS C:\> wsl ~ ⏎ who@pc:~$ cd ./ts/janken/ ⏎ who@pc:~/ts/janken/$ # tsconfig.json を再作成する who@pc:~/ts/janken/$ rm -f tsconfig.json ; npx tsc -init ⏎ who@pc:~/ts/janken/$ sed -i 's@// "rootDir":@"rootDir":@' ./tsconfig.json ⏎ who@pc:~/ts/janken/$ sed -i 's@// "outDir":@"outDir":@' ./tsconfig.json ⏎ who@pc:~/ts/janken/$ # tsconfig.json を分割する (server, client) who@pc:~/ts/janken/$ cp tsconfig.json tsconfig.server.json ⏎ who@pc:~/ts/janken/$ mv tsconfig.json tsconfig.client.json ⏎ who@pc:~/ts/janken/$ # サーバ用に tsconfig.server.json を変更する who@pc:~/ts/janken/$ vim tsconfig.server.json ⏎who@pc:~/ts/janken/$ # クライアント用に tsconfig.client.json を変更する who@pc:~/ts/janken/$ vim tsconfig.client.json ⏎
{ // Visit https://aka.ms/tsconfig to read more about this file "include": ["src/player.ts"], // 追加 "compilerOptions": { "composite": true, // 追加 // File Layout "rootDir": "./src", "outDir": "./dist", // Environment Settings // See also https://aka.ms/tsconfig/module "module": "nodenext", "target": "esnext", "types": ["node"], // 変更 …… // Recommended Options "strict": true, "jsx": "react-jsx", "verbatimModuleSyntax": true, "isolatedModules": true, "noUncheckedSideEffectImports": true, "moduleDetection": "force", // モジュール化 (確認*7) "skipLibCheck": true, } }who@pc:~/ts/janken/$ # ビルド用に tsconfig.json を再作成する who@pc:~/ts/janken/$ cat > tsconfig.json << EOF { "files": [], "references": [ { "path": "./tsconfig.server.json" }, { "path": "./tsconfig.client.json" } ] } EOF ⏎
{ // Visit https://aka.ms/tsconfig to read more about this file "include": ["src/client.ts"], // 追加 "compilerOptions": { "composite": true, // 追加 "lib": ["DOM", "ESNext"], // 追加 // File Layout "rootDir": "./src", "outDir": "./public/js", // 変更 // Environment Settings // See also https://aka.ms/tsconfig/module "module": "nodenext", "target": "esnext", "types": [], …… // Recommended Options "strict": true, "jsx": "react-jsx", "verbatimModuleSyntax": true, "isolatedModules": true, "noUncheckedSideEffectImports": true, "moduleDetection": "force", // モジュール化 (確認*7) "skipLibCheck": true, } }
who@pc:~/ts/janken/$ # クライアント用の /js/ ディレクトリを作成する who@pc:~/ts/janken/$ mkdir -p ./public/js/ ⏎ who@pc:~/ts/janken/$ # クライアント用の .ts を作成する who@pc:~/ts/janken/$ cat > ./src/client.ts << EOF /** * サーバから「手」を取得して画面を更新する関数 */ async function updateHand(): Promise<void> { const resultDiv = document.getElementById('result'); try { // サーバの /hand をアクセスする const response = await fetch('/hand'); if (!response.ok) { throw new Error(\`HTTP error! status: \${response.status}\`); } // JSON データの受信 const data: { name: string; hand: string } = await response.json(); // DOM の書き換え if (resultDiv) { // サーバから返ってきた "R", "P", "S" をそのまま表示 resultDiv.innerText = \`出した手: \${data.hand}\`; } } catch (error) { console.error('通信に失敗しました:', error); if (resultDiv) { resultDiv.innerText = 'エラーが発生しました。'; } } } /** * イベントリスナーの登録 * ページロード時に HTML のボタンと関数を紐付ける */ window.addEventListener('DOMContentLoaded', () => { const btn_pon = document.getElementById('btn_pon'); if (btn_pon) { btn_pon.addEventListener('click', updateHand); } }); EOF ⏎
who@pc:~/ts/janken/$ # index.html を再作成する who@pc:~/ts/janken/$ cat > ./public/index.html << EOF <!DOCTYPE html> <html> <body> <h1>Janken Client</h1> <span id="result">じゃん、けん…</span> <button id="btn_pon">ポン</button> <script src="/js/client.js" type="module"></script> <!--*7--> </body> </html> EOF ⏎
who@pc:~/ts/janken/$ # じゃんけんシステムをビルドする who@pc:~/ts/janken/$ npx tsc -b ⏎ who@pc:~/ts/janken/$ ls -ogh ./public/index.html ./public/js/client.js ./dist/player.js ⏎ -rw-r--r-- 1 1.2K Mar 31 14:38 ./dist/player.js -rw-r--r-- 1 205 Mar 31 14:37 ./public/index.html -rw-r--r-- 1 1.2K Mar 31 14:38 ./public/js/client.js
who@pc:~/ts/janken/$ # じゃんけんプレイヤーをひとつだけ起動する who@pc:~/ts/janken/$ node ./dist/player.js ⏎ -------------------------------------------------- Janken Server (Express) started on 0.0.0.0:8080 Environment MY_NAME: unknown -------------------------------------------------- [Hand Requested] From: 127.0.0.1:35866 -> Selected: R ^C ← 停止は をタイプする (下記 7-2 を実行後) who@pc:~/ts/janken/$ exit ⏎ logout PS C:\> exit ⏎
http://localhost:8080/ をブラウザでアクセスすると、上記 7-1 で作成した index.html (と /js/client.js) が表示される。
ボタンをクリックすると、
じゃんけんプレイヤーがアクセスされることにより、手が変化する。(R,P,S のどれか)