😏
laravelプロジェクトでesbuild使ってjsファイルのバージョニングしたい時
簡単にどいうことか先に説明すると、laravel デフォルトのlaravel-mixを使わずに、esbuild
やswc
を使ってassetsをbundleした場合にlaravel-mixのmanifest.json
ファイルが作られないので、バージョニングができなくなってしまい、アプリに新しい機能のアップデートをした時にキャッシュがクリアされるまで元のキャッシュファイルが読み込まれる事が起こります、当然laravelのmix()
ヘルパーも使えません。
その対策を探したところ、ピッタリの記事を見つかったので、そのまま日本語で書き残しておきたいと思います。
参考にした記事👇
流れとしては、productionの時だけphp artisan key:generate
と同じ感覚でランダムの文字列を作成して、.env
ファイルの中を更新します、そしてBlade::directive()
関数を使って、カスタムのblade関数を作ります、最後はその関数を使ってjsファイルのurlを指定します。
assets.php設定ファイルの作成
config/assets.php
ファイルを作成して👇の記述を追加します。
<?php
return [
'version' => env('ASSETS_VERSION', null)
];
?>
.envファイルにキーを追加
.env
ファイルにassets.php
で指定しているキーを追加
ASSETS_VERSION=
ここは一旦空文字で大丈夫です。
artisanコマンド作成
php artisan make:command AssetVerioningCommand
でコマンド作成します、そしたらapp\Commands\AssetVerioningCommand.php
が生成されます。
<?php
namespace App\Console\Commands;
use App\Utilities\Str;
use Illuminate\Console\Command;
use Illuminate\Console\ConfirmableTrait;
class AssetVersioningCommand extends Command
{
use ConfirmableTrait; //<--👈追加
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'assets:version {--force : Force the operation to run when in production}'; //<--👈変更する
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate an asset version identifier'; //<--👈コマンドの説明
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$key = $this->generateRandomKey();
if (! $this->setKeyInEnvironmentFile($key)) {
return;
}
$this->info('Asset version key set successfully.');
}
protected function generateRandomKey(): string
{
return Str::random(16);
}
/**
* @param string $key
*/
protected function setKeyInEnvironmentFile($key)
{
$currentKey = $this->laravel['config']['assets.version'];
if (strlen($currentKey) !== 0 && (!$this->confirmToProceed())) {
return false;
}
$this->writeNewEnvironmentFileWith($key);
return true;
}
protected function writeNewEnvironmentFileWith($key)
{
file_put_contents($this->laravel->environmentFilePath(), preg_replace(
$this->keyReplacementPattern(),
'ASSETS_VERSION=' . $key,
file_get_contents($this->laravel->environmentFilePath())
));
}
protected function keyReplacementPattern()
{
$escaped = preg_quote('=' . $this->laravel['config']['assets.version'], '/');
return "/^ASSETS_VERSION{$escaped}/m";
}
}
AppServiceProvider.phpに記述追加
次はAppServiceProvider.php
のboot()
関数にカスタムBlade関数を登録します。
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::directive('version', function ($path) {
return "<?php echo config('assets.version') ? asset({$path}) . '?v=' . config('assets.version') : asset({$path}); ?>";
});
}
}
blade.phpの記述を変更
<!-- <script src="{{ mix('js/public/app.js') }}" defer></script> -->
<!-- 👇に変更 -->
<script src="@version('js/public/app.js')" defer></script>
laravelを再起動すれば、反映されるはずです。🤗
Discussion