【簡単】laravel-mixを使って爆速マークアップ環境を構築する方法【laravel外で使う】

こんにちは!のせっちです。

今回は、laravel-mixを使った、マークアップ環境の構築を解説します。
当ブログでは、gulp x webpackを使ったマークアップ環境の構築方法を解説していますが、今回はlaravel-mixのみで構築します。

laravel-mixとはいえ、laravelは不要で単独で使うことができます。

当記事で解説した内容はgithubリポジトリを公開しております。ご自由にどうぞ。
内容が微妙に違う場合は、githubが最新です。

laravel-mixとは?

ざっくり説明すると、

  • アセットをコンパイル、バンドルするツール。
  • Laravelのためのツールだが、単独で使うことも可能。
  • webpackのラッパーで、webpackより簡単に書ける。

以下のような方にはピッタリなツールです。

  • Gulp環境を持っているが、更新されていないパッケージが多いのが気になる。
  • webpackで環境構築したいが、複雑でよくわからない。
  • Gulp x webpackの組み合わせではエラー対処なのが複雑になるので一本のツールで完結したい。
  • とにかく簡単に構築できるものをちょうだい!

公式のドキュメントでとても簡潔に説明されていますが、実はgithubのreadmeを参考にするのがオススメです。(npm scirptあたりでエラーでます。)

本記事のゴール

下記の環境を設定します。

  • SCSSのコンパイル
  • jsのバンドル
  • jQuery($)を使えるようにする
  • ローカルサーバーを起動

早速作ってみる

前提として、nodeが必要です。

推奨版』をダウンロードしましょう。

node.jsがダンロードできたら、
ターミナルを開いて、下記を入力します。

mkdir my-app && cd my-app
npm init -y
npm install laravel-mix --save-dev

簡単に解説すると、

mkdir my-app && cd my-app

my-appというディレクトリを作成(mkdir)し、my-appに移動(cd)

npm init -y

package.jsonができます。

npm install laravel-mix --save-dev

laravel-mixをインストールします。

次に、設定ファイル(webpack.mix.js)を作ります。
ターミナルに下記を入力してください。

touch webpack.mix.js

こういうディレクトリ構成になります。

では、jsのコンパイルをやってみましょう。
src/app.jsからdist/bundle.jsにコンパイルします。

webpack.mix.jsに下記を記述します。

const mix = require('laravel-mix');

mix.setResourceRoot('dist');

mix.js('src/app.js', 'dist');

src/app.jsから、distフォルダに書き出す設定を書きました。

src/app.jsを作成して、試しにスクリプトを書きます。(なんでもOK)

alert('hello');

ここまでできたら、ターミナルで下記を実行します。

npx mix
npx mixを叩くとdist/app.jsができる。

そうすると、dist/app.jsができました。たったこれだけで、コンパイルできるんですね。

dist/app.jsにコンパイルされている。

mix-manifest.jsonというファイルもできますが、今回は使いません。

SCSSのコンパイル設定をしていく

scssファイルのコンパイルも簡単です。

const mix = require('laravel-mix');

mix.setResourceRoot('dist');

mix
  .js('src/js/app.js', 'dist/js'); // パスを変更しています。

// 下記を追加
mix
  .sass('src/scss/app.scss', 'dist/css/')
  .options({
    processCssUrls: false,
    autoprefixer: {
      options: {
        grid: true,
      }
    },
  });

一気に書きました。下記のような設定になっています。

  • src/scss/app.scssからコンパイルし、dist/css/app.cssを作成
  • processCssUrls: false でurl()の変換をさせない
  • autoprefixerでベンダープレフィックスを付与。(grid: trueでIE11でのgrid使用できるように)

autoprefixerの設定(browserslist)は、webpack.mix.jsに書かず(非推奨なので)package.jsonか、.browserslistrcに記述します。お好きな方でどうぞ。

書き方が微妙に違います。

last 1 version,
IE 11,
Android >= 6
"browserslist": [
    "last 1 version",
    "IE 11",
    "Android >= 6"
  ]

では、コンパイルしてみましょう。
ベンダープレフィックスが付きそうなものを書いてみます。

.hoge{
  transform: translate(50%, 50%);
}

そしてnpxコマンド

npx mix

結果、

.hoge {
  -webkit-transform: translate(50%, 50%);
          transform: translate(50%, 50%);
}

よさそうです。

足りないライブラリを勝手にインストールしてくれる。

npx mixをしたときにSCSSのコンパイルに必要なライブラリを勝手にインストールしてくれたと思います。エラーを返さずに勝手に解決してくれるので便利ですよね!

npx mix時に必要なライブラリをインストールしてくれる。

ダウンロードされなかった場合は、ターミナルで下記を入力します。

npm i -D sass-loader postcss

おまけ:laravel-mixで使うnpxコマンド3種

npxはnodeをインストールすると自動で使えるようになるコマンドです。

laravel-mixでは下記を使います。

  • npx mix : developmentモードでコンパイル
  • npx mix -p : productionモードでコンパイル
  • npx mix watch : watchモード(後ほど設定します)

SCSSを更に便利に(PostCssオプションを使う)

PostCssオプションを使って、SCSSのコンパイルを更に便利にしていきます。
今回の例では、下記を設定してみましょう。

  • 任意の順番に並べる(css-declaration-sorter)
  • メディアクエリ をまとめる(css-mqpacker)
  • カスタム変数を使えるように(postcss-custom-properties)

今回はパッケージを先にインストールします。

npm i -D css-mqpacker css-declaration-sorter postcss-custom-properties

npm i -Dはnpm install –save-devと同じです。

webpack.mix.jsにPostCssオプションを追加します。

const mix = require('laravel-mix');

mix.setResourceRoot('dist');

mix
  .js('src/js/app.js', 'dist/js');

mix
  .sass('src/scss/app.scss', 'dist/css/')
  .options({
    processCssUrls: false,
    autoprefixer: {
      options: {
        grid: true,
      }
    },
    // 下記を追加
    postCss: [
      require('css-mqpacker')(),
      require('css-declaration-sorter')({
        order: 'alphabetical' // smacss, concentric-css
      }),
      require('postcss-custom-properties')({
        preserve: false
    })
    ]
  });

ローカルサーバーを起動

ローカルサーバーを起動して、更新がある度に自動でリロードしてくれる機能を追加します。
これも数行追加するだけなので簡単です。

const mix = require('laravel-mix');

mix.setResourceRoot('dist');
// 下記を追加
mix.browserSync({
  server: {
    baseDir: '.',
    index: 'index.html'
  },
  port: 8081,
  proxy: false,
  files: '**/*'
});

// 省略

では、早速起動します。

index.htmlを用意して、何か適当に書いておいてください。

npx mix watch
足りないパッケージをインストールしてくれて、再度npx mix watch

はい、また足りないパッケージを勝手にインストールしてくれました。

その後、もう一度npx mix watchでローカルサーバーが起動します。

ダウンロードされなかった場合は、ターミナルで下記を入力します。

npm i -D browser-sync-webpack-plugin browser-sync

sourcemapsを作る

下記を追加するだけです。

const mix = require('laravel-mix');

mix.setResourceRoot('dist');
mix.setPublicPath('dist');
mix.webpackConfig({ devtool: "source-map" }); // 追加

mix
  .js('src/app.js', 'dist/js')
  .sourceMaps(); // 追加

mix
  .sass('src/scss/app.scss', 'dist/css/')
  .sourceMaps() // 追加

 // 省略

laravel-mixの標準機能なので、パッケージは不要です。

@importを手軽に

通常@importはファイル名まで指定しないといけないのですが、ワイルドカードを使って一気に読み込めるようにします。

npm i -D import-glob-loader

設定を追加します。

const mix = require('laravel-mix');

mix.setResourceRoot('dist');
mix.setPublicPath('dist');
mix.webpackConfig({ devtool: "source-map" });

mix.webpackConfig({ 
  devtool: "source-map",
  // 下記を追加
  module: {
    rules: [
      {
        test: /\.scss/,
        loader: 'import-glob-loader'
      }
    ]
  }
});

// 省略

これでscssファイルを一気に読み込めるようになりました。(下記のような感じ)

@import "setting/**";
@import "foundation/**";
@import "mixin/**";
@import "layout/**";
@import "component/**";
@import "project/**";
@import "utility/**";
@import "external/**";

こういう系で何かやりたいことを調べるときは、普通にググるよりもGithubの issueを調べるのはかなりオススメです。サクッと解決策が書かれていたりします。
import-glob-loaderについてもGithub issueから見つけました。
https://github.com/JeffreyWay/laravel-mix/issues/241

jQueryの$を使用可能にする。

下記を追加します。

const mix = require('laravel-mix');

mix
  .js('src/js/app.js', 'dist/js/')
  // 下記を追加
  .autoload({
     jquery: ['$', 'window.jQuery']
  })

// 省略

折角なのでjQueryを書いてみる。(飛ばしてOK)

折角なので、npmからjQueryをインストールして使えるようにしちゃいましょう。

npm i jquery

これで、jQueryを使う準備ができました。
何か書いてみましょう。

src/js/module/jquery.jsを作って、src/js/app.jsで読み込んでみます。

$(window).on('load', () => {
  console.log('hello');
});

$を使いたかっただけなので特に意味のないコードです。

これを、src/js/app.jsにimportします。

import './module/jquery';

では、サーバーを立ち上げてみて確認します。

npx mix watch

検証ツールからコンソールを開くと「hello」と表示されているはずです。

おまけ:mix-manifest.jsonを出力したくない場合

mix-manifest.jsonはcash busting時に使えるのですが、基本的にlaravel環境でないと使えない(mix関数が必要)ので、laravel外の環境では使わないかもしれません。

mix関数を自分で定義して使う方法があるようです。
(試したのですが、うまくできなかったのでわかる人はコッソリ教えてください… m(_ _)m )
https://github.com/JeffreyWay/laravel-mix/issues/1635

使わない人にとっては不要なので、mix-manifest.jsonを出力しない方法をご紹介します。

const mix = require('laravel-mix');
const fs = require('fs'); // 追加

mix
  .js('src/app.js', 'dist/js')
  .sourceMaps()
  // 下記を追加
  .then(() => {
    fs.unlinkSync('mix-manifest.json');
  });

mix-manifest.jsonを消して、もう一度npx mixしてみましょう!

rm -rf mix-manifest.json
npx mix

mix-manifest.jsonは書き出されなくなります。

最終的な設定ファイル

最終的にこうなりました。

const mix = require('laravel-mix');
const fs = require('fs');

mix.setResourceRoot('dist');

mix.webpackConfig({ 
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.scss/,
        loader: 'import-glob-loader'
      }
    ]
  }
});

mix.browserSync({
  server: {
    baseDir: '.',
    index: 'index.html'
  },
  port: 8081,
  proxy: false,
  files: '**/*'
});

mix
  .js('src/app.js', 'dist/js')
  .autoload({
    jquery: ['$', 'window.jQuery']
  })
  .sourceMaps()
  .then(() => {
    fs.unlinkSync('mix-manifest.json');
  });

mix
  .sass('src/scss/app.scss', 'dist/css/')
  .sourceMaps()
  .options({
    processCssUrls: false,
    autoprefixer: {
      options: {
        grid: true,
      }
    },
    postCss: [
      require('css-mqpacker'),
      require('css-declaration-sorter')({
        order: 'alphabetical'
      }),
      require('postcss-custom-properties')({
        preserve: false
    })
    ]
  });
{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "devDependencies": {
    "browser-sync": "^2.26.13",
    "browser-sync-webpack-plugin": "^2.2.2",
    "css-declaration-sorter": "^6.0.2",
    "import-glob-loader": "^1.1.0",
    "css-mqpacker": "^7.0.0",
    "laravel-mix": "^6.0.10",
    "postcss": "^8.2.4",
    "postcss-custom-properties": "^11.0.0",
    "sass": "^1.32.4",
    "sass-loader": "^8.0.2"
  },
  "dependencies": {
    "jquery": "^3.5.1"
  },
  "browserslist": [
    "last 1 version",
    "IE 11",
    "Android >= 6"
  ]
}

余計な記述は消しておきました。

設定は以上です。お疲れ様でした。

追記:object-fitのpolyfill付与を自動化する方法を解説しました。

下記の記事で、object-fitのpolyfillを自動付与する方法を解説しました。合わせてどうぞ!
object-fitはとても便利なcssですが、IEには対応していませんので、polyfillの設定が必要です。

まとめ

・laravel-mixを使うと短い記述でマークアップ環境を構築できる。
・説明はよくわからなかったけど使いたい、という人はgithubリポジトリをどうぞ。

この記事を書いた人

のせっち

福岡県出身。早稲田大学卒。創業100年の鉄鋼商社でバンコク駐在最年少抜擢。毎日擦り切れるまで働かなくても幸せに生きている人々を見てフリーランスになりました。
- WordPressが得意!
- 初心者向けGulp教材は購入者100部以上!