Docker+Laravel+React+TypeScript構成のフルスタックパッケージを順を追って構築する【後編:フロントエンド】
Webアプリ開発に慣れない人にとって環境構築は大きなハードルです。 この記事ではサーバーサイドはDockerとLaravel、フロントエンドではReactとTypeScriptを使ったフルスタックパッケージを、ひとつづつ手順を確認しながら構築していきます。 後編ではフロントエンドのReact+TypeScriptの構築を行います。
前編終了時点でのコード
前編の記事は以下からリンクできます。
Docker+Laravel+React+TypeScript構成のフルスタックパッケージを順を追って構築する【前編:サーバーサイド】
また、前編終了時のコードはGitHubで確認できます。
1// 前編での最終形
2fullstack-project/
3 ├ src/
4 | └ (Laravelのコード)
5 ├ docker/
6 │ ├ nginx/
7 │ │ ├ Dockerfile
8 │ │ └ default.conf
9 │ ├ php/
10 │ │ ├ Dockerfile
11 │ │ └ php.ini
12 │ └ mysql/
13 │ ├ Dockerfile
14 │ └ my.conf
15 └ docker-compose.yml
3. React環境構築
Laravelを使う場合、ReactやVueなどのフロントエンド開発を手軽に始めるためのパッケージが用意されています。
3-1. Node.jsとnpm
まずは、フロントエンド開発では必須のNode.jsとnpmをDockerコンテナに導入します。phpのDockerfileに記載します。
1FROM php:8.1-fpm-alpine
2
3# install composer
4RUN curl -sS https://getcomposer.org/installer | php
5RUN mv composer.phar /usr/local/bin/composer
6
7# install packages
8RUN apk update
9RUN apk add git nodejs npm
10
11# install php extensions
12RUN docker-php-ext-install pdo pdo_mysql
apk install
コマンドの値にnodejsとnpmを追加します。Dockerfileを編集したのでdocker-compose build
コマンドでビルドします。
docker-compose build app
1docker-compose exec app node -v
2v16.15.0
3
4docker-compose exec app npm -v
58.10.0
node -v
コマンドおよびnpm -v
コマンドでインストールされていることが確認できたら成功です。
3-2. MixとUI
Laravel MixはLaravelにデフォルトでインストールされているパッケージで、 モジュールバンドラーのWebpackをラップするパッケージです。 Webpackの設定ファイルであるwebpack.config.jsは構造が複雑になりがちで苦労するのですが、 そのような設定作業に悩まされることなくフロントエンド開発を始めることができます。
Laravel MixはLaravelプロジェクトにあらかじめ導入されているのでインストールは不要です。
Laravel UI
Laravel UIはフロントエンドのスキャフォールディング(雛形作成)機能で、 ReactやVue、BootStrapの雛形をコマンド1つで作成してくれます。
docker-compose exec app composer require laravel/ui
Laravelには7.xまでLaravel UIに関するドキュメントがありますが、8.x以降は無くなっています。
JavaScript & CSS Scaffolding (7.x)
以下のコマンドを実行することでReactの雛形が作成されます。
docker-compose exec app php artisan ui react
コマンドを実行後、Laravelプロジェクトのあるsrc/resources配下にファイルがいくつか追加されます。
1// php artisan uiコマンド実行後
2fullstack-project/
3 ├ src/
4 | └ resources/
5 | ├ js/
6 | | ├ components/
7 | | | └ Example.js
8 | | ├ app.js
9 | | └ bootstrap.js
10 | └ sass/
11 | ├ _variables.scss
12 | └ app.scss
13 ├ docker/
14 └ docker-compose.yml
app.jsを確認すると、Example.jsコンポーネントを要求していることがわかります。
1import React from 'react';
2import ReactDOM from 'react-dom';
3
4function Example() {
5 return (
6 <div className="container">
7 <div className="row justify-content-center">
8 <div className="col-md-8">
9 <div className="card">
10 <div className="card-header">Example Component</div>
11
12 <div className="card-body">I'm an example component!</div>
13 </div>
14 </div>
15 </div>
16 </div>
17 );
18}
19
20export default Example;
21
22if (document.getElementById('example')) {
23 ReactDOM.render(<Example />, document.getElementById('example'));
24}
jsを確認すると、Exampleコンポーネントの定義と、ExampleコンポーネントをidがexampleのDOM要素に対して描画していることがわかります。
JavaScriptビルド
npm run dev
コマンドでJavaScriptとCSSをビルドします。
1docker-compose exec app npm run dev
2
3...
4Additional dependencies must be installed. This will only take a moment.
5
6Running: npm install resolve-url-loader@^5.0.0 --save-dev --legacy-peer-deps
7
8Finished. Please run Mix again.
初回は、上記のようなメッセージが表示されます。
もう一度npm run dev
コマンドを実行します。
1docker-compose exec app npm run dev
2...
3Laravel Mix v6.0.49
4✔ Compiled Successfully in 8145ms
Larvelプロジェクトのsrc/public配下にビルドされたファイルが追加されます。
1// php artisan devコマンド実行後
2fullstack-project/
3 ├ public/
4 | ├ css/
5 | ├ └ app.css
6 | └ js/
7 | └ app.js
8 ├ src/
9 ├ docker/
10 └ docker-compose.yml
welcome.blade.php
src/views配下にあるwelcome.blade.phpを編集して、Reactコンポーネントを表示するように編集します。
1<!DOCTYPE html>
2<html lang="ja">
3<head>
4 <meta charset="UTF-8">
5 <title>Fullstack Project</title>
6 <link rel="stylesheet" href="{{ mix('/css/app.css') }}" />
7</head>
8<body>
9 <div id="example"></div>
10 <script src="{{ mix('/js/app.js') }}"></script>
11</body>
12</html>
link要素にビルドしたcssを、body要素の閉じタグ直前にビルドしたjsを、 そしてbody要素にはexampleをidに持つdiv要素を用意します。
mix
メソッドを利用するとLaravelがファイルパスを自動的に指定してくれます。
ブラウザで確認してみる
ブラウザでlocalhost:8000
にアクセスし、Exampleコンポーネントが確認できたら成功です。
4. TypeScript環境構築
Reactを用いる場合、同時にTypeScriptを導入することが多いです。 Laravel Mixをすでに導入している場合は、特に負担なくTypeScriptを利用することができます。
4-1. TypeScript
Exampleコンポーネントのファイル名をExample.tsx
に変更します。
1import React from 'react';
2import ReactDOM from 'react-dom';
3
4function Example(): React.ReactElement {
5 return (
6 <div className="container">
7 <div className="row justify-content-center">
8 <div className="col-md-8">
9 <div className="card">
10 <div className="card-header">Example Component</div>
11
12 <div className="card-body">I'm an example component!</div>
13 </div>
14 </div>
15 </div>
16 </div>
17 );
18}
19
20export default Example;
21
22if (document.getElementById('example')) {
23 ReactDOM.render(<Example />, document.getElementById('example'));
24}
webpack.mix.js
のmix.js
メソッドをmix.ts
に変更します。
TypeScriptによる型を使用できるようになります。
1const mix = require('laravel-mix');
2
3/*
4 |--------------------------------------------------------------------------
5 | Mix Asset Management
6 |--------------------------------------------------------------------------
7 |
8 | Mix provides a clean, fluent API for defining some Webpack build steps
9 | for your Laravel application. By default, we are compiling the Sass
10 | file for the application as well as bundling up all the JS files.
11 |
12 */
13
14mix.ts('resources/js/app.js', 'public/js')
15 .react()
16 .sass('resources/sass/app.scss', 'public/css');
npm run dev
コマンドでJavaScriptとCSSをビルドします。
初回はTypeScriptに関連するnpmパッケージがインストールされます。
1docker-compose exec app npm run dev
2
3...
4Additional dependencies must be installed. This will only take a moment.
5
6Running: npm install ts-loader typescript --save-dev --legacy-peer-deps
7
8Finished. Please run Mix again.
もう一度npm run dev
コマンドを実行します。
1docker-compose exec app npm run dev
2
3...
4ERROR in ./resources/js/components/Example.tsx
5[tsl] ERROR
6 TS18002: The 'files' list in config file 'tsconfig.json' is empty.
7
8ERROR in ./resources/js/components/Example.tsx
9Module build failed (from ./node_modules/ts-loader/index.js):
10Error: error while parsing tsconfig.json
11 at Object.loader (/var/www/html/node_modules/ts-loader/dist/index.js:17:18)
12
13webpack compiled with 2 errors and 1 warning
tsconfig.json
Laravel MixのTypescript Supportに記載のある通り、
tsconfig.json
と型パッケージ(@types/*)が必要なので用意します。
1{
2 "compilerOptions": {
3 "target": "ES2015",
4 "module": "commonjs",
5 "strict": true,
6 "esModuleInterop": true,
7 "skipLibCheck": true,
8 "forceConsistentCasingInFileNames": true
9 },
10 "$schema": "https://json.schemastore.org/tsconfig",
11 "display": "Recommended"
12}
さらにReactのJSXを対応できるようにし、さらにvendor配下の検証は除外します。
1{
2 "compilerOptions": {
3 "target": "ES2015",
4 "module": "commonjs",
5 "strict": true,
6 "esModuleInterop": true,
7 "skipLibCheck": true,
8 "forceConsistentCasingInFileNames": true,
9 "jsx": "react"
10 },
11 "exclude": [
12 "vendor"
13 ],
14 "$schema": "https://json.schemastore.org/tsconfig",
15 "display": "Recommended"
16}
@types/*
関連する型パッケージをインストールします。
docker-compose exec app npm install @types/node @types/react @types/react-dom
ビルドして確認する
1docker-compose exec app npm run dev
2
3...
4Laravel Mix v6.0.49
5
6✔ Compiled Successfully in 10969ms
TypeScriptでのビルドができるようになりました。
完成
Docker+Laravel+React+TypeScript構成の環境が完成しました。
必要に応じてPHP静的解析ツールのphpcsやphpmd、JSのESLintやJS Standardなどを導入してください。
最終的な構成
1// 最終的な構成(この記事で編集していないLaravelのファイルは省略)
2fullstack-project/
3 ├ docker/
4 │ ├ nginx/
5 │ │ ├ Dockerfile
6 │ │ └ default.conf
7 │ ├ php/
8 │ │ ├ Dockerfile
9 │ │ └ php.ini
10 │ └ mysql/
11 │ ├ Dockerfile
12 │ └ my.conf
13 ├ src/
14 ├ ├ public/
15 | | ├ css/
16 | | ├ └ app.css
17 | | └ js/
18 | | └ app.js
19 | ├ resources/
20 | | ├ js/
21 | | | ├ components/
22 | | | | └ Example.tsx
23 | | | ├ app.js
24 | | | └ bootstrap.js
25 | | └ sass/
26 | | ├ _variables.scss
27 | | └ app.scss
28 | ├ views/
29 | | └ welcome.blade.php
30 | ├ .env
31 | ├ tsconfig.json
32 | └ webpack.mix.js
33 └ docker-compose.yml