Foundation6をLaravel Elixirで使用する1

タグ: Laravel5.1   Laravel5.2  

前記事でBootstrap CSSフレームワークの使い方を紹介しましたので、今回はFoundation6 CSSフレームワークを使う場合のケーススタディです。自動化はLaravel側のLaravel Elixir(Gulp)を利用します。

(追記:Foundation6のZUBRテンプレートをLaravelプロジェクトと一緒に利用する記事を書きました。お好みでどうぞ。)

方針

Foundation6ではnpmでインストールするfoundationコマンドが用意されています。バージョン6になり、かなり便利に環境を整えることができます。foundation newコマンドを実行し、表示されるプロンプトに答えると、指定ディレクトリーにプロジェクトが用意されます。

foundation build構築、foundation watchで変更を監視し自動コンパイル等のジョブを行ってくれますが、Laravel Elixirと機能はかちあいます。両方を一度に使用すると面倒ですので、今回はfoundation newコマンドでLaravelプロジェクトの中にFoundation6のプロジェクトディレクトリを作成し、この中に用意されたファイルをElixir側から利用する方針にします。

生成されたFoundation6のプロジェクトファイルには一切手を加えません。

事前準備

真新しくLaravelプロジェクトを作成してください。

foundationコマンドをインストールしていない場合は、Foundationのインストールドキュメントに従い、用意してください。

ドキュメントのManual Installに記述されている手段でFoundationテンプレートをインストールする方法もありますが、LaravelプロジェクトがGitで管理されているかどうかにより手順は変わるでしょう。また、foundation newコマンドにより生成されるテンプレートと構造が同じかは確認していません。そのため、以降のファイルパスの調整が必要かもしれません。

Foundationプロジェクトの作成

Laravelプロジェクトルート下に、Foundationプロジェクトを作成します。プロジェクトルートでfoundation newコマンドを実行してください。後は以降に従い、プロンプトに答えてください。

$ foundation new

? What are you building today? (Use arrow keys)
❯ A website (Foundation for Sites) # これを選択してEnter
  A web app (Foundation for Apps) 
  An email (Foundation for Emails)

? What's the project called? (no spaces) # foundation6 と入力しEnter

? Which template would you like to use? (Use arrow keys)
❯ Basic Template: includes a Sass compiler # これを選択してEnter
  ZURB Template: includes Handlebars templates and Sass/JS compilers 
            .
           /|     ,
      , /|/  \/| /|       Thanks for using ZURB Foundation for Sites!
     /|/       |/ |       -------------------------------------------
 |___|            |___|   Let's set up a new project.
 \___|  ^^   ^^   |___/   It shouldn't take more than a minute.
     | -[O]--[O]- |
     |    ___,    |
     |    ...     |
      \__________/


Downloading the project template...
Done downloading!

Installing dependencies...

インストールが終了するまで数分かかります。

テンプレートではBasicテンプレートを選択しました。構造が簡単だからです。ZURBテンプレートはFoundation単独のプロジェクトとして利用する場合には便利です。ZURBテンプレートとBasicテンプレートはディレクトリ構造が異なるため、選択した場合は以下の記述のファイルパスを修正する必要があります。

Laravelプロジェクトの準備

foundation6/scssディレクトリに存在する、_setting.scssとapp.scssをresources/assets/sassディレクトリー下にコピーします。この2つのファイルを変更し、生成するcssを調整します。

続いてfoundation6/jsディレクトリをresources/assetsへコピーします。resources/assets/js/app.jsファイルが含まれています。

最後がメインイベントです。プロジェクトルートのgulpfile.jsを変更します。foundation6ディレクトリ下にも同名のファイルがありますので、間違えないでください。

var gulp = require('gulp');
var elixir = require('laravel-elixir');
var del = require('del');
var plugins = require('gulp-load-plugins');

const $ = plugins();

// 使用するJavacriptスクリプトのリスト
// FoundationのZUBRテンプレートに含まれるConfig.ymlからコピー
const JsFiles = [
        // Foundationに必要なファイル
        '../../../foundation6/bower_components/jquery/dist/jquery.js',
        '../../../foundation6/bower_components/what-input/what-input.js',
        // Foundationのコアファイル
        '../../../foundation6/bower_components/foundation-sites/js/foundation.core.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.util.*.js',
        // Foundationのコンポーネント
        // 使用しないコンポーネントはコメントアウトすると軽くなる
        '../../../foundation6/bower_components/foundation-sites/js/foundation.abide.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.accordion.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.accordionMenu.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.drilldown.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.dropdown.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.dropdownMenu.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.equalizer.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.interchange.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.magellan.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.offcanvas.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.orbit.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.responsiveMenu.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.responsiveToggle.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.reveal.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.slider.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.sticky.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.tabs.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.toggler.js',
        '../../../foundation6/bower_components/foundation-sites/js/foundation.tooltip.js',
        // プロジェクト用のコードは以下へ記述
        'app.js'
        ];

// Laravel Elixirのパート

elixir(function(mix) {
    // SASSコンパイル
    mix.sass('app.scss', null, {includePaths: [
        'foundation6/bower_components/foundation-sites/scss',
        'foundation6/bower_components/motion-ui/src'
    ]})

        // FundationのGulpのコンパイルタスクではbabelを通しているため、
        // ここでもbabelを使用する
        .babel(JsFiles, 'public/js/app.js')

        // バージョン付け
        .version(['css/app.css', 'js/app.js'])

        // 表示ページの再描写
        .browserSync({proxy:'127.10.10.10:8000'});
});

// 実働(Production)環境向けファイル生成のためにGulpファイル追加
// Laravel ElixirのCSS処理ではUNCSSを使っていない
// FoundationのCSSファイルはUNCSSを通さないと十分に小さくならないため、
// UnCSSを通すために組んだタスク。
// JavaScriptの処理はElixirのタスクを使用することもできるはず。
//
// Produnction向け、バージョン付きCSS/JSを作成するには:
// 'gulp produnction'を実行する

// CSSとJSをプロダクション向けに圧縮する
gulp.task('production',['versioning']);

// タスクを順次実行するために、依存を記述する
// 以下の場合、slimcssとslimjsは同時実行される
gulp.task('versioning', ['slimcss', 'slimjs'], function () {
    // Elixirのversionの呼び出し
    return elixir.Task.find('version').run(['css/app.css', 'js/app.js']);
});

// 不必要なCSS要素を取り除き、圧縮する
gulp.task('slimcss', ['clean'], function () {
    return gulp.src('public/css/app.css')
        // 必要/不必要を判断するhtmlファイルとして
        // ビューファイルとビューのコンパイル結果を食わせる
        .pipe($.uncss({
            html: [
                'resources/views/**/*.php',
                'storage/framework/views/*'
            ],
            ignore: ['!!js/regexp .foundation-mq', '!!js/regexp ^\.is-.*']
        }))
        .pipe($.cssnano())
        .pipe(gulp.dest('public/css'));
});

// JSファイルの圧縮
gulp.task('slimjs', ['clean'], function slimJs() {
    return gulp.src(JsFiles.map(function (item) {
            return 'resources/assets/js/'+item;
        }))
        .pipe($.babel())
        .pipe($.concat('app.js'))
        .pipe($.uglify({compress: { drop_console: true }}))
        .pipe(gulp.dest('public/js'));
});

// マップファイル削除
gulp.task('clean', function (done) {
    del(['public/**/*.map']);
    done();
});

BrowserSyncのプロキシは適宜修正してください。プロジェクトへWebサーバーの仮想ホスト名を割りつける場合は、そのホスト名です。PHP組み込みサーバーを利用する場合は、たとえばphp artisan --host=127.10.10.10のように、localhostを避けてください。その場合、プロキシには127.10.10.10:8000を指定します。

次に、必要なnodejsパッケージをインストールします。

$> npm install
$> npm remove bootstrap-sass
$> npm install --save-dev gulp-uncss gulp-load-plugins gulp-cssnano gulp-babel gulp-cssnano gulp-concat gulp-uglify del

これで準備が整いました。

使い方

まず、上記コード中、browserSyncのプロキシをプロジェクトに合わせ指定してください。ローカルのマシン名をWebサーバーの仮想ホストとして利用する場合は、その名前です。

繰り返しますが、PHPビルトインサーバーを使用する場合は、php artisan serve --host=127.10.10.10のように、localhostを避けて起動してください。この場合はプロキシとして127.10.10.10:8000と指定します。

開発フロー

初回実行する場合、もしくは全体を再生成したいときは、gulpのみでElixirタスクを実行してください。

後は、gulp watchで監視タスクとして持続起動させると、自動的にブラウザにページが表示されます。リソースやapp下のphpコードを変更し保存すると、結果が自動的に反映されます。

実働環境用に圧縮したCSSとJSを作成する場合、通常Laravel Elixirを使用する場合は、gulp --productionとオプションで指定しますが、今回はUNCSSを通し、CSSを更に小さくするためにGulpタスクを追加してあります。gulp productionを実行してください。

welcomeビュー

Laravelをインストール直後にルートURLへアクセスした場合、resources/views/welcome.blade.phpファイルの内容が表示されます。Foundation6を使用していませんので、確認ができません。

そこで、foundation6/index.htmlの内容でwelcome.blade.phpの内容を上書きしてしまいましょう。続いて以下の箇所を修正します。

<link rel="stylesheet" href="css/app.css}}">

バージョンしたapp.cssファイルを読みこむように変更します。

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

もう一箇所、最後のほうで読み込んでいるJavaScriptファイルを変更します。

<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/what-input/what-input.js"></script>
<script src="bower_components/foundation-sites/dist/foundation.js"></script>
<script src="js/app.js"></script>

全てはapp.jsにまとめられています。バージョン付けしたファイルを指定します。

<script src="{{ elixir('js/app.js') }}"></script>

watch起動中であれば、保存した時点で再表示され、Foundation6のサンプルページが表示されます。

注意点

UNCSSの対象外にするため、!!js/regexp ^\.is-.*と指定しています。これは元々FoundationのUNCSSオプションとして指定されてるものです。しかし、必要な要素まで削除されることがあるようです。その場合は!!js/regexp \.is-.*に変更し、試してみてください。手元の環境では、うまくいくようです。

なお、さほど使い込んでいないため、多分バグもあると思います。適宜修正してお使いください。