Webアプリケーションを開発しててよくあるのが、画像とかcssとかを更新してもブラウザがキャッシュしちゃってて
なかなかクライアント側に反映されないなんてことがあります。
解決方法としては色々あると思いますが、その一つにファイル名を変えてしまうというのがあります。
例えば
app.css
こういうcssがあったとしたら
app-001.css
こんな名前にして、cssを更新するたびに001の部分も変えていくわけです。
ただしこれを自分で書き換えていくのは超しんどいです。
けれどLaravel5でWebアプリケーションをつくるなら、Laravel Elixirという機能を利用することで簡単に解決してくれる事がわかったので使ってみました。
Laravel Elixirを使えばcssに限らずpublicディレクトリ下のファイルを簡単にバージョニングして、テンプレート側を書き換えることなく更新する事が出来ます。
Laravel Elixirを利用するための準備
Elixirはnodeモジュールとして提供されているため、いくつかインストールする必要があります。
Node.js
nvmを利用してnodejsのインストール
$ cd ~
$ curl https://raw.githubusercontent.com/creationix/nvm/v0.13.1/install.sh | bash
$ nvm install v0.12.0
$ nvm alias default v0.12.0
$ node -v
v0.12.0
$ nvm --version
0.13.1
$ npm -v
2.5.1
nodejsのバージョンはv0.12.0を指定しました。1
gulp
ストリーミングビルドシステム
プラグインを組み合わせながら様々なファイルをビルドする仕組みを提供してくれるっぽい。
Laravel ElixirにはLESSを編集しながらCSSを適用していくみたいな機能があって
それを実現するためにストリーミング機能のあるgulpが採用されているんだと思う。
$ npm install -g gulp
$ gulp -v
[12:59:47] CLI version 3.8.11
[12:59:47] Local version 3.8.11
Elixir
Laravelアプリケーション内にあるpackage.json2を使ってインストール
(僕の場合は/www/laravel5.app/htdocs配下にappとか置いてある感じです。)
$ cd /www/laravel5.app/htdocs/
$ npm install
するとカレントディレクトリにnode_modulesディレクトリが作成されてそこにインストールされてます。
Elixirを使ってみる
まずはgulpfile.jsを見てみます。
$ cd /www/laravel5.app/htdocs/
$ cat 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 Less
| file for our application, as well as publishing vendor resources.
|
*/
elixir(function(mix) {
mix.less('app.less');
});
このmix.less('app.less');
で指定されているファイルはresources/assets/less/app.less
のことです。
Laravelではlessを使ってcssを作ることができて、これはapp.lessをコンパイルしてくれって命令ですね。
Elixirを使うにはこのgulpfile.jsを編集してgulpコマンドを叩く必要があるのですが、
いったんこのままgulpコマンドを実行してみます。
$ gulp
[13:00:32] Using gulpfile /www/laravel5.app/htdocs/gulpfile.js
[13:00:32] Starting 'default'...
[13:00:32] Starting 'less'...
[13:00:33] Finished 'default' after 930 ms
[13:00:35] gulp-notify: [Laravel Elixir]
[13:00:35] gulp-notify: [Laravel Elixir]
[13:00:35] Finished 'less' after 3.49 s
[13:00:35] gulp-notify: [Error in notifier] Error in plugin 'gulp-notify'
not found: notify-send
[13:00:35] gulp-notify: [Error in notifier] Error in plugin 'gulp-notify'
not found: notify-send
これにより
public/css/app.css.map が作成されて
public/css/app.css が更新されます
gulpコマンド実行時にエラーが発生しましたが、Elixirの利用にはひとまず問題ありませんでした3
バージョニング
gulpfile.jsを下記のように修正します。
elixir(function(mix) {
//mix.less('app.less');
mix.less('app.less').version('css/app.css');
});
再びgulpコマンドを実行すると publicディレクトリ配下にbuild関連のファイルが作成されます。
そしてバージョニングされたapp.cssが作成されます。
public/build/css/app-bfb06d94.css
あとはこれをViewで表示してあげるだけです。
app.cssを指定している箇所を下記のように修正します。
<!--<link href="/css/app.css" rel="stylesheet">-->
<link href="{{ elixir("css/app.css") }}" rel="stylesheet">
上記コードから生成されるHTMLはこれ
<link href="/build/css/app-bfb06d94.css" rel="stylesheet">
elixirメソッドがapp.cssのバージョニングされたファイルパスを返してくれるので
app-xxxxxx.cssというファイル名が変更されてもテンプレート側を修正する必要はありません。
ファイルを複数指定したい
配列で渡してあげます。
mix.less('app.less').version(['css/app.css', 'logo.jpg']);
less使わないでcss直接書くケース
mix.version(['css/app.css', 'logo.jpg']);
ディレクトリ単位でまとめて指定
mix.version(['css/*', 'image/*']);
Elixirは他にも色々機能があるようなので、引き続き色々試してみたいと思います。
-
最初 v0.11.14でやったらnode-sassのインストールでエラーになって困った。まさにピンポイントのissueがあがっててv0.12.0にしたら解決してたので参考にしました。https://github.com/sass/node-sass/issues/679 ↩
-
Laravel5.0.1まではpackage.jsonにないprivateオプションがmasterブランチには追加されていたから5.0.2あたりで入ってくるのかな https://github.com/laravel/laravel/blob/master/package.json ↩
-
なにやらvagrant環境だと出てしまうよう。。。要調査。https://laracasts.com/discuss/channels/general-discussion/laravel-elixer-gulp-watch-error-in-homestead http://stepquick.net/blog/2014/09/08/use-gulp-notify-with-terminal-notifier/ ↩