Laravel Elixir、初心者向け解説

タグ: Laravel5.1   Laravel5.2  

Laravel Elixirが導入された頃に触り、結論としてはGulpで直接書いた方が便利だという結論に達してから一年経ちました。今回、再度触ってみたら全く忘れていました。

真っ白な頭にリセットされ、ちょうどよい機会なので、初心者向けの解説を書きます。

Gulpとは

タスクランナーです。決まった動作(タスク)を定義し、それを実行する機能です。Gulpはnode.js上で動作しますが、タスクランナーはどんな言語でも実現できますので、いろいろな言語にタスクランナーは存在し、Laravelのようなフレームワークでも、独自のランナーを持っていたりします。

一般には、決まった手順を走らせるだけでは不便ですので、特定のディレクトリーやファイルの変更を監視し、それが起きた時に指定したタスクを走らせます。ソースファイルが変更、追加されたらテストを走らせるとか、Laravel Elixirの目的とする、Web関連のリソースに変更が起きたら、自動的に仮想するとかです。今ではファイル監視を含めてタスクランナーと考えて良いでしょう。

Laravel Elixirとは

Laravelフレームワークに含まれている、Gulpをラップしたユーティリティーです。CSSとJSのリソースを小さくし、再表示までスムーズに自動化するためのシステムです。

目的としては、Gulpを学習し、自分でタスクを組むよりも手間を少なく、このような自動化をできるようにすることですが、素のElixirでできること以上を行おうとすると、かえって面倒です。

そのため、公式マニュアルやこの記事、後ほど紹介する関連記事の範囲を超えることをやりたい場合は、素直にGulpを学習したほうが柔軟性もあり、時間もかかりません。やりたいことと似たようなサンプルを見つけ、手を入れ、足りない部分はGulpのプラグインを探すだけでたいてい事足ります。順次実行、非同期による複数タスクの同時実行の制御も簡単にできますので、複雑なことはGulpのほうがすっきりと実現できます。

Laravel Elixirの利用シナリオ

最初にリソースを作成するため、Gulpをタスクを指定せずに起動し、デフォルト動作を行います。後述するElixirタスクのcopyやBrowserSyncは、デフォルト動作では動きません。

$> gulp

次に、ファイルを監視するためwatchタスクを起動します。このコマンドはファイルの変更を監視し続けるため、終了しません。終わらせたい場合はCTRL+Cなどで強制終了させます。

$> gulp watch

開発がある程度進み、プロジェクトのリリースなどのため、CSSやJSを小さくし、マップファイルを削除する場合は、productionオプションを付けて実行します。

$> gulp --production

Laravel Elixirは、このフローで使用するためのものだと割りきって使いましょう。それ以上のことがやりたい場合は、Elixirを拡張するより、Gulpで直接書くか、他のタスクランナーを使いましょう。

Laravel Elixirのコードの流れ

ElixirはGulp上で動作するので、Gulpの動作ファイルである、gulpfile.jsがLaravelプロジェクトに用意されています。

Bootstrap CSSフレームワークを利用する場合の解説記事から、コード部分を抜き出します。Elixirタスクの呼び出し順は変えていますが、動作は同じです。

 var elixir = require('laravel-elixir');

elixir(function(mix) {
    mix.copy('node_modules/bootstrap-sass/assets/javascripts/bootstrap.min.js', 'public/js/bootstrap.min.js')
    .sass('app.scss')
    .version('css/app.css')
    .browserSync({proxy:'some.local'});

まず、つまずく点は、各タスクを呼び出すメソッドの解説は公式ドキュメントにありますが、チェーンで続けるというサンプルがないことでしょう。記述は1箇所あります。サンプルから学ぶタイプの人は、見落としがちです。

次につまずく点は、Gulpの起動方法により、動作が異なる点です。まず、gulpgulp --productionで動作させた場合、記述順に実行されます。この場合、指定したJSファイルをコピーし、SASSコンパイルし、バージョニングします。

browerSyncはwatchタスクでのみ動作します。逆にcopyタスクはwatchタスクでは動作しません。

gulp watchの場合、すべてのタスクは非同期でファイル変更を監視します。それぞれのタスクには管理対象ディレクトリ/ファイルがあり、変更があった場合に各タスクが実行されます。

タスクの監視対象

注意:ソースを読んでの理解ですので、間違って理解しているところもあると思います。特にcopyの動作については、詳細は調べていません。

Elixirのタスクにはデフォルトの入力ディレクトリーが決まっています。まず、このディフォルト入力ディレクトリー下が監視対象になります。たとえばJSスクリプトをまとめるstylesの場合、'resources/assets/js'ディレクトリがデフォルトの入力元です。最初の引数で指定する入力ファイルは、デフォルトディレクトリからの相対位置として扱われます。(copyタスクは不特定多数の場所が指定されるという性質から、デフォルトは決まっていません。)

大抵のタスクメソッドの引数は、入力、出力とドキュメントに記述されています。実際にはcopyやbrowserSyncを除き、入力デフォルトディレクトリを変更するために、ディレクトリパスを3番めに指定できるようになっています。

mix.styles(['入力1.css', '入力2.css'],'出力.css','resources/assets/project/js')

上記の場合、'resources/assets/project/js'がデフォルトの入力ディレクトリとなりますので、もともとの'resources/assets/js'に取って代わり、監視対象となります。

さらに、指定した入力ファイルも監視対象となります。たとえば'resources/assets/project/js/my.js'ファイルをまとめる入力ファイルに指定した場合、そのファイルも監視対象となります。

copyタスクの場合は、単に入力ファイル/ディレクトリが監視対象になります。

browserSyncタスクの場合は、以下のディレクトリと拡張子が監視対象です。

  • app下の.phpファイル
  • public/css下の.cssファイル
  • public/js下の.jsファイル
  • public/build/rev-manifest.jsonファイル
  • resources/views/下の.phpファイル

なお、gulpgulp --productionで実行した場合も監視先と出力ファイルが比較され、不必要なタスクは動きません。強制的に動作させるためには、監視先をtouchするか、出力ファイルを削除してください。(出力ファイルを削除した場合、すぐにgulp watchを実行してしまうと、はまりがちです。気をつけてください。)

参照リンク

検索かけたほうが早いとは思いますが…

再度繰り返しになりますが…

今回紹介した以外にも、入力にディレクトリーを指定した場合の取り扱いや、シンプルに指定されたファイルを接続するcombineタスク、タスクを自分で拡張する方法など、他にも記述を加えることができますが、最初に説明した通り、そこまで踏み込むのであれば、Gulpを直接勉強するほうが有利です。

この記事で書いたこと、ドキュメントに記載されている範囲で使うのであれば、Elixirは便利に使えます。ちょっとやって、つまづいたらGulpや他のタスクランナー、もしくはお使いのIDEの設定について調べてみるほうが良いでしょう。