転職したらスマレジだった件

スマレジのエンジニアやまてのテックブログです。マジレス大歓迎です。

Laravel 10 と React 18 の SPA 開発環境の構築手順(ucan-lab/docker-laravel 利用版)

スマレジのテックファーム(SES 部門)で Web 系エンジニアとして働いている やまて(@r_yamate) と申します。

2023 年 4 月からは、スマレジの関連アプリの開発業務を担当しています。触ったことのなかった Flutter での開発を担当(React も少々)することになり、日々奮闘中です。開発しているアプリはモニター利用も始まり、開発の醍醐味を味わえていて楽しいです。

はじめに

今回は Laravel 10 と React 18 の SPA の開発環境を、ucan-lab/docker-laravel を用いて構築します。

前回は、Laravel Sail を活用して構築する手順について投稿しましたが、自身が何度か利用したことがあって使い慣れている ucan-lab/docker-laravel で React を導入したいと思い、その方法も試してみます。

ryamate.hatenablog.com

目次

環境

$ git --version
git version 2.33.0

$ docker --version
Docker version 20.10.22, build 3a2c30b

$ docker compose version
Docker Compose version v2.15.1

バックエンド

  • Laravel 10(Vite)
  • MySQL 8

フロントエンド

  • React 18
  • Sass
  • TypeScript

ucan-lab/docker-laravel

ucan-lab/docker-laravel は「Docker, Docker Compose を使って、nginx, php-fpm, MySQLの実行環境(LEMP)を構築して、最強のLaravel開発環境」を用意できるリポジトリです。

github.com

qiita.com

2 年前にポートフォリオとしての Web アプリを作ったときも活用させていただきましたが、とても使いやすいのでオススメです。

ただ更新がマメに実施されるため、2年前とも使い方が結構変わっているようです。(その変更を確認することも、参考になってとても良いです)

1. Laravel の開発環境構築

Laravel の開発環境を構築します。

※ Docker Desktop が必要です。

www.docker.com

ターミナルを開き、任意のディレクトリに移動し、 git clone コマンドを実行します。

git clone https://github.com/ucan-lab/docker-laravel.git sample-app

プロジェクトルートに移動します。

cd sample-app
# r_yamate @ mbp in ~/development [9:29:05]
$ git clone https://github.com/ucan-lab/docker-laravel.git sample-app
Cloning into 'sample-app'...
remote: Enumerating objects: 689, done.
remote: Counting objects: 100% (232/232), done.
remote: Compressing objects: 100% (108/108), done.
remote: Total 689 (delta 134), reused 174 (delta 107), pack-reused 457
Receiving objects: 100% (689/689), 460.05 KiB | 5.35 MiB/s, done.
Resolving deltas: 100% (345/345), done.

# r_yamate @ mbp in ~/development [9:30:34]
$ cd sample-app

docker-laravel の README.md のとおり、以下の make コマンドを実行して、Laravel の開発環境を構築します。

make create-project
  • コマンド実行時ログ

      # r_yamate @ mbp in ~/development/sample-app on git:main o [9:31:39]
      $ make create-project
      mkdir -p src
      docker compose build
      [+] Building 0.0s (0/0)
      [+] Building 0.0s (0/0)
      [+] Building 0.1s (0/1)
       => [internal] load build definition from Dockerfile                                  0.1s
      [+] Building 0.2s (1/2)
       => [internal] load build definition from Dockerfile                                  0.2s
      [+] Building 0.3s (2/2)
       => [internal] load build definition from Dockerfile                                  0.2s
      [+] Building 0.4s (5/5)
       => [internal] load build definition from Dockerfile                                  0.2s
      [+] Building 0.5s (6/6) FINISHED
       => [internal] load build definition from Dockerfile                                  0.2s
       => => transferring dockerfile: 151B                                                  0.0s
       => [internal] load .dockerignore                                                     0.1s
       => => transferring context: 561B                                                     0.0s
       => [internal] load metadata for docker.io/mysql/mysql-server:8.0                     0.0s
       => [1/2] FROM docker.io/mysql/mysql-server:8.0                                       0.0s
      [+] Building 0.4s (2/3)
      [+] Building 5.4s (4/7)
       => [internal] load build definition from Dockerfile                                  0.1s
       => => transferring dockerfile: 138B                                                  0.0s
       => [internal] load .dockerignore                                                     0.0s
       => => transferring context: 561B                                                     0.0s
       => [internal] load metadata for docker.io/library/nginx:1.25                         4.7s
      [+] Building 5.5s (4/7)
       => [internal] load build definition from Dockerfile                                  0.1s
       => => transferring dockerfile: 138B                                                  0.0s
      [+] Building 7.2s (4/7)
      [+] Building 8.4s (4/7)
      [+] Building 9.2s (4/7)
       => [internal] load build definition from Dockerfile                                  0.1s
      [+] Building 9.5s (4/7)
      [+] Building 13.8s (4/11)
      [+] Building 22.0s (4/11)
      [+] Building 26.1s (4/11)
       => [internal] load metadata for docker.io/library/php:8.3-fpm-bullseye               4.9s
       => [internal] load metadata for docker.io/library/nginx:1.25                         4.7s
       => [1/3] FROM docker.io/library/nginx:1.25@sha256:10d1f5b58f74683ad34eb29287e07dab  20.9s
       => => resolve docker.io/library/nginx:1.25@sha256:10d1f5b58f74683ad34eb29287e07dab1  0.0s
       => => sha256:10d1f5b58f74683ad34eb29287e07dab1e90f10af243f151bb50aa 1.86kB / 1.86kB  0.0s
       => => sha256:3c4c1f42a89e343c7b050c5e5d6f670a0e0b82e70e0e7d023f1009 1.78kB / 1.78kB  0.0s
       => => sha256:1f7ce2fa46ab3942feabee654933948821303a5a821789dddab2 29.15MB / 29.15MB  3.3s
       => => sha256:9b16c94bb68628753a94b89ddf26abc0974cd35a96f785895ab0 41.38MB / 41.38MB  3.8s
       => => sha256:a6bd71f48f6839d9faae1f29d3babef831e76bc213107682c5cc80 8.15kB / 8.15kB  0.0s
       => => sha256:9a59d19f9c5bb1ebdfef2255496b1bb5d658fdccc300c4c1f0d18c73f1 625B / 625B  0.5s
       => => sha256:9ea27b074f71d5766a59cdbfaa15f4cd3d17bffb83fed066373eb28732 959B / 959B  0.9s
       => => sha256:c6edf33e2524b241a0b191d0a0d2ca3d8d4ae7470333b059dd97ba30e6 371B / 371B  1.3s
       => => sha256:84b1ff10387b26e2952f006c0a4fe4c6f3c0743cb08ee448bb7157 1.21kB / 1.21kB  1.7s
       => => sha256:51735783196785d1f604dc7711ea70fb3fab3cd9d99eaeff991c5a 1.40kB / 1.40kB  2.0s
       => => extracting sha256:1f7ce2fa46ab3942feabee654933948821303a5a821789dddab2d8c3df5  7.6s
       => => extracting sha256:9b16c94bb68628753a94b89ddf26abc0974cd35a96f785895ab011d9b50  4.1s
      [+] Building 28.3s (4/11)
      [+] Building 28.4s (4/11)
      [+] Building 28.8s (4/11)
      [+] Building 28.9s (4/11)
      [+] Building 29.0s (4/11)
      [+] Building 30.3s (4/11)
      [+] Building 31.4s (4/11)
      [+] Building 31.6s (4/11)
       => [base 1/4] FROM docker.io/library/php:8.3-fpm-bullseye@sha256:2d5f4befa91070594  26.3s
      [+] Building 32.2s (4/11)
       => [base 1/4] FROM docker.io/library/php:8.3-fpm-bullseye@sha256:2d5f4befa91070594  26.8s
      [+] Building 164.1s (12/12) FINISHED
       => [internal] load build definition from Dockerfile                                  0.1s
       => => transferring dockerfile: 1.55kB                                                0.0s
       => [internal] load .dockerignore                                                     0.1s
       => => transferring context: 561B                                                     0.0s
       => [internal] load metadata for docker.io/library/php:8.3-fpm-bullseye               4.9s
       => [internal] load build context                                                     0.1s
       => => transferring context: 613B                                                     0.0s
       => [base 1/4] FROM docker.io/library/php:8.3-fpm-bullseye@sha256:2d5f4befa91070594  31.3s
       => => resolve docker.io/library/php:8.3-fpm-bullseye@sha256:2d5f4befa91070594565fdc  0.1s
       => => sha256:2d5f4befa91070594565fdc5ea82d195afbc7ab58f751ffa3f15a1 1.86kB / 1.86kB  0.0s
       => => sha256:847b1caa324dbe80aa89aa9c0bab82b4f35f28ac7ade8fdb00cc68 2.41kB / 2.41kB  0.0s
       => => sha256:a5167fbbfff9b6ff9064d01373065a0257e93c7bb02ec3c0e1e1 11.87kB / 11.87kB  0.0s
       => => sha256:b7f91549542cca4b35a34cdee5364339f17468971ea730bb0728 31.42MB / 31.42MB  4.0s
       => => sha256:0754b57b9b7d3a089ca18ba98121861a56ce2624c2875a8e7bf8b21a79 225B / 225B  3.6s
       => => sha256:71e5060f3937930b5fa3d39f56adf3c2acfea72741014d1969f3 91.64MB / 91.64MB  8.2s
       => => sha256:f25a6e74b7f558f50a59c2efa94a62c44a6323861b0c76e6d2144078ab 271B / 271B  4.1s
       => => sha256:cfe33a1c9e51d04803112f71e930c4269107031efc4492cc8c5c 12.75MB / 12.75MB  6.6s
       => => sha256:d58c6c3d379db9c036fab15df68bd59cd5c41b64cff7c04b1273c9d677 494B / 494B  4.5s
       => => sha256:cf1390e81c475fb5d364ad488163d4b7f30014dc41029f88be5b 26.78MB / 26.78MB  7.5s
       => => sha256:f79e7693b86d830f0e80c0cf8a0b5cdeeac23d4b6f34288dcb8bd3 2.45kB / 2.45kB  6.9s
       => => sha256:9d907b627720968665b5d5d86ca0cbe3216a59fd11482c0a2ecd5177a0 246B / 246B  7.3s
       => => extracting sha256:b7f91549542cca4b35a34cdee5364339f17468971ea730bb072864d3e78  8.3s
       => => sha256:3aae34d45ac145909b5032380784641470d1f0b6e98814b113fc81 9.18kB / 9.18kB  8.7s
       => => extracting sha256:0754b57b9b7d3a089ca18ba98121861a56ce2624c2875a8e7bf8b21a795  0.0s
       => => extracting sha256:71e5060f3937930b5fa3d39f56adf3c2acfea72741014d1969f3f437e5  11.3s
       => => extracting sha256:f25a6e74b7f558f50a59c2efa94a62c44a6323861b0c76e6d2144078ab6  0.0s
       => => extracting sha256:cfe33a1c9e51d04803112f71e930c4269107031efc4492cc8c5c0bc4bf3  0.2s
       => => extracting sha256:d58c6c3d379db9c036fab15df68bd59cd5c41b64cff7c04b1273c9d677d  0.0s
       => => extracting sha256:cf1390e81c475fb5d364ad488163d4b7f30014dc41029f88be5b98f2167  1.4s
       => => extracting sha256:f79e7693b86d830f0e80c0cf8a0b5cdeeac23d4b6f34288dcb8bd3b9df0  0.0s
       => => extracting sha256:9d907b627720968665b5d5d86ca0cbe3216a59fd11482c0a2ecd5177a0b  0.0s
       => => extracting sha256:3aae34d45ac145909b5032380784641470d1f0b6e98814b113fc81730d9  0.0s
       => FROM docker.io/library/composer:2.6                                              27.3s
       => => resolve docker.io/library/composer:2.6                                         4.3s
       => => sha256:67f1bec07666f688791bff2c13b34b9c35042cc4c1e42fbb5bd4db 1.65kB / 1.65kB  0.0s
       => => sha256:20f5108974c63c7f1053b3a1e45215aeee2a83ee2c3e6fa0d011a9 3.25kB / 3.25kB  0.0s
       => => sha256:a367d1cb680d822e1cfff066254fd1db8392a47a1b7c31c38d62 11.34kB / 11.34kB  0.0s
       => => sha256:c926b61bad3b94ae7351bafd0c184c159ebf0643b085f7ef1d47ec 3.40MB / 3.40MB  4.0s
       => => extracting sha256:c926b61bad3b94ae7351bafd0c184c159ebf0643b085f7ef1d47ecdc731  0.8s
       => => sha256:e8e26b626c27026d1938a0b6bd77e36b4113da4b7a1134df8d1aa9 2.68MB / 2.68MB  5.2s
       => => sha256:23427f6f19cc27aa3496173559d7fc30c2501d1d179a15b52ac175 1.26kB / 1.26kB  4.7s
       => => sha256:938ee652f0dd66c081c31e773163d4c3d8ec979f9ced384ed270cdc5fb 269B / 269B  4.9s
       => => sha256:8abe2aaf4047e9984223c8d63be88c09b7d447f8c9f77851aa06 12.45MB / 12.45MB  7.5s
       => => sha256:e06ec6f102433dfe7410990547f8d059d4c3e56455e35d7b4dfbfb9678 492B / 492B  5.2s
       => => sha256:9ea984f05cf27a91a07a0b1f63adb1e6f9c4cb631325b5a07343 17.07MB / 17.07MB  7.3s
       => => extracting sha256:e8e26b626c27026d1938a0b6bd77e36b4113da4b7a1134df8d1aa9f4965  0.8s
       => => sha256:2e6c3ecb64ca025834e2eba225bd5d603742000e1d67407ba50cf0 2.45kB / 2.45kB  5.7s
       => => sha256:d3b07fe920dd6973a44ea83074fd9125fe7d4774492d00c0ffef 18.95kB / 18.95kB  6.3s
       => => extracting sha256:23427f6f19cc27aa3496173559d7fc30c2501d1d179a15b52ac1758cc16  0.0s
       => => sha256:db476e3c025b598a275cc72e45c12e45db55e1df982d1e90e45f 32.53MB / 32.53MB  8.6s
       => => extracting sha256:938ee652f0dd66c081c31e773163d4c3d8ec979f9ced384ed270cdc5fbc  0.0s
       => => sha256:00b605206545e71c8d6637e233d08e5cae279512b88f4eedbb3dd94449 257B / 257B  7.7s
       => => sha256:a3f172b6c24514834b464f5a515ea799ff120009dbb5e8be3574b7 1.32MB / 1.32MB  8.2s
       => => sha256:f4200807651477364bc9a9c65461e6606f9fd636a2bc8f3bb3b22b6c84 419B / 419B  8.0s
       => => extracting sha256:8abe2aaf4047e9984223c8d63be88c09b7d447f8c9f77851aa06771c52b  0.9s
       => => sha256:3ae5dfbba469e3be92262cca5c2241876dc072ecaaff4285c202d0c0c3e3 93B / 93B  8.3s
       => => extracting sha256:e06ec6f102433dfe7410990547f8d059d4c3e56455e35d7b4dfbfb96784  0.0s
       => => extracting sha256:9ea984f05cf27a91a07a0b1f63adb1e6f9c4cb631325b5a07343b8faf75  3.0s
       => => extracting sha256:2e6c3ecb64ca025834e2eba225bd5d603742000e1d67407ba50cf0f60ea  0.0s
       => => extracting sha256:d3b07fe920dd6973a44ea83074fd9125fe7d4774492d00c0ffefb9a04a8  0.0s
       => => extracting sha256:db476e3c025b598a275cc72e45c12e45db55e1df982d1e90e45f76b630e  6.3s
       => => extracting sha256:00b605206545e71c8d6637e233d08e5cae279512b88f4eedbb3dd944494  0.0s
       => => extracting sha256:a3f172b6c24514834b464f5a515ea799ff120009dbb5e8be3574b779c4f  0.3s
       => => extracting sha256:f4200807651477364bc9a9c65461e6606f9fd636a2bc8f3bb3b22b6c847  0.0s
       => => extracting sha256:3ae5dfbba469e3be92262cca5c2241876dc072ecaaff4285c202d0c0c3e  0.0s
       => [base 2/4] WORKDIR /workspace                                                     0.5s
       => [base 3/4] COPY --from=composer:2.6 /usr/bin/composer /usr/bin/composer           0.1s
       => [base 4/4] RUN apt-get update   && apt-get -y install --no-install-recommends   121.2s
       => [development 1/2] RUN apt-get -y install --no-install-recommends     default-mys  4.3s
       => [development 2/2] COPY ./infra/docker/php/php.development.ini /usr/local/etc/php  0.0s
       => exporting to image                                                                1.2s
       => => exporting layers                                                               1.2s
       => => writing image sha256:fed5decbff1787633896f6ad5c2c62e4d368f83d36ede7181f8b6288  0.0s
       => => naming to docker.io/library/sample-app-app                                     0.0s
      docker compose up -d
      [+] Running 7/7
       ⠿ Network sample-app_default       Created                                           0.1s
       ⠿ Volume "sample-app_db-store"     Created                                           0.0s
       ⠿ Volume "sample-app_psysh-store"  Created                                           0.0s
       ⠿ Container sample-app-app-1       Started                                           1.4s
       ⠿ Container sample-app-db-1        Started                                           1.3s
       ⠿ Container sample-app-mailpit-1   Started                                           1.3s
       ⠿ Container sample-app-web-1       Started                                           1.4s
      docker compose exec app composer create-project --prefer-dist laravel/laravel .
      Creating a "laravel/laravel" project at "./"
      Installing laravel/laravel (v10.2.9)
        - Downloading laravel/laravel (v10.2.9)
        - Installing laravel/laravel (v10.2.9): Extracting archive
      Created project in /workspace/.
      > @php -r "file_exists('.env') || copy('.env.example', '.env');"
      Loading composer repositories with package information
      Updating dependencies
      Lock file operations: 111 installs, 0 updates, 0 removals
        - Locking brick/math (0.11.0)
        - Locking carbonphp/carbon-doctrine-types (3.0.0)
        - Locking dflydev/dot-access-data (v3.0.2)
        - Locking doctrine/inflector (2.0.8)
        - Locking doctrine/lexer (3.0.0)
        - Locking dragonmantank/cron-expression (v3.3.3)
        - Locking egulias/email-validator (4.0.2)
        - Locking fakerphp/faker (v1.23.0)
        - Locking filp/whoops (2.15.4)
        - Locking fruitcake/php-cors (v1.3.0)
        - Locking graham-campbell/result-type (v1.1.2)
        - Locking guzzlehttp/guzzle (7.8.0)
        - Locking guzzlehttp/promises (2.0.1)
        - Locking guzzlehttp/psr7 (2.6.1)
        - Locking guzzlehttp/uri-template (v1.0.2)
        - Locking hamcrest/hamcrest-php (v2.0.1)
        - Locking laravel/framework (v10.34.2)
        - Locking laravel/pint (v1.13.6)
        - Locking laravel/prompts (v0.1.13)
        - Locking laravel/sail (v1.26.2)
        - Locking laravel/sanctum (v3.3.2)
        - Locking laravel/serializable-closure (v1.3.3)
        - Locking laravel/tinker (v2.8.2)
        - Locking league/commonmark (2.4.1)
        - Locking league/config (v1.2.0)
        - Locking league/flysystem (3.21.0)
        - Locking league/flysystem-local (3.21.0)
        - Locking league/mime-type-detection (1.14.0)
        - Locking mockery/mockery (1.6.6)
        - Locking monolog/monolog (3.5.0)
        - Locking myclabs/deep-copy (1.11.1)
        - Locking nesbot/carbon (2.72.0)
        - Locking nette/schema (v1.2.5)
        - Locking nette/utils (v4.0.3)
        - Locking nikic/php-parser (v4.17.1)
        - Locking nunomaduro/collision (v7.10.0)
        - Locking nunomaduro/termwind (v1.15.1)
        - Locking phar-io/manifest (2.0.3)
        - Locking phar-io/version (3.2.1)
        - Locking phpoption/phpoption (1.9.2)
        - Locking phpunit/php-code-coverage (10.1.9)
        - Locking phpunit/php-file-iterator (4.1.0)
        - Locking phpunit/php-invoker (4.0.0)
        - Locking phpunit/php-text-template (3.0.1)
        - Locking phpunit/php-timer (6.0.0)
        - Locking phpunit/phpunit (10.5.1)
        - Locking psr/clock (1.0.0)
        - Locking psr/container (2.0.2)
        - Locking psr/event-dispatcher (1.0.0)
        - Locking psr/http-client (1.0.3)
        - Locking psr/http-factory (1.0.2)
        - Locking psr/http-message (2.0)
        - Locking psr/log (3.0.0)
        - Locking psr/simple-cache (3.0.0)
        - Locking psy/psysh (v0.11.22)
        - Locking ralouphie/getallheaders (3.0.3)
        - Locking ramsey/collection (2.0.0)
        - Locking ramsey/uuid (4.7.5)
        - Locking sebastian/cli-parser (2.0.0)
        - Locking sebastian/code-unit (2.0.0)
        - Locking sebastian/code-unit-reverse-lookup (3.0.0)
        - Locking sebastian/comparator (5.0.1)
        - Locking sebastian/complexity (3.1.0)
        - Locking sebastian/diff (5.0.3)
        - Locking sebastian/environment (6.0.1)
        - Locking sebastian/exporter (5.1.1)
        - Locking sebastian/global-state (6.0.1)
        - Locking sebastian/lines-of-code (2.0.1)
        - Locking sebastian/object-enumerator (5.0.0)
        - Locking sebastian/object-reflector (3.0.0)
        - Locking sebastian/recursion-context (5.0.0)
        - Locking sebastian/type (4.0.0)
        - Locking sebastian/version (4.0.1)
        - Locking spatie/backtrace (1.5.3)
        - Locking spatie/flare-client-php (1.4.3)
        - Locking spatie/ignition (1.11.3)
        - Locking spatie/laravel-ignition (2.3.1)
        - Locking symfony/console (v6.4.1)
        - Locking symfony/css-selector (v6.4.0)
        - Locking symfony/deprecation-contracts (v3.4.0)
        - Locking symfony/error-handler (v6.4.0)
        - Locking symfony/event-dispatcher (v7.0.0)
        - Locking symfony/event-dispatcher-contracts (v3.4.0)
        - Locking symfony/finder (v6.4.0)
        - Locking symfony/http-foundation (v6.4.0)
        - Locking symfony/http-kernel (v6.4.1)
        - Locking symfony/mailer (v6.4.0)
        - Locking symfony/mime (v6.4.0)
        - Locking symfony/polyfill-ctype (v1.28.0)
        - Locking symfony/polyfill-intl-grapheme (v1.28.0)
        - Locking symfony/polyfill-intl-idn (v1.28.0)
        - Locking symfony/polyfill-intl-normalizer (v1.28.0)
        - Locking symfony/polyfill-mbstring (v1.28.0)
        - Locking symfony/polyfill-php72 (v1.28.0)
        - Locking symfony/polyfill-php80 (v1.28.0)
        - Locking symfony/polyfill-php83 (v1.28.0)
        - Locking symfony/polyfill-uuid (v1.28.0)
        - Locking symfony/process (v6.4.0)
        - Locking symfony/routing (v6.4.1)
        - Locking symfony/service-contracts (v3.4.0)
        - Locking symfony/string (v7.0.0)
        - Locking symfony/translation (v6.4.0)
        - Locking symfony/translation-contracts (v3.4.0)
        - Locking symfony/uid (v6.4.0)
        - Locking symfony/var-dumper (v6.4.0)
        - Locking symfony/yaml (v7.0.0)
        - Locking theseer/tokenizer (1.2.2)
        - Locking tijsverkoyen/css-to-inline-styles (2.2.6)
        - Locking vlucas/phpdotenv (v5.6.0)
        - Locking voku/portable-ascii (2.0.1)
        - Locking webmozart/assert (1.11.0)
      Writing lock file
      Installing dependencies from lock file (including require-dev)
      Package operations: 111 installs, 0 updates, 0 removals
        - Downloading doctrine/inflector (2.0.8)
        - Downloading doctrine/lexer (3.0.0)
        - Downloading symfony/polyfill-ctype (v1.28.0)
        - Downloading webmozart/assert (1.11.0)
        - Downloading dragonmantank/cron-expression (v3.3.3)
        - Downloading symfony/deprecation-contracts (v3.4.0)
        - Downloading psr/container (2.0.2)
        - Downloading fakerphp/faker (v1.23.0)
        - Downloading symfony/polyfill-php80 (v1.28.0)
        - Downloading symfony/polyfill-php83 (v1.28.0)
        - Downloading symfony/polyfill-mbstring (v1.28.0)
        - Downloading symfony/http-foundation (v6.4.0)
        - Downloading fruitcake/php-cors (v1.3.0)
        - Downloading psr/http-message (2.0)
        - Downloading psr/http-client (1.0.3)
        - Downloading ralouphie/getallheaders (3.0.3)
        - Downloading psr/http-factory (1.0.2)
        - Downloading guzzlehttp/psr7 (2.6.1)
        - Downloading guzzlehttp/promises (2.0.1)
        - Downloading guzzlehttp/guzzle (7.8.0)
        - Downloading guzzlehttp/uri-template (v1.0.2)
        - Downloading laravel/pint (v1.13.6)
        - Downloading symfony/polyfill-intl-normalizer (v1.28.0)
        - Downloading symfony/polyfill-intl-grapheme (v1.28.0)
        - Downloading symfony/string (v7.0.0)
        - Downloading symfony/service-contracts (v3.4.0)
        - Downloading symfony/console (v6.4.1)
        - Downloading voku/portable-ascii (2.0.1)
        - Downloading phpoption/phpoption (1.9.2)
        - Downloading graham-campbell/result-type (v1.1.2)
        - Downloading vlucas/phpdotenv (v5.6.0)
        - Downloading symfony/css-selector (v6.4.0)
        - Downloading tijsverkoyen/css-to-inline-styles (2.2.6)
        - Downloading symfony/var-dumper (v6.4.0)
        - Downloading symfony/polyfill-uuid (v1.28.0)
        - Downloading symfony/uid (v6.4.0)
        - Downloading symfony/routing (v6.4.1)
        - Downloading symfony/process (v6.4.0)
        - Downloading symfony/polyfill-php72 (v1.28.0)
        - Downloading symfony/polyfill-intl-idn (v1.28.0)
        - Downloading symfony/mime (v6.4.0)
        - Downloading psr/event-dispatcher (1.0.0)
        - Downloading symfony/event-dispatcher-contracts (v3.4.0)
        - Downloading symfony/event-dispatcher (v7.0.0)
        - Downloading psr/log (3.0.0)
        - Downloading egulias/email-validator (4.0.2)
        - Downloading symfony/mailer (v6.4.0)
        - Downloading symfony/error-handler (v6.4.0)
        - Downloading symfony/http-kernel (v6.4.1)
        - Downloading symfony/finder (v6.4.0)
        - Downloading ramsey/collection (2.0.0)
        - Downloading brick/math (0.11.0)
        - Downloading ramsey/uuid (4.7.5)
        - Downloading psr/simple-cache (3.0.0)
        - Downloading nunomaduro/termwind (v1.15.1)
        - Downloading symfony/translation-contracts (v3.4.0)
        - Downloading symfony/translation (v6.4.0)
        - Downloading psr/clock (1.0.0)
        - Downloading carbonphp/carbon-doctrine-types (3.0.0)
        - Downloading nesbot/carbon (2.72.0)
        - Downloading monolog/monolog (3.5.0)
        - Downloading league/mime-type-detection (1.14.0)
        - Downloading league/flysystem (3.21.0)
        - Downloading league/flysystem-local (3.21.0)
        - Downloading nette/utils (v4.0.3)
        - Downloading nette/schema (v1.2.5)
        - Downloading dflydev/dot-access-data (v3.0.2)
        - Downloading league/config (v1.2.0)
        - Downloading league/commonmark (2.4.1)
        - Downloading laravel/serializable-closure (v1.3.3)
        - Downloading laravel/prompts (v0.1.13)
        - Downloading laravel/framework (v10.34.2)
        - Downloading symfony/yaml (v7.0.0)
        - Downloading laravel/sail (v1.26.2)
        - Downloading laravel/sanctum (v3.3.2)
        - Downloading nikic/php-parser (v4.17.1)
        - Downloading psy/psysh (v0.11.22)
        - Downloading laravel/tinker (v2.8.2)
        - Downloading hamcrest/hamcrest-php (v2.0.1)
        - Downloading mockery/mockery (1.6.6)
        - Downloading filp/whoops (2.15.4)
        - Downloading nunomaduro/collision (v7.10.0)
        - Downloading sebastian/version (4.0.1)
        - Downloading sebastian/type (4.0.0)
        - Downloading sebastian/recursion-context (5.0.0)
        - Downloading sebastian/object-reflector (3.0.0)
        - Downloading sebastian/object-enumerator (5.0.0)
        - Downloading sebastian/global-state (6.0.1)
        - Downloading sebastian/exporter (5.1.1)
        - Downloading sebastian/environment (6.0.1)
        - Downloading sebastian/diff (5.0.3)
        - Downloading sebastian/comparator (5.0.1)
        - Downloading sebastian/code-unit (2.0.0)
        - Downloading sebastian/cli-parser (2.0.0)
        - Downloading phpunit/php-timer (6.0.0)
        - Downloading phpunit/php-text-template (3.0.1)
        - Downloading phpunit/php-invoker (4.0.0)
        - Downloading phpunit/php-file-iterator (4.1.0)
        - Downloading theseer/tokenizer (1.2.2)
        - Downloading sebastian/lines-of-code (2.0.1)
        - Downloading sebastian/complexity (3.1.0)
        - Downloading sebastian/code-unit-reverse-lookup (3.0.0)
        - Downloading phpunit/php-code-coverage (10.1.9)
        - Downloading phar-io/version (3.2.1)
        - Downloading phar-io/manifest (2.0.3)
        - Downloading myclabs/deep-copy (1.11.1)
        - Downloading phpunit/phpunit (10.5.1)
        - Downloading spatie/backtrace (1.5.3)
        - Downloading spatie/flare-client-php (1.4.3)
        - Downloading spatie/ignition (1.11.3)
        - Downloading spatie/laravel-ignition (2.3.1)
        - Installing doctrine/inflector (2.0.8): Extracting archive
        - Installing doctrine/lexer (3.0.0): Extracting archive
        - Installing symfony/polyfill-ctype (v1.28.0): Extracting archive
        - Installing webmozart/assert (1.11.0): Extracting archive
        - Installing dragonmantank/cron-expression (v3.3.3): Extracting archive
        - Installing symfony/deprecation-contracts (v3.4.0): Extracting archive
        - Installing psr/container (2.0.2): Extracting archive
        - Installing fakerphp/faker (v1.23.0): Extracting archive
        - Installing symfony/polyfill-php80 (v1.28.0): Extracting archive
        - Installing symfony/polyfill-php83 (v1.28.0): Extracting archive
        - Installing symfony/polyfill-mbstring (v1.28.0): Extracting archive
        - Installing symfony/http-foundation (v6.4.0): Extracting archive
        - Installing fruitcake/php-cors (v1.3.0): Extracting archive
        - Installing psr/http-message (2.0): Extracting archive
        - Installing psr/http-client (1.0.3): Extracting archive
        - Installing ralouphie/getallheaders (3.0.3): Extracting archive
        - Installing psr/http-factory (1.0.2): Extracting archive
        - Installing guzzlehttp/psr7 (2.6.1): Extracting archive
        - Installing guzzlehttp/promises (2.0.1): Extracting archive
        - Installing guzzlehttp/guzzle (7.8.0): Extracting archive
        - Installing guzzlehttp/uri-template (v1.0.2): Extracting archive
        - Installing laravel/pint (v1.13.6): Extracting archive
        - Installing symfony/polyfill-intl-normalizer (v1.28.0): Extracting archive
        - Installing symfony/polyfill-intl-grapheme (v1.28.0): Extracting archive
        - Installing symfony/string (v7.0.0): Extracting archive
        - Installing symfony/service-contracts (v3.4.0): Extracting archive
        - Installing symfony/console (v6.4.1): Extracting archive
        - Installing voku/portable-ascii (2.0.1): Extracting archive
        - Installing phpoption/phpoption (1.9.2): Extracting archive
        - Installing graham-campbell/result-type (v1.1.2): Extracting archive
        - Installing vlucas/phpdotenv (v5.6.0): Extracting archive
        - Installing symfony/css-selector (v6.4.0): Extracting archive
        - Installing tijsverkoyen/css-to-inline-styles (2.2.6): Extracting archive
        - Installing symfony/var-dumper (v6.4.0): Extracting archive
        - Installing symfony/polyfill-uuid (v1.28.0): Extracting archive
        - Installing symfony/uid (v6.4.0): Extracting archive
        - Installing symfony/routing (v6.4.1): Extracting archive
        - Installing symfony/process (v6.4.0): Extracting archive
        - Installing symfony/polyfill-php72 (v1.28.0): Extracting archive
        - Installing symfony/polyfill-intl-idn (v1.28.0): Extracting archive
        - Installing symfony/mime (v6.4.0): Extracting archive
        - Installing psr/event-dispatcher (1.0.0): Extracting archive
        - Installing symfony/event-dispatcher-contracts (v3.4.0): Extracting archive
        - Installing symfony/event-dispatcher (v7.0.0): Extracting archive
        - Installing psr/log (3.0.0): Extracting archive
        - Installing egulias/email-validator (4.0.2): Extracting archive
        - Installing symfony/mailer (v6.4.0): Extracting archive
        - Installing symfony/error-handler (v6.4.0): Extracting archive
        - Installing symfony/http-kernel (v6.4.1): Extracting archive
        - Installing symfony/finder (v6.4.0): Extracting archive
        - Installing ramsey/collection (2.0.0): Extracting archive
        - Installing brick/math (0.11.0): Extracting archive
        - Installing ramsey/uuid (4.7.5): Extracting archive
        - Installing psr/simple-cache (3.0.0): Extracting archive
        - Installing nunomaduro/termwind (v1.15.1): Extracting archive
        - Installing symfony/translation-contracts (v3.4.0): Extracting archive
        - Installing symfony/translation (v6.4.0): Extracting archive
        - Installing psr/clock (1.0.0): Extracting archive
        - Installing carbonphp/carbon-doctrine-types (3.0.0): Extracting archive
        - Installing nesbot/carbon (2.72.0): Extracting archive
        - Installing monolog/monolog (3.5.0): Extracting archive
        - Installing league/mime-type-detection (1.14.0): Extracting archive
        - Installing league/flysystem (3.21.0): Extracting archive
        - Installing league/flysystem-local (3.21.0): Extracting archive
        - Installing nette/utils (v4.0.3): Extracting archive
        - Installing nette/schema (v1.2.5): Extracting archive
        - Installing dflydev/dot-access-data (v3.0.2): Extracting archive
        - Installing league/config (v1.2.0): Extracting archive
        - Installing league/commonmark (2.4.1): Extracting archive
        - Installing laravel/serializable-closure (v1.3.3): Extracting archive
        - Installing laravel/prompts (v0.1.13): Extracting archive
        - Installing laravel/framework (v10.34.2): Extracting archive
        - Installing symfony/yaml (v7.0.0): Extracting archive
        - Installing laravel/sail (v1.26.2): Extracting archive
        - Installing laravel/sanctum (v3.3.2): Extracting archive
        - Installing nikic/php-parser (v4.17.1): Extracting archive
        - Installing psy/psysh (v0.11.22): Extracting archive
        - Installing laravel/tinker (v2.8.2): Extracting archive
        - Installing hamcrest/hamcrest-php (v2.0.1): Extracting archive
        - Installing mockery/mockery (1.6.6): Extracting archive
        - Installing filp/whoops (2.15.4): Extracting archive
        - Installing nunomaduro/collision (v7.10.0): Extracting archive
        - Installing sebastian/version (4.0.1): Extracting archive
        - Installing sebastian/type (4.0.0): Extracting archive
        - Installing sebastian/recursion-context (5.0.0): Extracting archive
        - Installing sebastian/object-reflector (3.0.0): Extracting archive
        - Installing sebastian/object-enumerator (5.0.0): Extracting archive
        - Installing sebastian/global-state (6.0.1): Extracting archive
        - Installing sebastian/exporter (5.1.1): Extracting archive
        - Installing sebastian/environment (6.0.1): Extracting archive
        - Installing sebastian/diff (5.0.3): Extracting archive
        - Installing sebastian/comparator (5.0.1): Extracting archive
        - Installing sebastian/code-unit (2.0.0): Extracting archive
        - Installing sebastian/cli-parser (2.0.0): Extracting archive
        - Installing phpunit/php-timer (6.0.0): Extracting archive
        - Installing phpunit/php-text-template (3.0.1): Extracting archive
        - Installing phpunit/php-invoker (4.0.0): Extracting archive
        - Installing phpunit/php-file-iterator (4.1.0): Extracting archive
        - Installing theseer/tokenizer (1.2.2): Extracting archive
        - Installing sebastian/lines-of-code (2.0.1): Extracting archive
        - Installing sebastian/complexity (3.1.0): Extracting archive
        - Installing sebastian/code-unit-reverse-lookup (3.0.0): Extracting archive
        - Installing phpunit/php-code-coverage (10.1.9): Extracting archive
        - Installing phar-io/version (3.2.1): Extracting archive
        - Installing phar-io/manifest (2.0.3): Extracting archive
        - Installing myclabs/deep-copy (1.11.1): Extracting archive
        - Installing phpunit/phpunit (10.5.1): Extracting archive
        - Installing spatie/backtrace (1.5.3): Extracting archive
        - Installing spatie/flare-client-php (1.4.3): Extracting archive
        - Installing spatie/ignition (1.11.3): Extracting archive
        - Installing spatie/laravel-ignition (2.3.1): Extracting archive
      52 package suggestions were added by new dependencies, use `composer suggest` to see details.
      Generating optimized autoload files
      > Illuminate\Foundation\ComposerScripts::postAutoloadDump
      > @php artisan package:discover --ansi
    
         INFO  Discovering packages.
    
        laravel/sail ..................................................................... DONE
        laravel/sanctum .................................................................. DONE
        laravel/tinker ................................................................... DONE
        nesbot/carbon .................................................................... DONE
        nunomaduro/collision ............................................................. DONE
        nunomaduro/termwind .............................................................. DONE
        spatie/laravel-ignition .......................................................... DONE
    
      83 packages you are using are looking for funding.
      Use the `composer fund` command to find out more!
      > @php artisan vendor:publish --tag=laravel-assets --ansi --force
    
         INFO  No publishable resources for tag [laravel-assets].
    
      No security vulnerability advisories found.
      > @php artisan key:generate --ansi
    
         INFO  Application key set successfully.
    
      docker compose exec app php artisan key:generate
    
         INFO  Application key set successfully.
    
      docker compose exec app php artisan storage:link
    
         INFO  The [public/storage] link has been connected to [storage/app/public].
    
      docker compose exec app chmod -R 777 storage bootstrap/cache
      docker compose exec app php artisan migrate:fresh --seed
    
        Dropping all tables ........................................................ 232ms DONE
    
         INFO  Preparing database.
    
        Creating migration table .................................................... 88ms DONE
    
         INFO  Running migrations.
    
        2014_10_12_000000_create_users_table ....................................... 113ms DONE
        2014_10_12_100000_create_password_reset_tokens_table ....................... 106ms DONE
        2019_08_19_000000_create_failed_jobs_table .................................. 87ms DONE
        2019_12_14_000001_create_personal_access_tokens_table ...................... 115ms DONE
    
         INFO  Seeding database.
    

create-project で実行されるのは、以下の内容です。

# srcディレクトリを作成
$ mkdir -p src

# イメージをビルド
$ docker compose build

# コンテナをバックグラウンドで起動
$ docker compose up -d

# appサービスのコンテナ内でComposerコマンドを実行し、Laravelプロジェクトを現在のディレクトリに作成
$ docker compose exec app composer create-project --prefer-dist laravel/laravel .

# アプリケーションの暗号化キーを生成
$ docker compose exec app php artisan key:generate

# public/storageからstorage/app/publicへのシンボリックリンクを作成
$ docker compose exec app php artisan storage:link

# 指定のstorageディレクトリ、bootstrap/cacheディレクトリに対して書き込み権限付与
$ docker compose exec app chmod -R 777 storage bootstrap/cache

# データベースのマイグレーションを実行
$ docker compose exec app php artisan migrate

Web ブラウザで http:// localhost にアクセスし、Laravel と書かれたページが表示されるか確認します。

app サービスのコンテナの Dockerfile を編集します。追加した内容の確認のために、ステップを踏んで追加します。

2. Node.js のバージョンを指定してインストール

デフォルトの状態では以下のとおり、Node.js は導入されていないため、インストールします。

# r_yamate @ mbp in ~/development/sample-app on git:main x [9:38:20]
$ make app
docker compose exec app bash

root@87b34a2bdd9a:/workspace# node --version
bash: node: command not found

root@87b34a2bdd9a:/workspace# npm --version
bash: npm: command not found

root@87b34a2bdd9a:/workspace# npx --version
bash: npx: command not found

構築した Laravel の開発環境に node, npm, npx がインストールされるように app サービスのコンテナの Dockerfile を編集します。

  • 編集:infra/docker/php/Dockerfile
FROM php:8.3-fpm-bullseye AS base

WORKDIR /workspace

# timezone environment
ENV TZ=UTC \
  # locale
  LANG=en_US.UTF-8 \
  LANGUAGE=en_US:en \
  LC_ALL=en_US.UTF-8 \
  # composer environment
  COMPOSER_ALLOW_SUPERUSER=1 \
  COMPOSER_HOME=/composer

COPY --from=composer:2.6 /usr/bin/composer /usr/bin/composer

# 必要なパッケージのインストールと設定
RUN apt-get update \
  && apt-get -y install --no-install-recommends \
  locales \
  git \
  unzip \
  libzip-dev \
  libicu-dev \
  libonig-dev \
  && locale-gen en_US.UTF-8 \
  && localedef -f UTF-8 -i en_US en_US.UTF-8 \
  && docker-php-ext-install \
  intl \
  pdo_mysql \
  zip \
  bcmath \
  && composer config -g process-timeout 3600 \
  && composer config -g repos.packagist composer https://packagist.org

# === ここから追加 ===
# Node.jsのバージョンを指定してインストール
ARG NODE_VERSION=20.x
RUN curl -sL https://deb.nodesource.com/setup_$NODE_VERSION | bash - \
  && apt-get update \
  && apt-get install -y nodejs \
  && apt-get clean \
  && npm install -g npm@10.2.4
# === ここまで追加 ===

# 開発用設定
FROM base AS development

RUN apt-get -y install --no-install-recommends \
  default-mysql-client \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

COPY ./infra/docker/php/php.development.ini /usr/local/etc/php/php.ini

# Xdebug設定
FROM development AS development-xdebug

RUN pecl install xdebug && \
  docker-php-ext-enable xdebug

COPY ./infra/docker/php/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini

# デプロイ用設定
FROM base AS deploy

COPY ./infra/docker/php/php.deploy.ini /usr/local/etc/php/php.ini
COPY ./src /workspace

RUN composer install -q -n --no-ansi --no-dev --no-scripts --no-progress --prefer-dist \
  && chmod -R 777 storage bootstrap/cache \
  && php artisan optimize:clear \
  && php artisan optimize \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

Docker イメージ内に Node.js をセットアップし、npm を指定のバージョンにアップグレードしています。

環境を再構築します。

make remake
  • コマンド実行時ログ

      # r_yamate @ mbp in ~/development/sample-app on git:main x [9:56:36] C:2
      $ make remake
      docker compose down --rmi all --volumes --remove-orphans
      [+] Running 4/4
       ⠿ Image sample-app-db:latest     Removed                                             0.3s
       ⠿ Image sample-app-web:latest    Removed                                             0.3s
       ⠿ Volume sample-app_db-store     Removed                                             0.0s
       ⠿ Volume sample-app_psysh-store  Removed                                             0.0s
      docker compose build
      [+] Building 0.0s (0/0)
      [+] Building 0.0s (0/0)
      [+] Building 0.3s (1/1)
       => [internal] load build definition from Dockerfile                                  0.0s
      [+] Building 0.0s (1/1)
       => [internal] load build definition from Dockerfile                                  0.0s
      [+] Building 0.5s (6/6) FINISHED
       => [internal] load build definition from Dockerfile                                  0.0s
       => => transferring dockerfile: 31B                                                   0.0s
       => [internal] load .dockerignore                                                     0.0s
       => => transferring context: 35B                                                      0.0s
       => [internal] load metadata for docker.io/mysql/mysql-server:8.0                     0.0s
       => [1/2] FROM docker.io/mysql/mysql-server:8.0                                       0.0s
       => CACHED [2/2] RUN mkdir /var/log/mysql   && chown mysql:mysql $_   && chmod 777 $  0.0s
       => exporting to image                                                                0.0s
      [+] Building 0.3s (2/3)
       => => transferring context: 35B                                                      0.0s
       => [internal] load metadata for docker.io/library/php:8.3-fpm-bullseye               0.9s
      [+] Building 3.0s (8/8) FINISHED
       => [internal] load build definition from Dockerfile                                  0.0s
       => => transferring dockerfile: 31B                                                   0.0s
       => [internal] load .dockerignore                                                     0.0s
       => => transferring context: 35B                                                      0.0s
       => [internal] load metadata for docker.io/library/nginx:1.25                         2.6s
       => [internal] load build context                                                     0.0s
       => => transferring context: 953B                                                     0.0s
       => [1/3] FROM docker.io/library/nginx:1.25@sha256:10d1f5b58f74683ad34eb29287e07dab1  0.0s
      [+] Building 98.5s (13/13) FINISHED
       => [internal] load build definition from Dockerfile                                  0.0s
       => => transferring dockerfile: 1.83kB                                                0.0s
       => [internal] load .dockerignore                                                     0.0s
       => => transferring context: 35B                                                      0.0s
       => [internal] load metadata for docker.io/library/php:8.3-fpm-bullseye               2.6s
       => [base 1/5] FROM docker.io/library/php:8.3-fpm-bullseye@sha256:2d5f4befa910705945  0.0s
       => [internal] load build context                                                     0.1s
       => => transferring context: 613B                                                     0.0s
       => FROM docker.io/library/composer:2.6                                               1.5s
       => => resolve docker.io/library/composer:2.6                                         1.5s
       => CACHED [base 2/5] WORKDIR /workspace                                              0.0s
       => CACHED [base 3/5] COPY --from=composer:2.6 /usr/bin/composer /usr/bin/composer    0.0s
       => CACHED [base 4/5] RUN apt-get update   && apt-get -y install --no-install-recomm  0.0s
       => [base 5/5] RUN curl -sL https://deb.nodesource.com/setup_20.x | bash -   && apt  87.5s
       => [development 1/2] RUN apt-get -y install --no-install-recommends   default-mysql  4.2s
       => [development 2/2] COPY ./infra/docker/php/php.development.ini /usr/local/etc/php  0.1s
       => exporting to image                                                                2.4s
       => => exporting layers                                                               2.3s
       => => writing image sha256:5443fca82f3999e8d839ab763661ef37983bb62a1032fb36eed64bd5  0.0s
       => => naming to docker.io/library/sample-app-app                                     0.0s
      docker compose up -d
      [+] Running 4/4
       ⠿ mailpit Pulled                                                                     5.2s
         ⠿ c926b61bad3b Already exists                                                      0.0s
         ⠿ 06402ac516d6 Pull complete                                                       1.4s
         ⠿ b077324cb2fc Pull complete                                                       1.6s
      [+] Running 7/7
       ⠿ Network sample-app_default       Created                                           0.1s
       ⠿ Volume "sample-app_psysh-store"  Created                                           0.0s
       ⠿ Volume "sample-app_db-store"     Created                                           0.0s
       ⠿ Container sample-app-web-1       Started                                           4.0s
       ⠿ Container sample-app-db-1        Started                                           4.0s
       ⠿ Container sample-app-mailpit-1   Started                                           1.4s
       ⠿ Container sample-app-app-1       Started                                           3.7s
      docker compose exec app composer install
      Installing dependencies from lock file (including require-dev)
      Verifying lock file contents can be installed on current platform.
      Nothing to install, update or remove
      Generating optimized autoload files
      > Illuminate\Foundation\ComposerScripts::postAutoloadDump
      > @php artisan package:discover --ansi
    
         INFO  Discovering packages.
    
        laravel/sail ..................................................................... DONE
        laravel/sanctum .................................................................. DONE
        laravel/tinker ................................................................... DONE
        nesbot/carbon .................................................................... DONE
        nunomaduro/collision ............................................................. DONE
        nunomaduro/termwind .............................................................. DONE
        spatie/laravel-ignition .......................................................... DONE
    
      83 packages you are using are looking for funding.
      Use the `composer fund` command to find out more!
      docker compose exec app cp .env.example .env
      docker compose exec app php artisan key:generate
    
         INFO  Application key set successfully.
    
      docker compose exec app php artisan storage:link
    
         ERROR  The [public/storage] link already exists.
    
      docker compose exec app chmod -R 777 storage bootstrap/cache
      docker compose exec app php artisan migrate:fresh --seed
    
        Dropping all tables ...................................................... 1,521ms DONE
    
         INFO  Preparing database.
    
        Creating migration table ................................................... 306ms DONE
    
         INFO  Running migrations.
    
        2014_10_12_000000_create_users_table ..................................... 1,343ms DONE
        2014_10_12_100000_create_password_reset_tokens_table ....................... 422ms DONE
        2019_08_19_000000_create_failed_jobs_table ................................. 296ms DONE
        2019_12_14_000001_create_personal_access_tokens_table ...................... 502ms DONE
    
         INFO  Seeding database.
    

以下のとおり、指定したバージョンの Node.js をインストールできていることが確認できました。

# r_yamate @ mbp in ~/development/sample-app on git:main x [10:07:57]
$ make app
docker compose exec app bash

root@37aa25accac5:/workspace# node --version
v20.5.1

root@37aa25accac5:/workspace# npm --version
10.2.4

root@37aa25accac5:/workspace# npx --version
10.2.4

3. React の開発環境構築

React の開発環境を Laravel の開発環境内に構築します。TypeScript, Sass も追加します。

npm install -D react react-dom @types/react @types/react-dom
npm install -D @vitejs/plugin-react
npm install -D react-router-dom
npm install -D @types/react-router-dom

npm install -D typescript
npx tsc --init --jsx react-jsx

npm install -D sass
  • コマンド実行時ログ

      root@5f8dbf46957f:/workspace# npm install -D react react-dom @types/react @types/react-dom
      npm install -D @vitejs/plugin-react
      npm install -D react-router-dom
      npm install -D @types/react-router-dom
    
      npm install -D typescript
      npx tsc --init --jsx react-jsx
    
      npm install -D sass
    
      up to date, audited 46 packages in 995ms
    
      6 packages are looking for funding
        run `npm fund` for details
    
      found 0 vulnerabilities
    
      added 60 packages, and audited 106 packages in 25s
    
      10 packages are looking for funding
        run `npm fund` for details
    
      found 0 vulnerabilities
    
      added 3 packages, and audited 109 packages in 5s
    
      10 packages are looking for funding
        run `npm fund` for details
    
      found 0 vulnerabilities
    
      added 3 packages, and audited 112 packages in 6s
    
      10 packages are looking for funding
        run `npm fund` for details
    
      found 0 vulnerabilities
    
      added 1 package, and audited 113 packages in 17s
    
      10 packages are looking for funding
        run `npm fund` for details
    
      found 0 vulnerabilities
    
      Created a new tsconfig.json with:
                                                                                              TS
        target: es2016
        module: commonjs
        jsx: react-jsx
        strict: true
        esModuleInterop: true
        skipLibCheck: true
        forceConsistentCasingInFileNames: true
    
      You can learn more at https://aka.ms/tsconfig
    
      up to date, audited 113 packages in 1s
    
      10 packages are looking for funding
        run `npm fund` for details
    
      found 0 vulnerabilities
    

package.json を確認してみます。

  • 確認:src/package.json
{
    "private": true,
    "type": "module",
    "scripts": {
        "dev": "vite",
        "build": "vite build"
    },
    "devDependencies": {
        "@types/react": "^18.2.41",
        "@types/react-dom": "^18.2.17",
        "@types/react-router-dom": "^5.3.3",
        "@vitejs/plugin-react": "^4.2.0",
        "axios": "^1.6.1",
        "laravel-vite-plugin": "^0.8.0",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "react-router-dom": "^6.20.1",
        "sass": "^1.69.5",
        "typescript": "^5.3.2",
        "vite": "^4.0.0"
    }
}

先ほど Docker コンテナでインストールしたパッケージが追加されています。

導入ができているかの検証は、前回の記事同様であるため省略させていただきます。

ryamate.hatenablog.com

おわりに

今回は Laravel 10 と React 18 の SPA の開発環境を、ucan-lab/docker-laravel を用いて構築しました。

ありがとうございました。



社内の方々のエンジニアキャリアがとても気になる今日この頃です。