Windows での PWA 開発環境セットアップ(WSL2 + Node LTS + pnpm + Vite + vite-plugin-pwa、Laravel API 連携)

Windows での PWA 開発環境セットアップ(WSL2 + Node + pnpm + Vite + Laravel 連携)

このドキュメントは、これまで実施した Windows 側の環境設定を 再現性のある手順として整理したものです。ゴールは 「React/TypeScript の PWA を Windows 上で快適に開発し、Laravel API と連携する」こと。WSL2 を使い、フロントは Vite、パッケージは pnpm、PWA は vite-plugin-pwa で構築します。


0. PWAとは

PWA(Progressive Web App)は、Web技術(HTML/CSS/JS)で作るインストール可能なアプリです。URLで開ける通常のWebと同じ配布性を保ちつつ、ホーム画面アイコン全画面表示オフライン動作プッシュ通知(対応環境)など、ネイティブに近い体験を提供します。中核は以下の3要素です。

  • Service Worker:ブラウザの裏方で動くスクリプト。リソースやAPI応答のキャッシュオフラインバックグラウンド同期(限定)を担当。
  • Web App Manifest:アプリ名、アイコン、テーマ色、起動モード(standalone)などのメタ情報。これがあると「ホーム画面に追加」等が有効に。
  • HTTPS:SWや多くのデバイスAPIは安全なコンテキストが必須。開発時の http://localhost は例外的に安全扱い。

できること:オフライン閲覧・フォーム/キューのローカル保存(IndexedDB)・カメラ/マイク/位置情報・WebGPU/WebGL/WASMでの端末内推論・Web Share・AndroidでのWeb Push 等。

弱いところ:iOSのバックグラウンド制限、長時間の常駐処理不可、細粒度のハード制御(ISO/露出など)は不可。
結論として、今回の動画+GPXの大容量アップロード/オフライン一時保存/再送という要件にPWAは適合します。重い推論はサーバ側(Laravel→Python)に回し、端末側は前処理やUIに注力する構成が堅牢です。


1. ゴールと構成

  • WSL2 (Ubuntu) 上で Node LTS + pnpm を利用してフロントエンドを開発
  • Vite + React/TypeScript で PWA 雛形を作成、vite-plugin-pwa で SW/Manifest を自動生成
  • 開発中は http://localhost:5173(安全なローカル)で SW が動作、Laravel API は /api プロキシ
  • Android 実機は adb reverse でローカルに接続し、PWA をホーム追加して検証

2. 前提条件と管理者権限の扱い

基本スタンスは 「普段は一般ユーザ権限、初回の OS 設定だけ管理者」です。

管理者が必要管理者不要
WSL / 仮想化機能の有効化(DISM)Vite 開発サーバ起動、コード編集
mkcert -install で証明書を信頼ストアに登録(任意)pnpm での依存解決やビルド
Chocolatey 等のシステム範囲インストールService Worker の登録(localhost は安全扱い)

3. Windows の機能(有効化するもの)

WSL2 を使うなら、次の 2 つにチェック → 再起動。

  • Linux 用 Windows サブシステム
  • Virtual Machine Platform(仮想マシンプラットフォーム)

Docker や一部エミュレータを使う場合のみ Windows ハイパーバイザー プラットフォーム を ON。その他(IIS、SMB1.0、Telnet、Windows PowerShell 2.0 など)は不要・OFF で問題なし。


4. WSL2 の導入と確認(PowerShell)

管理者 PowerShell で実行。すでに完了していますが、復習として掲載。

# 機能の有効化(未有効なら)
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

# 再起動後に導入
wsl --install -d Ubuntu
wsl --set-default-version 2

# 状態確認
wsl --status
wsl --list --verbose

想定出力:

既定のディストリビューション: Ubuntu
既定のバージョン: 2

NAME     STATE    VERSION
* Ubuntu Running  2

注:「wsl: command not found」は wsl: という文字列を打った入力ミスの典型。正しくは wsl(コロン無し)。


5. Ubuntu(WSL2 内)で Node LTS + pnpm

WSL2 の Ubuntu ターミナルで実行。プロジェクトは Linux 側のファイルシステム(例:~/src に置くと高速です(/mnt/c は遅い)。

sudo apt-get update
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.nvm/nvm.sh
nvm install --lts
corepack enable
corepack prepare pnpm@9 --activate
node -v && pnpm -v

6. Vite + React/TypeScript プロジェクトの作成

mkdir -p ~/src && cd ~/src
npm create vite@latest pwa-app -- --template react-ts
cd pwa-app
pnpm i
pnpm add -D vite-plugin-pwa workbox-window

6.1 vite.config.ts(PWA と API プロキシ)

開発中に Service Worker を有効化し、/api を Laravel にプロキシします。

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { VitePWA } from 'vite-plugin-pwa'

export default defineConfig({
  plugins: [
    react(),
    VitePWA({
      registerType: 'autoUpdate',
      manifest: {
        name: 'GPX/Video Uploader',
        short_name: 'Uploader',
        start_url: '/?source=pwa',
        display: 'standalone',
        background_color: '#ffffff',
        theme_color: '#0ea5e9',
        icons: [
          { src: 'icons/icon-192.png', sizes: '192x192', type: 'image/png' },
          { src: 'icons/icon-512.png', sizes: '512x512', type: 'image/png' }
        ]
      },
      workbox: {
        navigateFallback: '/index.html',
        runtimeCaching: [{ urlPattern: /^\/api\//, handler: 'NetworkFirst' }]
      },
      devOptions: { enabled: true }
    })
  ],
  server: {
    host: true,
    proxy: { '/api': { target: 'http://localhost:8000', changeOrigin: true } }
  }
})

6.2 PWA アイコンの配置

最初はアイコンが無くて OK ではありません。自分で作る必要があります。ファイルパスを「コマンドのように」叩くとエラーになるので注意。

mkdir -p public/icons
# 例:簡易アイコンを ImageMagick で生成
sudo apt-get install -y imagemagick
convert -size 192x192 xc:"#0ea5e9" public/icons/icon-192.png
convert -size 512x512 xc:"#0ea5e9" public/icons/icon-512.png

# または Python/Pillow
python3 - <<'PY'
from PIL import Image, ImageDraw
for s in (192,512):
    im=Image.new('RGBA',(s,s),'#0ea5e9')
    d=ImageDraw.Draw(im); d.ellipse((s*0.2,s*0.2,s*0.8,s*0.8), fill='white')
    im.save(f'public/icons/icon-{s}.png')
PY

6.3 起動

pnpm dev
# ブラウザで http://localhost:5173
# DevTools → Application → Service Workers で登録確認

補足:localhost は安全扱いのため、開発時は HTTPS でなくても SW が動作します。


7. Laravel API 側(簡単な連携)

開発中は Laravel をローカルで起動し、フロントからは /api プロキシで叩きます。

# Laravel 側(WSL でも Windows 側でも可)
php artisan serve --host=0.0.0.0 --port=8000
  • CORS は http://localhost:5173 を許可(Sanctum SPA モード or PAT)。
  • PWA 側から fetch('/api/...') で呼べば、Vite のプロキシが http://localhost:8000 に中継。

8. Android 実機テスト(ローカル接続)

Android の開発者モードを有効化し、adb を使用します。端末と PC を USB 接続。

adb devices
adb reverse tcp:5173 tcp:5173
adb reverse tcp:8000 tcp:8000
# 端末の Chrome で http://localhost:5173 → 「ホーム画面に追加」で PWA 起動

HTTPS を使った外部端末検証が必要な場合のみ、mkcert 等でローカル証明書を発行し、Vite の server.https に設定。ただし日常の開発では不要です。


9. よくあるハマりどころと対処

  • wsl: command not found:PowerShell ではなく別シェル(Git Bash 等)で実行している、または単に wsl: と打っている。wslPowerShell/CMD で。
  • Vite の URL が端末から見えないadb reverse を実行、または同一 Wi-Fi で PC の IP を使う。
  • アイコンが無いpublic/icons を作って icon-192.png, icon-512.png を配置。パスを「実行」しないこと。
  • WSL の性能が遅い:プロジェクトは ~/src(Linux 側)に置く。/mnt/c は避ける。
  • Service Worker が更新されない:vite-plugin-pwa の registerType:'autoUpdate' で自動更新。手動なら DevTools の「Unregister」→ リロード。

10. 任意:ローカル HTTPS(mkcert)

外部端末から https://<PC-IP>:5173 で検証したい場合のみ。Windows 側で一度だけ管理者権限が必要です。

# PowerShell(管理者)で mkcert を導入(Chocolatey例)
choco install mkcert -y
mkcert -install

# 証明書作成(任意のフォルダで)
mkdir cert & cd cert
mkcert localhost 127.0.0.1 ::1

# Vite の server.https に設定(vite.config.ts)
server: {
  https: {
    key: fs.readFileSync('cert/localhost-key.pem'),
    cert: fs.readFileSync('cert/localhost.pem')
  },
  host: true
}

開発中は基本的に HTTP の localhost で十分です(SW 動作可)。


11. 仕上げチェック(Lighthouse)

  • Chrome DevTools → Lighthouse → PWA カテゴリを実行
  • 要件:Manifest / Service Worker / アイコン / オフライン対応 / HTTPS(本番)

12. 次の拡張

  • 大容量アップロード:S3 Multipart 直 PUT または tus に対応し、IndexedDB でレジューム
  • GPX/POI 可視化:Leaflet/MapLibre を追加、送信前確認を UI 化
  • Sanctum 認証:テナントスコープ(会社/部署/端末)をフロント設定に保存
  • 端末内前処理:必要に応じて tfjs / ORT Web を導入(モデルは IndexedDB キャッシュ)

付録:実施コマンドまとめ

# PowerShell(管理者)
dism /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
wsl --install -d Ubuntu
wsl --set-default-version 2
wsl --list --verbose --status

# Ubuntu(WSL2)
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.nvm/nvm.sh
nvm install --lts
corepack enable && corepack prepare pnpm@9 --activate
npm create vite@latest pwa-app -- --template react-ts
cd pwa-app && pnpm i && pnpm add -D vite-plugin-pwa workbox-window
mkdir -p public/icons
convert -size 192x192 xc:"#0ea5e9" public/icons/icon-192.png
convert -size 512x512 xc:"#0ea5e9" public/icons/icon-512.png
pnpm dev

# Android 実機
adb reverse tcp:5173 tcp:5173
adb reverse tcp:8000 tcp:8000

これで、Windows 上の WSL2 を軸に PWA のビルド/実機検証/バックエンド連携まで一通り回せます。追加で S3 直 PUT・tus を組み込みたい場合は、そのまま雛形を拡張できます。©株式会社ビー・ナレッジ・デザイン

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA