Laravel5.5 LTS 日本語ドキュメント

このリポジトリはPHP Webアプリフレームワークである、LaravelのLTSバージョンである5.5の公式英文ドキュメントを日本語へ翻訳しています。

This project is maintained by okinaka

アセットのコンパイル(Laravel Mix)

イントロダクション

Laravel Mixは多くの一般的なCSSとJavaScriptのプリプロセッサを使用し、Laravelアプリケーションために、構築過程をWebpackでスラスラと定義できるAPIを提供しています。シンプルなメソッドチェーンを使用しているため、アセットパイプラインを流暢に定義できます。例を見てください。

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css');

Webpackやアセットのコンパイルを始めようとして、混乱と圧倒を感じているならLaravel Mixを気に入ってもらえるでしょう。しかし、アプリケーションの開発時に必要だというわけではありません。どんなアセットパイプラインツールを使用してもかまいませんし、使わなくても良いのです。

インストールと準備

Nodeのインストール

Elixirを始める前、最初にNode.jsとNPMを開発機へ確実にインストールしてください。

node -v
npm -v

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

Laravel Mix

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

npm install

Mixの実行

MixはWebpack上の設定レイヤーですから、Laravelに含まれるpackage.jsonファイル上のNPMスクリプトの一つをMixの実行で起動してください。

// 全タスク実行
npm run dev

// 全タスク実行を実行し、出力を圧縮
npm run production

アセット変更の監視

npm run watchコマンドはターミナルで実行し続け、関連ファイル全部の変更を監視します。Webpackは変更を感知すると、アセットを自動的に再コンパイルします。

npm run watch

特定の環境のWebpackでは、ファイル変更時に更新されないことがあります。自分のシステムでこれが起きた場合は、watch-pollコマンドを使用してください。

npm run watch-poll

スタイルシートの操作

webpack.mix.jsファイルは全アセットコンパイルのエントリポイントです。Webpackの軽い設定ラッパーだと考えてください。Mixタスクはアセットをどのようにコンパイルすべきかを正確に定義するため、チェーンでつなげます。

Less

LessをCSSへコンパイルするにはlessメソッドを使用します。最も主要なapp.lessファイルをpublic/css/app.cssとしてコンパイルしてみましょう。

mix.less('resources/assets/less/app.less', 'public/css');

複数のファイルをコンパイルするには、lessメソッドを複数回呼び出します。

mix.less('resources/assets/less/app.less', 'public/css')
   .less('resources/assets/less/admin.less', 'public/css');

コンパイル済みのCSSのファイル名をカスタマイズしたい場合は、lessの第2引数にファイルのフルパスを指定してください。

mix.less('resources/assets/less/app.less', 'public/stylesheets/styles.css');

裏で動作しているLessプラグインのオプションをオーバーライドする必要が起きたら、mix.less()の第3引数にオブジェクトを渡してください。

mix.less('resources/assets/less/app.less', 'public/css', {
    strictMath: true
});

Sass

sassメソッドは、SassをCSSへコンパイルします。次のように使用します。

mix.sass('resources/assets/sass/app.scss', 'public/css');

lessメソッドでも、複数のSassファイルを別々のCSSファイルへコンパイルできますし、結果のCSSの出力ディレクトリをカスタマイズ可能です。

mix.sass('resources/assets/sass/app.sass', 'public/css')
   .sass('resources/assets/sass/admin.sass', 'public/css/admin');

さらに、Node-Sassプラグインオプションを第3引数に指定できます。

mix.sass('resources/assets/sass/app.sass', 'public/css', {
    precision: 5
});

Stylus

LessやSassと同様に、stylusメソッドにより、StylusをCSSへコンパイルできます。

mix.stylus('resources/assets/stylus/app.styl', 'public/css');

さらに、Ruptureのような、追加のStylusプラグインをインストールすることもできます。最初に、NPM (npm install rupture)による質問でプラグインをインストールし、それからmix.stylus()の中で呼び出してください。

mix.stylus('resources/assets/stylus/app.styl', 'public/css', {
    use: [
        require('rupture')()
    ]
});

PostCSS

強力なCSS加工ツールであるPostCSSも、Laravel Mixには最初から含まれています。デフォルトでは、自動的に必要なCSS3ベンダープレフィックスを適用する、人気のAutoprefixerプラグインを利用します。しかし、アプリケーションに適したプラグインを自由に追加できます。最初に、NPMにより希望のプラグインをインストールし、それからwebpack.mix.jsの中から参照してください。

mix.sass('resources/assets/sass/app.scss', 'public/css')
   .options({
        postCss: [
            require('postcss-css-variables')()
        ]
   });

平文CSS

平文のCSSスタイルシートを一つのファイルへ結合したい場合は、stylesメソッドを使って下さい。

mix.styles([
    'public/css/vendor/normalize.css',
    'public/css/vendor/videojs.css'
], 'public/css/all.css');

URL処理

Laravel MixはWebpack上に構築されているため、Webpackのコンセプトを理解することが重要です。CSSコンパイルのため、Webpackはスタイルシート中のurl()呼び出しをリライトし、最適化します。最初は奇妙に聴こえるかもしれませんが、これは非常に強力な機能の一部です。画像への相対URLを含んだSassをコンパイルするのを想像してください。

.example {
    background: url('../images/example.png');
}

{note} 絶対パスをurl()へ指定しても、URL書き換えの対象外になります。たとえば、url('/images/thing.png')や、url('http://example.com/images/thing.png')は変更されません。

デフォルト動作として、Laravel MixとWebpackがexample.pngを見つけると、それをpublic/imagesフォルダへコピーします。それから、生成したスタイルシート中のurl()を書き換えます。

.example {
  background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e);
}

この機能は便利ですが、好きなようにフォルダ構造を設定することもできます。その場合、以下のようにurl()リライトを停止してください。

mix.sass('resources/assets/app/app.scss', 'public/css')
   .options({
      processCssUrls: false
   });

これをwebpack.mix.jsファイルへ追加することで、Mixはどんなurl()に一致することも、publicディレクトリへアセットをコピーすることもしなくなります。言い換えれば、コンパイル済みのCSSは、みなさんがタイプした内容そのままに見えるでしょう。

.example {
    background: url("../images/thing.png");
}

ソースマップ

デフォルトでは無効になっているため、webpack.mix.jsファイルでmix.sourceMaps()を呼び出すことで、ソースマップは有効になります。コンパイルコストと実行パフォーマンスコストはかかりますが、これによりコンパイル済みアセットを使用する時に、ブラウザの開発ツール向けの追加デバッグ情報が提供されます。

mix.js('resources/assets/js/app.js', 'public/js')
   .sourceMaps();

JavaScriptの操作

MixはECMAScript 2015のコンパイル、モジュール結合、圧縮やシンプルなJavaScriptファイルの結合などの操作を手助けする、多くの機能を提供しています。それだけでなく、設定をカスタマイズする必要は全く無く、全てがシームレスに動作します。

mix.js('resources/assets/js/app.js', 'public/js');

このコード一行で、以下の利点を享受できます。

  • ES2015記法
  • モジュール
  • .vueファイルのコンパイル
  • 開発環境向けに圧縮

ベンダの抽出

全ベンダーライブラリーをアプリケーション固有のJavaScriptとして結合することにより、発生する可能性がある欠点は、長期間のキャッシュが効きづらくなることです。たとえば、アプリケーションコードの一箇所を更新すれば、変更のないベンダーライブラリーの全てを再度ダウンロードするように、ブラウザに共用することになります。

アプリケーションのJavaScriptを頻繁に更新したい場合は、全ベンダーライブラリを専用のファイルへ分ける方法を考慮する必要があります。これにより、アプリケーションコードの変更は、大きなvendor.jsファイルのキャッシュへ影響しなくなります。Mixのextractメソッドで簡単に実現できます。

mix.js('resources/assets/js/app.js', 'public/js')
   .extract(['vue'])

extractメソッドは全ライブラリとモジュールの配列を受け取り、vendor.jsへ別にまとめます。上記のコードを例にすると、Mix配下のファイルを生成します。

  • public/js/manifest.js: Webpackマニフェストランタイム
  • public/js/vendor.js: ベンダーライブラリ
  • public/js/app.js: アプリケーションコード

JavaScriptエラーを起こさないために、以下のファイルは順番通りにロードしてください。

<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>

React

MixはReactをサポートするために、Babelプラグインを自動的にインストールします。使用開始するためには、mix.js()の呼び出しをmix.react()に置換してください。

mix.react('resources/assets/js/app.jsx', 'public/js');

実際には、Mixは最適なBabelプラグインとしてbabel-preset-reactをダウンロードし、取り込んでいます。

バニラJS

スタイルシートをmix.styles()により結合するのと同様に、多くのJavaScriptファイルをscripts()メソッドで結合し、圧縮できます。

mix.scripts([
    'public/js/admin.js',
    'public/js/dashboard.js'
], 'public/js/all.js');

この選択肢は特にWebpackによる操作を必要としないレガシープロジェクトに便利です。

{tip} mix.scripts()のちょっとしたバリエーションとしてmix.babel()があります。このメソッドはscriptsと同じ使い方です。しかし、結合したファイルはBabelにより編集され、ES2015コードを全てのブラウザーが理解できるバニラJavaScriptへ変換します。

Webpackカスタム設定

Laravel Mixはできるだけ素早く実行できるように、裏で事前に設定済みのwebpack.config.jsファイルを参照しています。時々、このファイルを変更する必要が起きるでしょう。参照する必要がある特別なローダやプラグインがあったり、Sassの代わりにStylusを使うのが好みであるかもしれません。そうした場合、2つの選択肢があります。

カスタム設定のマージ

Mixはオーバーライドする短いWebpack設定をマージできるように、便利なwebpackConfigメソッドを提供しています。これは、webpack.config.jsファイルをコピーし、独自バージョンをメンテナンスする必要がないため、やや魅力的な選択しです。webpackConfigメソッドは、適用したいWebpack限定設定を含むオブジェクトを引数に取ります。

mix.webpackConfig({
    resolve: {
        modules: [
            path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')
        ]
    }
});

カスタム設定ファイル

Webpack設置をすべてカスタマイズしたい場合は、node_modules/laravel-mix/setup/webpack.config.jsをプロジェクトのルートディレクトリへコピーしてください。次に、package.jsonファイル中の--config参照を全て新しくコピーした設定ファイルに変更します。カスタマイズにこのアプローチを取る場合は、Mixのwebpack.config.jsに対するアップストリームの機能変更を自分でカスタマイズするファイルへマージする必要があります。

ファイル/ディレクトリコピー

copyメソッドは、ファイルやディレクトリを新しい場所へコピーします。これはnode_modulesディレクトリ中の特定のアセットをpublicフォルダへ再配置する必要がある場合に便利です。

mix.copy('node_modules/foo/bar.css', 'public/css/bar.css');

ディレクトリのコピー時は、copyメソッドはディレクトリ構造をフラットにします。元の構造を保持したい場合は、copyDirectoryメソッドを代わりに使用してください。

mix.copyDirectory('assets/img', 'public/img');

バージョン付け/キャッシュ対策

多くの開発者は古いコードが提供され続けないように、新しいアセットがブラウザにロードされるよう、タイムスタンプやユニークなトークンをコンパイル済みのアセットへサフィックスとして付加しています。Mixでは、versionメソッドを使用し、これを処理できます。

versionメソッドは自動的に全コンパイルファイルのファイル名へ一意のハッシュを追加し、キャッシュを更新できるようにします。

mix.js('resources/assets/js/app.js', 'public/js')
   .version();

バージョン付けしたファイルを生成すると、皆さんは実際のファイル名がわからなくなります。そのため、適切なハッシュ付きアセットをロードするために、ビュー中でLaravelのグローバルmix関数を使う必要があります。mix関数はハッシュ付きファイルの最新の名前を自動的に判定します。

<link rel="stylesheet" href="">

バージョン付けしたファイルは、通常開発に必要ないため、npm run productionを実行するときのみ、バージョン付けするように指示したいと思うでしょう。

mix.js('resources/assets/js/app.js', 'public/js');

if (mix.inProduction()) {
    mix.version();
}

Browsersyncリロード

BrowserSyncは自動的にファイルの変更を監視し、手動で再読込しなくても変更をブラウザに反映してくれます。mix.browserSync()メソッドを呼び出し、有効にします。

mix.browserSync('my-domain.dev');

// もしくは

// https://browsersync.io/docs/options
mix.browserSync({
    proxy: 'my-domain.dev'
});

このメソッドには文字列(プロキシ)かオブジェクト(BrowserSync設定)のどちらかを渡します。次に、npm run watchコマンドにより、Webpackの開発サーバを起動します。これでスクリプトかPHPファイルを変更すると、すぐにページが再読込され、変更が反映されるのを目にするでしょう。

環境変数

.envファイルの中でキーにMIX_をプリフィックスとしてつけることで、環境変数をMixへ注入できます。

MIX_SENTRY_DSN_PUBLIC=http://example.com

.envファイルで定義すると、process.envオブジェクトを通じてアクセスできるようになります。watchタスク実行中に、その値が変化した場合は、タスクを再起動する必要があります。

process.env.MIX_SENTRY_DSN_PUBLIC

通知

可能な場合、Mixは自動的に各バンドルをOS通知で表示します。これにより、コンパイルが成功したのか、失敗したのか、即座にフィードバックが得られます。しかし、こうした通知を無効にしたい場合もあるでしょう。一例は、実働サーバでMixを起動する場合です。disableNotificationsメソッドにより、通知を無効にできます。

mix.disableNotifications();