イントロダクション

Laravel Elixir(エリクサー:万能薬)は、Laravelアプリケーションのための、基本的なGulpタスクを定義しており、きれいでスラスラかけるAPIを提供しています。Elixirは人気のあるCSSとJavascriptプリプロセッサー、それにテストツールもサポートしています。

Gulpやアセットのコンパイルを始めようとして、頭がこんがらがっているようでしたら、Laravel Elixirを気に入ってもらえるでしょう!

インストールと準備

Nodeのインストール

Elixirを始める前、最初にNode.jsをマシーンにインストール済みであることを確認してください。

node -v

Laravel Homesteadなら、デフォルトのままでも必要なものが全部そろっています。しかし、Vagrantを使っていなくても、Nodeのダウンロードページを読めば、簡単にインストールできます。心配ありません、簡単で時間もかかりません!

Gulp

次に、GulpをグローバルNPMパッケージとしてインストールします。

npm install --global gulp

Laravel Elixir

まだ残っているステップは、Elixirのインストールだけです。新しくLaravelをインストールすると、ルートディレクトリーにpackage.jsonがあることに気づくでしょう。PHPの代わりにNodeの依存パッケージが定義されている所が異なりますが、composer.jsonファイルと同じようなものだと考えてください。以下のコマンドで、依存パッケージをインストールしてください。

npm install

使用法

これでElixirがインストールできました。すぐに、コンパイルしたり、ファイルを結合したりできますよ!プロジェクトのルートディレクトリーに存在する、gulpfile.jsに全Elixirタスクが含まれています。

Lessのコンパイル

elixir(function(mix) {
    mix.less("app.less");
});

上の例は、Lessファイルがresources/assets/lessに保存されている前提です。

複数のLessファイルのコンパイル

elixir(function(mix) {
    mix.less([
        'app.less',
        'something-else.less'
    ]);
});

Sassのコンパイル

elixir(function(mix) {
    mix.sass("app.scss");
});

これは、Sassファイルがresources/assets/sassに保存してあると仮定しています。

Elixirはコンパイルするライブラリーとして、LibSassを裏で使用しています。状況により速度は遅いのですが、機能が豊かなRuby版を代わりに使用するのが有利な場合も明らかに存在します。RubyとSass gemがインストール済み(gem install sass)であれば、次のようにRuby版を使用できます。

elixir(function(mix) {
    mix.rubySass("app.sass");
});

ソースマップの生成を行わずコンパイルする

elixir.config.sourcemaps = false;

elixir(function(mix) {
    mix.sass("app.scss");
});

ソースマップ生成はデフォルトで有効になっています。各ファイルをコンパイルするごとに、\*.css.mapファイルが同じディレクトリーに生成されます。このマッピングはデバッグの時にコンパイル済みのスタイルシートセレクターからオリジナルのSassやLess定義を見つけるのに役立ちます!しかし、この機能を無効にすることもでき、上記のように指定します。

CoffeeScriptのコンパイル

elixir(function(mix) {
    mix.coffee();
});

これは、CoffeeScriptファイルがresources/assets/coffeeに保存されている前提です。

LessとCoffeeScript全部のコンパイル

elixir(function(mix) {
    mix.less()
       .coffee();
});

PHPUnitテストの起動

elixir(function(mix) {
    mix.phpUnit();
});

PHPSpecテストの起動

elixir(function(mix) {
    mix.phpSpec();
});

スタイルシートの結合

elixir(function(mix) {
    mix.styles([
        "normalize.css",
        "main.css"
    ]);
});

このメソッドに渡すファイルパスは、resources/assets/cssディレクトリーからの相対パスです。

スタイルシートを結合し、カスタムディレクトリーへ保存

elixir(function(mix) {
    mix.styles([
        "normalize.css",
        "main.css"
    ], 'public/build/css/everything.css');
});

カスタムベースディレクトリーのスタイルシートを結合

elixir(function(mix) {
    mix.styles([
        "normalize.css",
        "main.css"
    ], 'public/build/css/everything.css', 'public/css');
});

stylesscriptsメソッド両方の第3引数は、メソッドに渡される全相対パスに適用されるベースディレクトリーパスです。

ディレクトリー中の全スタイルシートを結合

elixir(function(mix) {
    mix.stylesIn("public/css");
});

スクリプトの結合

elixir(function(mix) {
    mix.scripts([
        "jquery.js",
        "app.js"
    ]);
});

この場合も、全パスはresources/assets/jsからの相対位置であると仮定されます。

ディレクトリー中の全スクリプトを結合

elixir(function(mix) {
    mix.scriptsIn("public/js/some/directory");
});

複数のスクリプトの組み合わせを結合

elixir(function(mix) {
    mix.scripts(['jquery.js', 'main.js'], 'public/js/main.js')
       .scripts(['forum.js', 'threads.js'], 'public/js/forum.js');
});

バージョン/ハッシュファイル

elixir(function(mix) {
    mix.version("css/all.css");
});

これにより、キャッシュを破棄させるために、一意のハッシュをファイル名に追加します。例えば、all-16d570a7.cssのような名前が生成されます。

ビューの中で、elixir()関数を使用すれば、適切なハッシュ値付きアセット名がロードされます。例をご覧ください。

<link rel="stylesheet" href="{{ elixir("css/all.css") }}">

裏でelixir()関数は、読み込むべきハッシュ値付きファイルの名前を決定します。肩の荷を下ろしたような感じがするでしょう?

バージョンを付ける複数のファイルを配列でversionメソッドに渡すこともできます。

elixir(function(mix) {
    mix.version(["css/all.css", "js/app.js"]);
});
<link rel="stylesheet" href="{{ elixir("css/all.css") }}">
<script src="{{ elixir("js/app.js") }}"></script>

新しい場所にファイルをコピー

elixir(function(mix) {
    mix.copy('vendor/foo/bar.css', 'public/css/bar.css');
});

新しい場所にディレクトリ全体をコピー

elixir(function(mix) {
    mix.copy('vendor/package/views', 'resources/views');
});

Browserifyの起動

elixir(function(mix) {
    mix.browserify('index.js');
});

ブラウザの中でモジュールを取り込みたい?そのうち、EcmaScript6を使いたい?JSXトランスフォーマーを組み込みたい?それならば、browserify Elixirタスクにより、Browserifyが仕事をうまいこと片付けてくれます。

このタスクはスクリプトの保存先がresources/assets/jsとして扱いますが、デフォルトは自由に変更できます。

メソッドのチェーン

もちろん、自分のレシピを作成するため、ほぼ全部のElixirのメソッドを一緒につなげて使用できます。

elixir(function(mix) {
    mix.less("app.less")
       .coffee()
       .phpUnit()
       .version("css/bootstrap.css");
});

Gulp

では、Elixirにどのタスクを実行するのか伝えましょう。コマンドラインから、Gulpを起動する必要があるだけです。

一度に全登録タスクを実行する

gulp

アセットの変更を監視する

gulp watch

スクリプトのコンパイルのみ

gulp scripts

スタイルのコンパイルのみ

gulp styles

テストとPHPクラスの変更を監視する

gulp tdd

注目: 全タスクは開発環境であると仮定していますので、圧縮はされません。実働用にするには、gulp --productionを指定してください。

タスクカスタマイズと拡張

ElixirのGulpタスクをフックしたいこともあるでしょう。自分に合うようにElixirのmixや監視を変更したいこともあるでしょう。問題ありません!

例として、呼びだされた時にテキストを少々話す一般的なタスクを考えてみましょう。

gulp.task("speak", function() {
    var message = "Tea...Earl Grey...Hot";

    gulp.src("").pipe(shell("say " + message));
});

とても簡単です。もちろん端末から、gulp speakでこのタスクを起動できます。ですが、Elixirに付け加えるには、mix.task()メソッドを使ってください。

elixir(function(mix) {
    mix.task('speak');
});

これだけです!これでGlupを実行すると、あなたがmixした他のElixirタスクと一緒に、"speak"カスタムタスクが実行されます。一つ以上のファイルが更新されるたび、カスタムタスクを再実行するために監視を登録するには、第2引数に正規表現で指定してください。

elixir(function(mix) {
    mix.task('speak', 'app/**/*.php');
});

この第2引数の指定により、"app/"ディレクトリー下のPHPファイルが保存される度に、"speak"タスクが再実行されるようにElixirへ指示しています。

より柔軟な方法として、完全なElixir拡張を作成することもできます。前の"speak"の例を拡張として書いてみましょう。次のようになります。

var gulp = require("gulp");
var shell = require("gulp-shell");
var elixir = require("laravel-elixir");

elixir.extend("speak", function(message) {

    gulp.task("speak", function() {
        gulp.src("").pipe(shell("say " + message));
    });

    return this.queueTask("speak");

 });

Gulpタスクを作成するコールバック関数と同時に、Gulpfileの中で参照される名前を渡すことにより、ElixirのAPIを拡張(extend)していることに注目してください。

前記のように、カスタムタスクを監視したい場合は登録しましょう。

this.registerWatcher("speak", "app/**/*.php");

この行は、正規表現app/**/*.phpに一致するファイルが変更された時に、speakタスクを実行することを示しています。

これだけです!これを一番上のGulpfileに書いても良いですし、代わりにカスタムタスクファイルへ切り分けてもかまいません。後者のアプローチを取る場合、Gulpfileの中から読み込むだけです。

require("./custom-tasks")

済みました!これで使えます。

elixir(function(mix) {
    mix.speak("Tea, Earl Grey, Hot");
});

この追加により、Gulpを起動すると、ピカードがお茶を要求してくるようになります。