イントロダクション
Laravel Mixは多くの一般的なCSSとJavaScriptのプリプロセッサを使用し、Laravelアプリケーションために、構築過程をwebpackでスラスラと定義できるAPIを提供しています。シンプルなメソッドチェーンを使用しているため、アセットパイプラインを流暢に定義できます。例を見てください。
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
webpackやアセットのコンパイルを始めようとして、混乱と圧倒を感じているならLaravel Mixを気に入ってもらえるでしょう。しかし、アプリケーションの開発時に必要だというわけではありません。どんなアセットパイプラインツールを使用してもかまいませんし、使わなくても良いのです。
インストールと準備
Nodeのインストール
Mixを始める前、最初に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/less/app.less', 'public/css');
複数のファイルをコンパイルするには、less
メソッドを複数回呼び出します。
mix.less('resources/less/app.less', 'public/css')
.less('resources/less/admin.less', 'public/css');
コンパイル済みのCSSのファイル名をカスタマイズしたい場合は、less
の第2引数にファイルのフルパスを指定してください。
mix.less('resources/less/app.less', 'public/stylesheets/styles.css');
裏で動作しているLessプラグインのオプションをオーバーライドする必要が起きたら、mix.less()
の第3引数にオブジェクトを渡してください。
mix.less('resources/less/app.less', 'public/css', {
strictMath: true
});
Sass
sass
メソッドは、SassをCSSへコンパイルします。次のように使用します。
mix.sass('resources/sass/app.scss', 'public/css');
less
メソッドと同様に、複数のSassファイルを別々のCSSファイルへコンパイルできますし、結果のCSSの出力ディレクトリをカスタマイズ可能です。
mix.sass('resources/sass/app.sass', 'public/css')
.sass('resources/sass/admin.sass', 'public/css/admin');
さらに、Node-Sassプラグインオプションを第3引数に指定できます。
mix.sass('resources/sass/app.sass', 'public/css', {
precision: 5
});
Stylus
LessやSassと同様に、stylus
メソッドにより、StylusをCSSへコンパイルできます。
mix.stylus('resources/stylus/app.styl', 'public/css');
さらに、Ruptureのような、追加のStylusプラグインをインストールすることもできます。最初に、NPM(npm install rupture
)による質問でプラグインをインストールし、それからmix.stylus()
の中で呼び出してください。
mix.stylus('resources/stylus/app.styl', 'public/css', {
use: [
require('rupture')()
]
});
PostCSS
強力なCSS加工ツールであるPostCSSも、Laravel
Mixには最初から含まれています。デフォルトでは、自動的に必要なCSS3ベンダープレフィックスを適用する、人気のAutoprefixerプラグインを利用します。しかし、アプリケーションに適したプラグインを自由に追加できます。最初に、NPMにより希望のプラグインをインストールし、それからwebpack.mix.js
の中から参照してください。
mix.sass('resources/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/sass/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/js/app.js', 'public/js')
.sourceMaps();
ソースマップのスタイル
webpackはさまざまなソースマップスタイルを提供しています。Mixはソースマッピングスタイルのデフォルトとして、ブルド時間の早い
eval-source-map
をセットしています。マッピングスタイルを変更したい場合は、
sourceMaps
メソッドを使用してください。
let productionSourceMaps = false;
mix.js('resources/js/app.js', 'public/js')
.sourceMaps(productionSourceMaps, 'source-map');
JavaScriptの操作
MixはECMAScript 2015のコンパイル、モジュール結合、圧縮やJavaScriptファイルの結合などの操作を手助けする、多くの機能を提供しています。それだけでなく、設定をカスタマイズする必要はまったく無く、すべてがシームレスに動作します。
mix.js('resources/js/app.js', 'public/js');
このコード一行で、以下の利点を享受できます。
- ES2015記法
- モジュール
.vue
ファイルのコンパイル- 開発環境向けに圧縮
ベンダの抽出
すべてのアプリケーション固有のJavaScriptとベンダーライブラリを結合することにより、発生する可能性がある欠点は、長期間のキャッシュが効きづらくなることです。たとえば、アプリケーションコードの一箇所を更新すれば、変更のないベンダーライブラリーのすべてを再度ダウンロードするように、ブラウザに強要します。
アプリケーションのJavaScriptを頻繁に更新したい場合は、全ベンダーライブラリを専用のファイルへ分ける方法を考慮する必要があります。これにより、アプリケーションコードの変更は、大きなvendor.js
ファイルのキャッシュへ影響しなくなります。Mixのextract
メソッドで簡単に実現できます。
mix.js('resources/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/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('resources/img', 'public/img');
バージョン付け/キャッシュ対策
多くの開発者は古いコードが提供され続けないように、新しいアセットがブラウザにロードされるよう、タイムスタンプやユニークなトークンをコンパイル済みのアセットへサフィックスとして付加しています。Mixでは、version
メソッドを使用し、これを処理できます。
version
メソッドは、キャッシュを簡単に破壊できるようにするため、コンパイル済みファイルのファイル名に一意のハッシュを自動的に付け加えます。
mix.js('resources/js/app.js', 'public/js')
.version();
バージョン付されたファイルを生成した後は、適切にバージョン付けされたアセットのURLを生成するため、Laravelのグローバルmix
関数をビューの中で使用してください。
<script src="{{ mix('/js/app.js') }}"></script>
バージョン付けしたファイルは、通常開発に必要ないため、npm run production
を実行するときのみ、バージョン付けするように指示したいと思うでしょう。
mix.js('resources/js/app.js', 'public/js');
if (mix.inProduction()) {
mix.version();
}
MixのベースURLのカスタマイズ
アプリケーションから独立して、MixがコンパイルしたアセットをCDNへデプロイしている場合は、mix
関数が生成するベースURLを変更する必要があります。そのためには、config/app.php
設定ファイルへmix_url
設定オプションを追加してください。
'mix_url' => env('MIX_ASSET_URL', null)
MixのURLを設定後、mix
関数はアセットへのURLを生成する場合に、設定したURLを使用します。
https://cdn.example.com/js/app.js?id=1964becbdd96414518cd
Browsersyncリロード
BrowserSyncは自動的にファイルの変更を監視し、手動で再読込しなくても変更をブラウザに反映してくれます。mix.browserSync()
メソッドを呼び出し、有効にします。
mix.browserSync('my-domain.test');
// もしくは
// https://browsersync.io/docs/options
mix.browserSync({
proxy: 'my-domain.test'
});
このメソッドには文字列(プロキシ)かオブジェクト(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();