Laravelのパッケージ開発に必要な手順をまとめました。
なお、この記事ではローカルでの動作確認のみとしてpackagistへの登録等は行いません。
動作環境
- Laravel 8.12
- PHP 7.4.1
- Composer 2.0.4
どちらもローカルで動作させます
ざっくりとした仕様
ブラウザでhttp://localhost:8000/hello
にアクセスすると「Hello from SayHello Package!」と表示できるようになるパッケージの開発
大まかな流れ
- 必要なディレクトリを作成する
- composer.jsonを作成する
- パッケージ開発をする
- パッケージを利用したい側のcomposer.jsonにrepositoriesをキーに使用したいパッケージへのパスを記述する
- composer require [vendor]/[package_name]でパッケージをインストールする
ディレクトリ構成
laravelpackage.comによるとLaravelのプロジェクトとパッケージのディレクトリは分けた方がよい(highly recommend)らしいのですが、今回はごく簡単なパッケージなのでLaravelプロジェクトの中にpackages/というディレクトリを切ってその中で開発します。
pac-dev/ <- ライブラリを使用するLaravelアプリのルートディレクトリ
├ app/
├ packages/
│ └ nasteng/
│ └ say-hello/ <- 今回作成するパッケージ
│ ├ routes/
│ │ └ routes.php
│ ├ resources/
│ │ └ views/
│ │ └ hello.blade.php
│ ├ src/
│ │ ├ Http/
│ │ │ └ Controllers/
│ │ │ └ HelloController.php
│ │ └ HelloServiceProvider.php
│ └ composer.json
└ ・・・
それでは実装していきます。
実装
composer.jsonの作成
Laravel new [project名(今回はpac-dev)]でプロジェクトが準備できたらpackages/[vendor_name]/[package_name]ディレクトリを作成します。[vendor_name]は省略してpackages/[package_name]としても(のちの名前空間の指定を正確に記述できれば)問題ないかと思います。
$ mkdir packages && cd packages
$ mkdir nasteng && cd nasteng
$ mkdir say-hello && cd say-hello
ターミナルでcomposer initをすると対話形式でcomposer.jsonを作成することができますが、今回は手打ちしました。
重要なのはautoloadとextraです。
名前空間を使用する場合はautoloadで指定、Laravelプロジェクトに読み込ませるServiceProviderがある場合はprovidersに追記します。
また、今回はLaravel8で新しくなったルーティングの書き方をしているのでrequireでlaravel8以上に依存するように書いておきます。
{
"name": "nasteng/say-hello",
"description": "Add hello world automatically",
"authors": [{
"name": "nasteng"
}],
"require": {
"laravel/framework": "8.*"
},
"license": "MIT",
"autoload": {
"psr-4": {
"Nasteng\\SayHello\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Nasteng\\SayHello\\HelloServiceProvider"
]
}
}
}
ServiceProviderの作成
php artisan make:provider HelloServiceProvider
で作成ができますが、出力先がapp/Providersディレクトリなのでパッケージのディレクトリに移動させてnamespace等を編集する必要があります。
<?php
namespace Nasteng\SayHello;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
class HelloServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
$this->configureRoutes();
$this->configureViews();
}
private function configureRoutes()
{
$this->loadRoutesFrom(__DIR__ . '/../routes/routes.php');
}
private function configureViews()
{
$this->loadViewsFrom(__DIR__ . '/../resources/views', 'nasteng');
}
}
$this->loadRoutesFrom()メソッドでパッケージ内で定義するルーティングファイルを読み込みます。これによって自動的にLaravelアプリケーションのルーティングにroutes.phpの内容が追加されます。
$this->loadViewsFrom()メソッドではパッケージ内で使用するViewの場所を第一引数に渡し、第二引数はパッケージ名を指定します。詳しくはこちらのビューの項目を参考ください。こうすることでパッケージ内でview('nasteng::hello')
のようにヘルパメソッドのview()が使えるようになります。
Controllerの作成
localhost:8000/helloで受けたリクエストを処理するControllerを作成します。
<?php
namespace Nasteng\SayHello\Http\Controllers;
use Illuminate\Routing\Controller;
class HelloController extends Controller
{
public function index()
{
// パッケージ内のviewを指定
return view('nasteng::hello');
}
}
routesファイルの作成
helloページを表示するためのルーティングを定義します。
/helloへのアクセスは先ほど作成したHelloControllerのindexメソッドが処理します。
<?php
use Illuminate\Support\Facades\Route;
use Nasteng\SayHello\Http\Controllers\HelloController;
Route::get('hello', [HelloController::class, 'index']);
ビューの作成
今回は単にHello from SaHello Package!というH1タグを表示するBladeをsrc/resources/viewsディレクトリに作成します。
<h1>Hello from SayHello Package!</h1>
Laravelアプリケーション側のcomposer.jsonを編集
ローカルで作成しているパッケージを使うときはrepositories
というキーに追記していきます。場所はどこでも構いません。urlは絶対パスでも相対パスでもよいですが、相対パスの場合はLaravelアプリのcomposer.jsonからのパスを指定します。optionsのsymlinkはtrueにしておくとシンボリックリンクを貼ってくれるので、パッケージ開発中にソースコードを変更してもcomposer update
不要でリアルタイムに反映してくれます。
"repositories": [{
"type": "path",
"url": "./packages/nasteng/say-hello",
"options": {
"symlink": true
}
}],
"require": {
・・・
Laravelアプリケーション側でrequireする
ここまで書いたら後は使いたいLaravelアプリ側でcomposer require nasteng/say-hello
するとパッケージをインストールしてくれます。
$ composer require nasteng/say-hello
Using version dev-master for nasteng/say-hello
./composer.json has been updated
Running composer update nasteng/say-hello
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
- Locking nasteng/say-hello (dev-master)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing nasteng/say-hello (dev-master): Symlinking from ./packages/nasteng/say-hello
Generating optimized autoload files
・・・
これでパッケージのインストールは完了です。
php artisan serve
でビルトインサーバーを起動してlocalhost:8000/helloにアクセスすると・・・
表示できました!
機会があればもう少し実用的な機能を追加してみたいと思います。
以上、HappyなLaravelライフを🎉