Rectorを使って地獄のLaravelアップグレード作業をEASYにしよう[Laravel7→11]
はじめに
あるプロジェクトで、PHP・Laravelのアップグレードを行うことになりました。
バージョンを確認したところ、Laravel7でした。がんばって11まで上げていかなくてはなりません。
アップグレード作業は未経験であり、ましてやLaravel7→11と八艘飛びな変更であるため、「間違いなくやらかすぞ!?」と戦々恐々でした。
はてさて、どっから手を付けたらいいものか。ミスを減らしながら、楽にできる方法は無いかと探していたところ、Rectorに出会いました。
Rectorがなければ、私は爆発していました。
Rectoreへの感謝を込めて、Rector推し記事を書いた次第です。
この記事を読んで欲しい人
- PHP・Laravelのアップグレードしたい人!
- アップグレード作業が不慣れ・未経験の人
Rector、Rector-laravelとは
公式がこちら
RectorはPHPコードを即座にアップグレード、リファクタリングします。PHP、Laravelだけでなく、Symfony、PHPUnit、Doctrineなどをサポートしています。
更に、Rectorの拡張機能として、Laravelコミュニティが開発した"Rector-laravel"が提供されています。本記事ではRector&Rector-laravelにより、PHPとLaravelのバージョンアップのやりかたを記述します。
Rectorをインストールし、rector.phpを以下のように書き換え、実行するだけで、非推奨になった記述法などを検出し、アップグレードに対応したコードに一気に書き換えてくれます!素敵!
↓これでLaravel11の記法に変更してくれる。素敵!
<?php declare(strict_types=1);
use Rector\Config\RectorConfig;
use RectorLaravel\Set\LaravelLevelSetList;
return RectorConfig::configure()
->withSets([
LaravelLevelSetList::UP_TO_LARAVEL_110,
]);
Rector、Rector-laravelの導入方法
composer require rector/rector --dev
composer require driftingly/rector-laravel --dev
を実行します。
rector.phpの書き換え
rector.phpのconfigを書き換え、アップグレードしたいPHPやLaravelのバージョンに調整します。
<?php declare(strict_types=1);
use Rector\Config\RectorConfig;
use RectorLaravel\Set\LaravelLevelSetList;
return RectorConfig::configure()
->withSets([
LevelSetList::UP_TO_PHP_84, // PHP 8.4の機能を有効化
LaravelLevelSetList::UP_TO_LARAVEL_110,
]);
LevelSetList::UP_TO_PHP_80
にすると、PHP8.0に対応したコード修正ができます
Laravelは7→8→9→10→11と段階的に上げていく必要がありますが、LaravelLevelSetList::UP_TO_LARAVEL_80
と記述すればLaravel8に対応したコード修正ができるので、段階的に上げていくのも簡単です。
実行!
いよいよ、Rectorを実行してコードを修正しましょう。
ドライランを行うと、変更点をターミナルで明記してくれます。
vendor/bin/rector process --dry-run
実際にコードを書き換える際はドライランオプションを消して実行すればOKです!
vendor/bin/rector process
これでコード修正ができました!!
おわりに
折角なので、実際に使用したrector.phpファイルの中身をお見せします。
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use RectorLaravel\Set\LaravelSetList;
use Rector\Set\ValueObject\LevelSetList;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector;
use Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector;
use Rector\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector;
use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\PHPUnit\Set\PHPUnitSetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/app',
__DIR__ . '/config',
__DIR__ . '/database',
__DIR__ . '/routes',
__DIR__ . '/routes/web.php',
__DIR__ . '/tests',
]);
// Laravel 11への移行に必要なルールセット
$rectorConfig->sets([
LaravelSetList::LARAVEL_110, // Laravel 11.0への移行ルール
LaravelSetList::LARAVEL_CODE_QUALITY,
LevelSetList::UP_TO_PHP_84, // PHP 8.4の機能を有効化
PHPUnitSetList::PHPUNIT_100,
]);
// PHP 8.4の機能を活用するためのルール
$rectorConfig->rule(TypedPropertyFromStrictConstructorRector::class);
$rectorConfig->rule(ClassPropertyAssignToConstructorPromotionRector::class);
$rectorConfig->rule(RemoveUselessParamTagRector::class);
$rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
// インポート設定
$rectorConfig->importNames();
$rectorConfig->importShortClasses(false);
// スキップ設定
$rectorConfig->skip([
__DIR__ . '/vendor',
__DIR__ . '/bootstrap/cache',
__DIR__ . '/storage',
__DIR__ . '/.phpunit.cache',
__DIR__ . '/node_modules',
]);
};
Discussion