13
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

久々にLaravelを触ったら、コンテナやフロントエンド開発が簡単になっていた

Posted at

最近、ちょっと時間ができたのでキャッチアップのために Laravel8を触ってみました。
知識がLaravel5前後で止まっていたので、進化したエコシステムに驚いたので書き記しておきます。
ちなみに、次のLTSはLaravel9(2022/1/25リリース予定)になるので、この手の機能をプロダクションで使うときは、しかるべき時にアップデートをしましょう。

コンテナを使っての開発環境構築が楽になってる!(Laravel Sail)

ちょっと前まではコンテナでLaravelを動かす時には自分で適当なDockerFileを書くか、Laradoc使って構築するケースが多かったと思います。
Laradockは大きくなりすぎて余計な機能もあったりしたので、私は自前でDockerFileを書く派でした。これだけでも、ちょっと「面倒くさいな。。。」なんて思っていました。
ここでLaravel Sailの登場です。
Sailを使っての環境構築は、

$ curl -s "https://laravel.build/[ディレクトリ名]" | bash
$ cd [ディレクトリ名]
# バックグラウンドで動かすなら、-dを付ければ OK
# 下記の様にaliasを設定しておくとsailコマンドを使うのが簡単になる
# alias sail='bash vendor/bin/sail'
$ ./vendor/bin/sail up

たったこれだけで、PHP + MySql + mailhog + redis + selenium を使ったプロジェクトが立ち上がります。
seleniumはブラウザテストの時なんかに便利ですね。

# 立ち上げたときの表示
$ sail up -d
lara-sample_laravel.test_1   start-container                  Exit 255   0.0.0.0:80->80/tcp,:::80->80/tcp, 8000/tcp                                        
Shutting down old Sail processes...
Creating network "lara-sample_sail" with driver "bridge"
Creating lara-sample_mysql_1       ... done
Creating lara-sample_selenium_1    ... done
Creating lara-sample_mailhog_1      ... done
Creating lara-sample_meilisearch_1 ... done
Creating lara-sample_redis_1       ... done
Creating lara-sample_laravel.test_1 ... done

ちなみに、

sail artisan sail:publish

でDockerFileなどが編集できる様になるので、独自のPHP拡張などを入れるのも簡単ですね:tada:

React(Vueも)+認証の構築が楽になってる!(Laravel Breeze)

とりあえず、Sailを使ってプロジェクトが動かせる様になったら認証を作って行きます。
元々はlaravel/uiがあったのですが、こちらか Jetstreamを使っていく方針の様です。
細かな認証の組み込みが不要な場合や初学者にはBreezeがお薦めですね。

認証をReactやVueで作っていくためには、

php artisan breeze:install vue
# Vueの場合はこちら
php artisan breeze:install react

npm install
npm run dev
php artisan migrate

で導入が可能です。ただ、初期インストール時に作成されるのはJavaScriptになるのでTypeScriptを使う時には下記の修正が必要です。

  • webpack.mix.jsの修正
  • tsconfig.jsonの作成
  • resources/js配下のTypeScript化

下記の様にオプションをつけられる様になったら、もっと楽になると思っています。

# こちらはできません!
php artisan breeze:install react --typescript

ただ、非公式ですがBreeze + React + TypeScriptGitHubリポジトリがあるので問題なく対処できるのではないでしょうか。

inertia.jsの衝撃(modern monolithとの出会い)

Breezeを使ったReactの導入にはinertia.jsが使われています。

Build single-page apps, without building an API.(SPAをAPIを使うことなく構築できる)

ということで、Reactを使ったSPAのルーティング、サーバサイドとのデータの受け渡しなどをbladeと同じ様な感覚で行うことができる様になっています。
おなじみのroutes/web.phpのルーティング情報を使えるのので、メンテナンスを行う上で非常に楽になると思います。
(下記は会員登録画面のサンプル。post(route('register'));が、そこに該当します。LaravelからはProps経由で値を受け取れています。)

import Button from '@/Components/Button';
import Guest from '@/Layouts/Guest';
import Input from '@/Components/Input';
import Label from '@/Components/Label';
import React, { useEffect } from 'react';
import ValidationErrors from '@/Components/ValidationErrors';
import { InertiaLink } from '@inertiajs/inertia-react';
import { useForm } from '@inertiajs/inertia-react';
import route from 'ziggy-js';

type Props = {
    element1: string
}

export default function Register({ element1 }: Props) {
    const { data, setData, post, processing, errors, reset } = useForm({
        name: '',
        email: '',
        password: '',
        password_confirmation: '',
    });

    useEffect(() => {
        return () => {
            reset('password', 'password_confirmation');
        };
    }, []);

    const onHandleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        setData(event.target.name as "name" | "email" | "password" | "password_confirmation", event.target.type === 'checkbox' ? event.target.checked + '' : event.target.value);
    };

    const submit = (e: React.SyntheticEvent) => {
        e.preventDefault();

        post(route('register'));
    };


    return (
        <Guest>
            <ValidationErrors errors={errors} />
            <form onSubmit={submit}>
                <div>
                    <Label forInput="name" value="Name" />
                    {element1}
                    <Input
                        type="text"
                        name="name"
                        value={data.name}
                        className="mt-1 block w-full"
                        autoComplete="name"
                        isFocused={true}
                        handleChange={onHandleChange}
                        required
                    />

                </div>

                <div className="mt-4">
                    <Label forInput="email" value="Email" />

                    <Input
                        type="email"
                        name="email"
                        value={data.email}
                        className="mt-1 block w-full"
                        autoComplete="username"
                        handleChange={onHandleChange}
                        required
                    />
                </div>

                <div className="mt-4">
                    <Label forInput="password" value="Password" />

                    <Input
                        type="password"
                        name="password"
                        value={data.password}
                        className="mt-1 block w-full"
                        autoComplete="new-password"
                        handleChange={onHandleChange}
                        required
                    />
                </div>

                <div className="mt-4">
                    <Label forInput="password_confirmation" value="Confirm Password" />

                    <Input
                        type="password"
                        name="password_confirmation"
                        value={data.password_confirmation}
                        className="mt-1 block w-full"
                        handleChange={onHandleChange}
                        required
                    />
                </div>

                <div className="flex items-center justify-end mt-4">
                    <InertiaLink href={route('login')} className="underline text-sm text-gray-600 hover:text-gray-900">
                        Already registered?
                    </InertiaLink>

                    <Button className="ml-4" processing={processing}>
                        Register
                    </Button>
                </div>
            </form>
        </Guest>
    );
}

フロントエンドとサーバサイドを分業せずに開発しているプロダクトなどでは非常に有用に思います。

他にもリリースノートを見ると

  • Models Directoryの導入(結局作るんかい!と思いましたが:sweat_smile:)
  • Migration Squashing(マイグレーションを圧縮してディレクトリの肥大化を防ぐ)

などなど、面白そうな機能がたくさんありました!
わずか1年強、キャッチアップから離れていただけなのですが進化の速さに驚かされます。
勉強は続けないといけないですね。

13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?