【Laravel】SASS(scss)の使い方実例。Laravel Mixを使って簡単にコンパイルする方法

**Laravel Mix**というツールを使うとSassをCSSにコンパイルすることができる。

出力先のディレクトリ設定も超簡単。


##目次

1. [Laravel Mixの機能](#laravel-mixの機能)
2. [Node.jsとnpmのインストール](#1-nodejsとnpmのインストール)
3. [Laravel Mixのインストール](#2-laravel-mixのインストール)
4. [コンパイル先の指定](#3-コンパイル先の指定)
5. [ファイルの作成](#4-ファイルの作成)
6. [コンパイルの実行](#5-コンパイルの実行)
7. [ブラウザに表示](#6-ブラウザに表示)
8. [変更反映の自動化](#7-変更反映の自動化)
9. [本番用のコンパイル](#8-本番用のコンパイル)
10. [URLの自動変換機能（オフにする方法も）](#9-urlの自動変換機能オフにする方法も)
11. [複数ファイルをワイルドカードで指定する](#10-複数ファイルをワイルドカードで指定する)




<br>
##Laravel Mixの機能
SassをCSSにコンパイルするだけでなく、**Less, Stylus, PostCSS**にも対応している。**複数のcssファイルを１つのcssファイルに統合**することもできる。

また、CSS以外にも**JSの圧縮、.vue（ビューJS）、.jsx（リアクトJS）などのコンパイル**にも対応している。

今回は、Sass -> CSS機能のみにフォーカス。


<br>
##コンパイル手順
###1. Node.jsとnpmのインストール

```インストール済みか確認
node -v 
#v12.18.3

npm -v
#6.14.8
```

バージョンが表示されればインストール済み。
ない場合は、[node.js公式ページ](https://nodejs.org/ja/download/)からダウンロード。


<br>
##2. Laravel Mixのインストール
Laravelのプロジェクトを作成した時点でルートディレクトリ直下に`package.json`が存在する。

ここにはnodeの依存パッケージが記述されており、以下コマンドで記載のパッケージをインストールする。

```
$npm install
```

<br>
`package-lock.json`が作成されたらインストール完了。このファイルはインストール済みのnpmパッケージが記載されている。（自動生成されるファイルなので編集しない！）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/5ecede8a-2cf4-9cc7-99ed-412e95697f9b.png)
laravel mixもインストールされている。


>`$npm install [パッケージ名]`で指定したパッケージをインストールする。
パッケージ名を指定しない場合は、package.jsonに従ってインストールを行う。


<br>
##3. コンパイル先の指定

デフォルトでルートディレクトリに`webpack.mix.js`がある。この中にコンパイルする形式や出力先の情報を記述する。

・`mix.メソッド名('コンパイルするファイルパス', '出力先');`

```js:webpack.mix.js（デフォルト）
const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]);
```

↓　以下に変更

``````js:webpack.mix.js
mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');
```

resources > sass　の app.scssファイルをコンパイルして、public > css　配下に出力する。


<br>
**▼（補足）別の指定方法**
メソッドチェーンでつなげず、別々に記述しても機能する。

```js:php:webpack.mix.js
mix.js('resources/js/app.js', 'public/js');
mix.sass('resources/sass/app.scss', 'public/css');
```



<br>
##4. ファイルの作成
実際にコンパイルするファイルを作成する。

###app.scssファイルの作成
resources > sass > app.scss

```scss:app.scss
h1 {
  color: skyblue;
}
```

テストなのでシンプルに、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/63e4ce7b-8e0e-9d1b-f970-bd16e9cbe050.png)




###ビュー
resorces > views > for-scss.blade.php

```php:for-scss.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="{{ asset('css/app.css') }}">
</head>
<body>
  <div>
    <h1>SCSSのテスト</h1>
  </div>
</body>
</html>
```

**▼cssファイルの読み込み**
コンパイルされたcssファイルを読み込む記述を記載する。

```html:
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
```
URLの呼び出しはassetヘルパー関数を使用。


（参考）[assetヘルパー関数とは？](https://qiita.com/yuta-38/items/ad72bb3b4350a4791afd)


<br>
###ルーティング
routes > web.php

```php:web.php
Route::get('scss', function () {
    return view('for-scss');
});
```



<br>
##5. コンパイルの実行
以下コマンドでコンパイルが開始する。

```
npm run dev
```



<br>
**▼実行例**

```
$ npm run dev

99% done plugins BuildOutputPlugin
                         
   Laravel Mix v6.0.10   
                         
✔ Compiled Successfully in 1143ms
┌───────────────────────────────────────────────────────┬──────────┐
│                                                  File │ Size     │
├───────────────────────────────────────────────────────┼──────────┤
│                                            /js/app.js │ 596 KiB  │
│                                           css/app.css │ 25 bytes │
└───────────────────────────────────────────────────────┴──────────┘
```

webpack.mix.jsの指示通り、jsファイルとcssファイルが作成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/8c6bfc57-1b58-4190-29ab-bd5ec81dbb5a.png)

###コンパイル結果の確認
生成されたapp.cssを確認する。今回はapp.scssと同じ内容が記述されていればOK。

```css:app.css
h1 {
  color: skyblue;
}
```


<br>
##6. ブラウザに表示
サーバーを起動する。

```:
php artisan serve
```

<br>
URLを入力。http://127.0.0.1:8000/scss

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/03b02c40-3649-8c01-5162-4aa36db57de7.png)|
|:--|

狙い通りコンパイル後のCSSが反映されている。



<br>
##7. 変更反映の自動化
`$ npm run watch`を実行すると、指定したコンパイル元のファイルに変更があった場合に、自動でコンパイルを実行する。

```
$ npm run watch

> @ watch /Users/s01386/projects/laravel/test-pj
> mix watch
```

<br>
`ctrl + c`でサーバーを停止すれば自動監視（mix watch）も停止する。



<br>
##8. 本番用のコンパイル
`$npm run production`を実行すると、本番用の圧縮したファイルを出力してくれる。

圧縮版は、改行やスペース、コメントアウトなどを削除したもの。

```:
$ npm run production

> @ production /Users/s01386/projects/laravel/test-pj
> mix --production

99% done plugins BuildOutputPlugin


                         
   Laravel Mix v6.0.10   
                         

✔ Compiled Successfully in 5416ms
┌───────────────────────────────────────────────────────┬──────────┐
│                                                  File │ Size     │
├───────────────────────────────────────────────────────┼──────────┤
│                                            /js/app.js │ 84.8 KiB │
│                                           css/app.css │ 14 bytes │
└───────────────────────────────────────────────────────┴──────────┘
```

**▼出力されたファイル**

```css:app.css
h1{color:red}
```

改行やスペースが削除されている。


<br>
##9. URLの自動変換機能（オフにする方法も）
Laravel Mixの便利機能の一つで、urlで画像リソースを指定した場合に、対象のファイルを`public/images`フォルダにコピーし、コンパイル後のURLをコピー後のファイルのパスに変更する機能がある。

**▼例**

```scss:css:app.scss
.example {
  background: url('../../public/img/cat3.png');
}
```

↓　コンパイル

```
$ npm run dev

99% done plugins BuildOutputPlugin
                         
   Laravel Mix v6.0.10   
                         
✔ Compiled Successfully in 888ms
┌──────────────────────────────────────────────────────┬───────────┐
│                                                 File │ Size      │
├──────────────────────────────────────────────────────┼───────────┤
│                                           /js/app.js │ 596 KiB   │
│                                          css/app.css │ 105 bytes │
│     images/cat3.png?204c4068c53d4775b6e9cb23998276cb │ 158 KiB   │
└──────────────────────────────────────────────────────┴───────────┘
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/06581e3d-033e-11a2-db7a-351c04cfc833.png)


**▼コンパイル後のCSSファイル**

```scss:css:app.scss
.example {
  background: url(/images/cat3.png?204c4068c53d4775b6e9cb23998276cb);
}
```

画像がパラメータで指定されている。（画像名にパラメータはついていない）


###自動コピー＆URL変換機能をオフにする
この機能をオフにして、指定したURLをそのままコンパイルしたい場合は、`webpack.mix.js`内にオプションメソッドで以下を追記する。

```js:webpack.mix.js
.options({
      processCssUrls: false
   });
```

<br>
**▼実際のコード例**

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





<br>
##10. 複数ファイルをワイルドカードで指定する
scssファイルがいくつもある場合、コンパイル元のファイルと出力先を個別に設定するのは手間。

npmのパッケージの一つである`glob`を使うことでファイルをワイルドカードで指定できる。


```js:
const mix = require('laravel-mix');
const glob = require('glob');

glob.sync('resources/sass/*.scss').map(function(file) {
  mix.sass(file, 'public/css');
});
```

・冒頭に`const glob = require('glob');`を記述。


<br>
**▼scssファイルが多いPJ例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/aea8a86a-4e98-9ab5-bbc6-ed0ec27c3992.png)


<br>
**▼jsのコンパイルもグローバル指定した場合の例**

```js:webpack.mix.js
const mix = require('laravel-mix');
const glob = require('glob');

glob.sync('resources/sass/*.scss').map(function (file) {
  mix.sass(file, 'public/css').options({
    processCssUrls: false,
  });
});

glob.sync('resources/js/*.js').map(function (file) {
  mix.js(file, 'public/js');
});
```

 


<br>
##参考リンク
[Laravel公式 Laravel Mix アセットのコンパイル](https://readouble.com/laravel/8.x/ja/mix.html)