Laravel Mix のすすめ

webpack
公開日:
更新日:

素の CSS を手書きしたり、いちいちベンダープレフィックスを付けたりしている方へ

Laravel Mix とは

webpack を簡単に使えるようにしてくれる奴です。以下のようなことができます。

  • CSS の機能を拡張した Sass で書かれたコードを、ブラウザが理解できる CSS に変換する
  • ベンダープレフィックスが必要な CSS を判別して、自動的に付与する
  • ES6 で書かれた JS を、IE で実行できる ES5 のコードに変換する
  • コードの変更を監視して、自動的にブラウザを更新する

Laravel という PHP フレームワークの名前が付いていますが、Laravel を使わない(スタンドアローン)プロジェクトでも使えます。

Nuxt.js など、もともと上記のような機能があるフレームワークで開発する場合は、こちらを使う必要はありません。

インストール

Laravel Mix(以下 Mix)は、npm を使ってインストールします。

以下のコマンドを実行して、バージョンが表示されるか確認します。

$ node -v
v14.16.0
$ npm -v
6.14.11

コマンドがないと怒られた方は、nodebrew を使うなり直にインストールするなりして、Node.js を使えるようにしてください。

Node.js のバージョン違いで動かなくなるコードがあったりもするので、個人的には nodebrew でのインストールをおすすめします。

Windows で nodebrew を使いたい方は、Windows で Linux 環境を作るという記事で説明しています。

npm が使えることが確認できたら、以下のコマンドで Mix をインストールします。

インストールが終わったら、設定ファイルを作成します。

$ npm i -D laravel-mix
$ touch webpack.mix.js

使い方

作成した webpack.mix.js ファイルに処理したいタスクを書いていきます。

Mix 本体をインポートしたら、あとはやりたいことをメソッドチェーンで書くだけです。

// webpack.mix.js
const mix = require('laravel-mix')

mix
.sass('resources/sass/app.scss', 'public/css/hoge.css')
.babel('resources/js/app.js', 'public/js/piyo.js')

設定ファイルが書けたら、以下のコマンドで実行します。

$ npx mix       #コンパイルのみ実行する
$ npx mix watch #ファイルの変更を監視して自動コンパイルする(Ctrl + C で終了)
$ npx mix -p    #コンパイルを実行し、CSS や JS を圧縮する

mix.sass()

.sass() は、Sass や Scss で書かれたファイルを、ブラウザが解釈できる普通の CSS に変換します。

複数の CSS を書き出すには、必要な数だけ .sass を実行します。

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

mix.babel()

.babel() は、指定されたファイルを結合して、さらに Babel で変換します。

ES6 で書いた新しめのコードを、IE 11 などでも解釈できる ES5 コードに変換できます。

Babel による変換が不要な場合は、.scripts() を使います。

mix
.babel([
  'resources/js/foo.js',
  'resources/js/bar.js',
], 'public/js/foobar.js')
.scripts([
  'node_modules/siema/dist/siema.min.js',
], 'public/js/vendor.js')

mix.browserSync()

npx mix watch の時に、指定した URL をブラウザで開き、コンパイルする度に再読込します。

mix.browserSync('https://www.google.com/?hl=ja')

スタティック(HTML, CSS, JS のみ)なサイトを作っている場合は、proxy をオフにして、サイトのルートとなるフォルダを指定します。

また、files に glob 形式のパスを渡すことで、監視するファイルを指定できます。

mix.browserSync({
  server: 'public', //public フォルダがサイトのルートの場合
  files: ['public/**/*'],
  proxy: false,
})

mix.options()

コンパイル時の動作を設定できます。

mix.options({
  processCssUrls: false,
  autoprefixer: {
    grid: 'autoplace',
  },
})

processCssUrls

CSS 内に url(../relative/path) の記述があったら、その画像を dist/images フォルダにコピーして、キャッシュ対策に適当な GET パラメータを付けた URL に変換するという機能です。デフォルトでは true なので、この動作が不要な場合は false に設定しましょう。

autoprefixer

Autoprefixer に渡すオプションを指定できます。よく grid: true という設定が紹介されていますが、grid に設定するのは 'autoplace', 'no-autoplace', false の何れかです。

grid: 'autoplace'

grid-template-columns / rows が指定された場合に、IE 11 でも表示できるように CSS を生成します。

columns / rows ともに指定する必要があるので、アイテム数の決まったグリッドしか再現できません。

gap (grid-gap) の指定がある場合は、何も置かないグリッドを用意して再現してくれます。

/* before */
.grid-autoplace {
  display: grid;
  grid-gap: 3rem 1.5rem;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, auto);
}

/* after */
.grid-autoplace {
  display: -ms-grid;
  display: grid;
  grid-gap3rem 1.5rem;
  -ms-grid-columns1fr 1.5rem 1fr 1.5rem 1fr;
  grid-template-columns: repeat(31fr);
  -ms-grid-rows: auto 3rem auto;
  grid-template-rows: repeat(2, auto);
}
.grid-autoplace > *:nth-child(1) {
  -ms-grid-row1;
  -ms-grid-column1;
}
.grid-autoplace > *:nth-child(2) {
  -ms-grid-row1;
  -ms-grid-column3;
}
.grid-autoplace > *:nth-child(3) {
  -ms-grid-row1;
  -ms-grid-column5;
}
.grid-autoplace > *:nth-child(4) {
  -ms-grid-row3;
  -ms-grid-column1;
}
.grid-autoplace > *:nth-child(5) {
  -ms-grid-row3;
  -ms-grid-column3;
}
.grid-autoplace > *:nth-child(6) {
  -ms-grid-row3;
  -ms-grid-column5;
}
grid: 'no-autoplace'

grid-template と grid-area の指定があるグリッドのみ処理します。こちらも gap (grid-gap) 含めて再現してくれます。

/* before */
.grid-no-autoplace {
  display: grid;
  grid-gap: 1rem;
  grid-template:
  "gna-1 gna-1 gna-2" auto
  "gna-4 gna-5 gna-2" 1fr
  "gna-4 gna-3 gna-3" auto
  /1fr   1fr   1fr;

  .item-1 { grid-area: gna-1 }
  .item-2 { grid-area: gna-2 }
  .item-3 { grid-area: gna-3 }
  .item-4 { grid-area: gna-4 }
  .item-5 { grid-area: gna-5 }
}

/* after */
.grid-no-autoplace {
  display: -ms-grid;
  display: grid;
  grid-gap1rem;
  -ms-grid-rows: auto 1rem 1fr 1rem auto;
  -ms-grid-columns1fr 1rem 1fr 1rem 1fr;
      grid-template"gna-1 gna-1 gna-2" auto "gna-4 gna-5 gna-2" 1fr "gna-4 gna-3 gna-3" auto/1fr 1fr 1fr;
}
.grid-no-autoplace .item-1 {
  -ms-grid-row1;
  -ms-grid-column1;
  -ms-grid-column-span3;
  grid-area: gna-1;
}
.grid-no-autoplace .item-2 {
  -ms-grid-row1;
  -ms-grid-row-span3;
  -ms-grid-column5;
  grid-area: gna-2;
}
.grid-no-autoplace .item-3 {
  -ms-grid-row5;
  -ms-grid-column3;
  -ms-grid-column-span3;
  grid-area: gna-3;
}
.grid-no-autoplace .item-4 {
  -ms-grid-row3;
  -ms-grid-row-span3;
  -ms-grid-column1;
  grid-area: gna-4;
}
.grid-no-autoplace .item-5 {
  -ms-grid-row3;
  -ms-grid-column3;
  grid-area: gna-5;
}
grid: false

グリッドに関する変換を一切行ないません。