Laravel5 チュートリアル - フロントエンド

ここまでで、ページの表示・データベースの設定ができるようになったので、一旦ビュー側の開発に関する事柄をまとめていきます。

LaravelのビューはBladeを使ってページをレンダリングします。ここでフロントエンドのスタックとしてSassを使ったり、JavaScriptのミニファイをしたり、Babelを使いたかったりとなるとGruntやGulpを使うことになると思いますが、LaravelではElixirというGulpのタスクでほとんどgulpfile.jsを書かずにSass/Less、Browserify、Babelのコンパイル、watchタスクを利用できます。

導入

Node.jsが必要なので、予めインストールしておきます。

Composerでプロジェクトを作ると、既にpackage.jsonが生成されているので、そのままnpm installします。インストール後、gulpが使えることを確認しておきます。

package.jsonにはdependenciesbootstrap-sassが記述されているので、必要に応じて削除しておきます。

% which gulp
./node_modules/.bin//gulp

設定

Gulpの設定はgulpfile.jsに書きます。

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

/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Sass
 | file for our application, as well as publishing vendor resources.
 |
 */

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

デフォルトではSassが有効になっていて、resources/assets/sass以下のapp.scssをコンパイルするようになっています。複数のsassファイルを対象にしたい場合はmix.sass()に対象ファイルの配列を渡します。

Sassをコンパイルするにはgulpコマンドを実行します。

% gulp

...
[11:22:14] Finished 'sass' after 490 ms

public/css以下にコンパイルされたapp.cssとソースマップのapp.css.mapができているはずです。

ソースマップを作らない場合は、gulpfileでelixirの設定をしておきます。

elixir.config.sourcemaps = false;  

JavaScript

CoffeeScript、Browserify、Babel、スクリプトのミニファイがデフォルトで使えるようになっています。(CoffeeScriptは個人的に普段使っていないので割愛)

複数のJSファイルを纏める

複数のJSのファイルをまとめるにはmix.scripts()を使います。

ファイルはresources/assets/jsからの相対パスであることが前提になっています。

elixir(function(mix) {  
  mix.scripts([
    'module.js',
    'app.js'
  ]);
});

gulpを実行すると、public/js以下にall.jsall.js.mapができています。また、配列で渡したファイルの順に処理されるので外部ライブラリを使う場合は、記述する順番を気をつける必要があります。

elixir(function(mix) {  
  mix.scripts([
    'jquery.js',   // app.jsで$を使うのでjqueryを先に書く
    'app.js'
  ]);
});

複数のファイルに出力したい場合にはscripts()をチェインします。

elixir(function(mix) {  
  mix.scripts([
        'module.js',
        'app.js'
      ], 'public/js/app.js')
     .scripts([
        'jquery.js',
        'underscore.js',
        'backbone.js'
      ], 'public/js/vendor.js');
});

Babel + Browserify

Babelを使う場合にはmix.babel()を利用します。ソースは同じようにresource/assets/jsからの相対パスで指定します。

elixir(function(mix) {  
  mix.babel([
    'module.js',
    'app.js'
  ]);
});

実際はBrowserifyとの組み合わせでbabelifyのようなトランスフォーマーを使うと思います。Babelifyは既にelixirでサポートされているので、設定を記述するだけです。

elixir.config.js.browserify.transformers.push({  
  name: 'babelify',
  options: {/** babelのオプション **/}
});

// ...

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

watch

% gulp watch

を実行すると、上記の処理が各ファイル保存時に走るようになるので、開発中はこれを使います。

BrowserSyncを使う

ElixirでBrowserSyncを使うための拡張があるので、それを使ってみました。

Laravel 5.2(Elixir 4~)以降はデフォルトで付属しているようです。

% npm install --save-dev laravel-elixir-browser-sync-simple

gulpfileは以下の様になります。

// elixir 4~ では不要
// require('laravel-elixir-browser-sync-simple');

elixir(function(mix) {  
  mix.browserSync({
    proxy:           'homestead.app',
    logConnections:  false,
    reloadOnRestart: true,
    notify:          true
  }, [
    "app/**/*",
    "public/**/*",
    "resources/views/**/*"
  ]);
});

proxy: 'homestead.app'の部分はHomestead.ymlで設定したドメイン名に書き換えて下さい。

Sass/Browserifyのタスクを絡めると以下の様になります。

var elixir = require('laravel-elixir');  
require('laravel-elixir-browser-sync-simple');

elixir.config.js.browserify.transformers.push({  
  name: 'babelify',
  options: {
    'stage': 2,
    'optional': []
  }
});

elixir(function(mix) {  
    mix
      .sass('app.scss')
      .browserify('app.js')
      .browserSync({
        proxy:           'homestead.app',
        logConnections:  false,
        reloadOnRestart: true,
        notify:          true
      }, [
        "app/**/*",
        "public/**/*",
        "resources/views/**/*"
      ]);
});

gulp watchを実行することでlocalhost:3000がブラウザで開きます。あとはassets以下のファイルの処理が完了しpublic以下にコピーされた時、Laravel側のコード(app/)、ビューが変更された時にブラウザが勝手にリロードしてくれるようになります。