【Laravel】webpack.mix.jsのglob.syncとは何か？実例で使い方を説明。

Laravelのコンパイラー、webpack.mix.jsで使われているglob.syncについて。

```js:例（webpack.mix.js）
glob.sync('resources/js/*.js').map(function(file) {
  mix.js(file, 'public/js').version()
});
```

##globとは？
npmのパッケージの一つで、**指定したパターンにマッチしたファイル名を抽出する**機能。

例えば、resourcesディレクトリ配下にある、末尾が.jsのファイルをコンパイルしたい場合に、globを使うと完結に記述することができる。ファイル名を変更にも対応することができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/1697641a-95ff-6298-f5a5-a09c13f86b8a.png)

・[npmjs公式 glob](https://www.npmjs.com/package/glob)


<br>
##globの使い方
###1. globのインストール

```:インストール
$ npm i glob
```

###2. globの読み込み
globを使いたいjsファイルの冒頭に以下を記述。

```js:.js
var glob = require("glob")
```

###3. globの使用

・`glob("パターン"[, options], function(er, files){ 処理 })`

- optionは任意
- パターンは相対パスで記述
- パターンの記述がない場合は`"**/*.js"`とみなす。

指定したパターンにマッチしたファイル名を抽出し、処理を実行した結果を返す。



<br>
###4. パターン

| 記号 | 意味 |
|:-:|:--|
| *  | ワイルドカード。0個以上の文字  |
| ?  | 1文字  |
| [...] | １文字の範囲を絞る。[a-z], [1-9]など。正規表現と同じ  |
| !(pattern1|pattern2|pattern3) |  以外 |
| {...}  | セット。 a{/b/c, bcd}なら、a/b/cかabcdがマッチする  |



<br>
##glob.sync
globのsync関数を使うと、パターンにマッチしたファイル名を戻り値として返す。

`glob.sync(pattern, [options])`

```js:例.js
glob.sync('resources/*.scss')
```

例えば、上記であれば、resoucrces配下のscssファイルを配列として次の処理に渡す。



<br>
###glob()とglob.sync()の違い
globとglob.syncの違いは処理結果。globはコールバック関数で処理を記述するが、glob.syncはパターンにマッチした内容をそのまま返す。


<br>
##冒頭のLaravel Mixのコンパイル処理の内容
冒頭で例として紹介したwebpack.mix.jsの記述内容を読み解いてみる。

```js:例（webpack.mix.js）
glob.sync('resources/js/*.js').map(function(file) {
  mix.js(file, 'public/js').version()
});
```

処理は大きく4つに別れる

1. glob.sync
2. map
3. mix.js
4. version

###1. glob.sync

```js:
glob.sync('resources/js/*.js')
```

globモジュールのsync関数を使って、resources/jsディレクトリ配下にある拡張子.jsのファイルを配列として抜き出す。

戻り値の例：　`[aaa.js, bbb.js, ccc.js]`


###2. map
map関数で渡された配列の要素一つ一つに処理を施す。

・`map(function(変数){処理})` 

>または、`map(変数 => 処理)`

```js:
map(function(file) {
  処理
})
```

渡されたデータを変数fileとして処理を実行する。


###3. mix.js
mix.jsでコンパイルを実行する。

・`mix.js('ファイルパス', 'コンパイル後のディレクトリパス')`

指定したファイルを、コンパイルし指定したディレクトリに出力する。

```js:
mix.js(file, 'public/js')
```

渡されたデータ(例：aaa.js)をコンパイルし、public/js/aaa.jsとして保存する。


###4. version
キャッシュ対策のため、version関数でバージョン付けをする。

Laravel Mixではversionメソッドを使うと、**コンパイルしたファイルのすべてに一意のハッシュ名を付与**し、キャッシュを更新するようにする。

呼び出し時に**`mix`関数を使うことで、Laravelが一番新しいファイルを自動で判定**する。


**▼例**

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

```php:blade.php
<link rel="stylesheet" href="{{ mix('/css/app.css') }}">
```

バージョン付けしたファイルは開発には不要なため、使うのは本番環境。


・[Laravel8.x アセットのコンパイル](https://readouble.com/laravel/8.x/ja/mix.html)



<br>
##実例２ scssファイルのコンパイル処理

```js:
glob.sync('resources/sass/*.scss').map(function(file) {
  mix.sass(file, 'public/css')
  .options({
    processCssUrls: false,
    postCss: [
      require('autoprefixer')({ grid: true })
    ]
  })
  .version()
})
```

###1. glob.sync

```js:
glob.sync('resources/sass/*.scss')
```

resources/sassディレクトリ配下の拡張子scssファイルを配列として抽出。


###2. map

```js:
.map(function(file) {
 処理
})
```

受け取ったファイルパス＆ファイル名を一つづつ処理。


###3. mix

```js:
mix.sass(file, 'public/css')
```

抽出したファイルをコンパイルし、public/css配下に出力。


###4. option
Laravel Mixのoptionメソッドを使うことで、コンパイル後のcssファイルにpostCSSを適用できる。

```js:
.options({
    processCssUrls: false,
    postCss: [
      require('autoprefixer')({ grid: true })
    ]
  })
```

ここでは`autoprefixer`を適用。


####autoprefixerとは？
ベンダープレフィックスを自動で適用してくれるpostCSSの便利プラグイン。

```js:
postCss: [
      require('autoprefixer')({ grid: true })
    ]
```

postCSSのautoprefixerプラグインを有効にする。`({ grid: true })`をつけることで、IE11で`display: grid`の処理を読み込めるようにする。

（参考）[postCSSとautoprefixerについて](https://qiita.com/yuta-38/items/47c7c1a305ce3d152737)


<br>
####processCssUrls: false
webpackは、cssにurlの記載があると、指定したファイルを探し出してpublic/imagesにコピーし、生成したcssファイルの中のurlを書き換える、自動コピーリライト機能がついている。

画像の指定がとても簡単になるが、コンパイル後のファイルからはどこを指しているのかわからなくなってしまうため、ここではこの機能をオフ（false）にしている。

(参考)[Laravel8.x アセットのコンパイル](https://readouble.com/laravel/8.x/ja/mix.html)



<br>
###5. version
キャッシュ対策のため、version関数でバージョン付けをする。

Laravel Mixではversionメソッドを使うと、**コンパイルしたファイルのすべてに一意のハッシュ名を付与**し、キャッシュを更新するようにする。

呼び出し時に**`mix`関数を使うことで、Laravelが一番新しいファイルを自動で判定**する。

処理内容は以上となる。



<br>
##補足
autoprefixerなどpostCSSのプラグインを使うには、事前にnpmでインストールする必要がある。

```
$ npm i autoprefixer --save-dev
```

ローカルのみにインストールする場合は`--save-dev`オプションをつける。