【sass】ファイルの更新を監視し自動でSassをビルド&ブラウザをリロードする環境を構築

# はじめに
この記事では、
①node-sassを使いSassファイルの更新を感知して、自動でcssにビルド
②BrowserSyncを使いhtml・css等のファイルの更新を監視して、自動でブラウザをリロード
してくれる環境を構築する方法を記載します。
パッケージ管理にはyarnを使います。

# 対象読者
- yarnを既にインストールしている方
- Macを利用している方（私が使用するのがMacのため）

# 私の環境
- OS: macOS Catalina Version 10.15.7
- yarn: 1.22.10
- node.js: 10.23.2

(21/05/03現在)

# 結論

```json:package.json
{
  "name": "copy_clipbord",
  "version": "1.0.0",
  "main": "index.js",
  "license": "ISC",
  "devDependencies": {
    "browser-sync": "^2.26.14",
    "node-sass": "^5.0.0",
    "npm-run-all": "^4.1.5"
  },
  "scripts": {
    "start"      : "run-p start:*",
    "start:sync" : "browser-sync start --server --files *.html css/*.css *.js",
    "start:sass" : "node-sass -w -r --output-style expanded css/style.scss css/style.css"
  }
}
```
上記を記述した`package.json`を該当ディレクトリにおいた状態でターミナルで

```
yarn
```
と実行すれば、今回構築するの環境に必要なパッケージがインストールできます。
まぁscriptに記載ある監視やビルドするファイルのディレクトリは修正が必要ですが。。

# 実際の作業

## 0.プロジェクトのディレクトリ(フォルダ)に移動
cdコマンドを使って作業するディレクトリまで移動します。

```
root/
  ┣━css/
  ┃  ┣━reset.css
  ┃  ┣━style.css
  ┃  ┗━style.scss
  ┃
  ┣━app.js
  ┣━index.html
  ┗━package.json
```

今回のディレクトリ構造はこんな感じを想定(適当


## 1.プロジェクト内にpackage.jsonを作成
以下のコマンドを実行して、まずpackage.jsonを作成します。
※既にプロジェクト内にpackage.jsonがある場合はこの作業はスキップしてください。

```:package.jsonを作成
yarn init
```

この時、なんかいろいろ訊かれますが、何も入力せずにエンターでOKです。
そうすると以下のような内容のjsonファイルが生成されると思います。

```json:package.json
{
  "name": "project名(ディレクトリ名)",
  "version": "1.0.0",
  "main": "index.js",
  "license": "ISC",
}
```

ここにいろいろインストールして情報を加えていきます。

## 2.必要なソフトをそれぞれインストール

### 2-1.yarnを使ってnode-sassをインストール
以下のコマンドを実行しnode-sassをインストール
開発環境のみで必要なので「-D」をつけて`devDependencies`としてインストールします。
※`devDependencies`について、[こちらの記事](https://qiita.com/chihiro/items/ca1529f9b3d016af53ec "【いまさらですが】package.jsonのdependenciesとdevDependencies")で詳しく解説してくれています。

```:node-sassをインストール
yarn add node-sass -D
```

### 2-2.yarnを使ってBrowserSyncをインストール
以下のコマンドを実行しBrowserSyncをインストール
こちらも「ｰD｣をつけて`devDependencies`としてインストールします。

```:BrowserSyncをインストール
yarn add ｂｒｏｗｓｅｒ−ｓｙｎｃ -D
```

### 2-3.yarnを使ってnpm-run-allをインストール
以下のコマンドを実行しnpm-run-allをインストール
こちらも「ｰD｣をつけて`devDependencies`としてインストールします。

```:npm-run-allをインストール
yarn add npm-run-all -D
```

npm-run-allは後々役に立ちますが、必須じゃないです。
特にMacの方は不要かも。

この時点でjsonファイルは以下のような感じになっているかと思います。

```json:package.json
{
  "name": "project名(ディレクトリ名)",
  "version": "1.0.0",
  "main": "index.js",
  "license": "ISC",
  "devDependencies": {
    "browser-sync": "^2.26.14",
    "node-sass": "^5.0.0",
    "npm-run-all": "^4.1.5"
  }
}
```
※各ソフトのバージョン("^2.26.14"とか)は違っても大丈夫です(たぶん

次からはscriptを作っていきます。

## 3.jsonにscriptsを記述

```json:package.json
{
  "name": "project名(ディレクトリ名)",
  "version": "1.0.0",
  "main": "index.js",
  "license": "ISC",
  "devDependencies": {
    "browser-sync": "^2.26.14",
    "node-sass": "^5.0.0",
    "npm-run-all": "^4.1.5"
  },
  "scripts": {
    "script名_1": "やってほしい作業_1",
    "script名_2": "やってほしい作業_2",
    ・・・
  }

}
```

上記の様な感じでscriptsを記述し、ターミナルで呼び出すことで実行できます。
実行するにはターミナルで下記のように記述します。

```:scripts実行
yarn run [script名]
```

「run」は省略しても実行できるようです。

今回は、冒頭で説明したように、
(1)node-sassでsassファイルを監視し(常駐させて)変更があったらcssファイルにビルド
(2)BrowserSyncでhtml・css等のファイルを監視し(常駐させて)変更があったらブラウザをリロード
というscriptを作成します。

なので、jsonファイルのscriptsは以下のようなイメージ

```json:package.jsonのscripts
"scripts": {
  "script_1": "sassファイルをcssファイルにビルド(node-sass)",
  "script_2": "ブラウザをリロード(BrowserSync)"
}
```

### 3-1.node-sassのscriptを記述

```json:node-sassのscripts
"scripts": {
  "watch-sass": "node-sass -w -r --output-style expanded css/style.scss css/style.css"
}
```

【解説】

```:nodeｰsass
node-sass [入力元(sassファイル)] [出力先(cssファイル)]
```
node-sassのscriptは上記のように書きます。
必要があればオプションを追記します。
今回使用するオプションは以下の通り。

- -w(オプション):「--watch」の略、常駐してディレクトリやファイルを監視してくれる
- -ｒ(オプション):「--recursive」の略、再帰的にディレクトリやファイルを監視してくれる
- --output-style：出力されるcssの形式を選択(nested | expanded | compact | compressed)

`yarn node-sass --help`と入力するとオプション等の一覧が出るので、確認してみてください。

### 3-2.BrowserSyncのscriptを記述

```json:BrowserSyncのscripts
"scripts": {
  "sync": "browser-sync start --server --files *.html css/*.css *.js"
}
```

【解説】

```:BrowserSync
browser-sync start --server --files **/*
```

上記のコマンドを実行すると、現在のディレクトリに`http://localhost:3000`でアクセス可能なWebサーバを立ち上げてブラウザを起動します。
その後、現在のディレクトリ下の全てのファイル(下階層含)の変更を監視し、変更があった際に自動的にブラウザをリロードします。

特定のファイルや階層を指定したいときは`**/*`を変更して指定することができます。
例えば、現在のディレクトリ内のhtml、css、jsファイルのみを対象にしたい場合は、

```:BrowserSync
browser-sync start --server --files *.html *.css *.js
```

という感じで半角スペースで区切って指定します。
今回は最初に記述したようなディレクトリ構造で、html、css、jsファイルだけを監視したいので上のように記述します。

こちらも`yarn browser-sync --help`でヘルプが出るので、必要があれば確認してください。


## 4.動かしてみる
現時点でのpackage.jsonはこんな感じになっているハズ。

```json:package.json
{
  "name": "copy_clipbord",
  "version": "1.0.0",
  "main": "index.js",
  "license": "ISC",
  "devDependencies": {
    "browser-sync": "^2.26.14",
    "node-sass": "^5.0.0",
  },
  "scripts": {
    "watch-sass" : "node-sass -w -r --output-style expanded css/style.scss css/style.css",
    "sync" : "browser-sync start --server --files *.html css/*.css *.js"
  }
}
```

"watch-sass"や"sync"はscript名なので、わかりやすい任意の名前をつけていいです。

これで当初のやりたいことはできるようになりました！
あとはこれを実行するだけです。
2つ以上のscriptを実行するにはターミナルで下記のコマンドを実行します。

```:script実行
yarn run watch-sass & sync
```

これで当初の目的だった、
①node-sassを使いSassファイルの更新を感知して、自動でcssにビルド
②BrowserSyncを使いhtml・css等のファイルの更新を監視して、自動でブラウザをリロード
をしてくれる環境が構築できました！！

Macの方は上記のコマンドを実行するだけでOKですが、他のOSにはスクリプトを連続実行や並列実行する方法はありません。

ここでnpm-run-allの出番です！


## 5.npm-run-allを使って動かしてみる

npm-run-allを利用することで、OSに依存せずに複数のスクリプトを実行できます。

```json:package.jsonのscripts
"scripts": {
  "script_1": "sassファイルをcssファイルにビルド(node-sass)",
  "script_2": "ブラウザをリロード(BrowserSync)",
  "script_3": "script_1とscript_2を実行(npm-run-all)"
}
```

今回、npm-run-allを使って実行するscriptsは上記のようなイメージ。
で、実際にsassのビルドとブラウザリロードの常駐を開始させるscriptは以下の通り。

```json:npm-run-allのscripts
"scripts": {
  "watch-sass" : "node-sass -w -r --output-style expanded css/style.scss css/style.css",
  "sync"       : "browser-sync start --server --files *.html css/*.css *.js",
  "start"      : "npm-run-all --parallel watch-sass sync"
}
```

【解説】

```:npm-run-all
 npm-run-all --parallel watch-sass sync
```

npm-run-allで上記のように記述し実行すると`watch-sass`というscriptと`sync`というscriptをパラレル(並列)実行します。
npm-run-allの実行方法は下記のとおり、下に行くほど省略形です(やることは一緒)。

【並列実行】
`npm-run-all --parallel [script名]`
`npm-run-all -p [script名]`
`run-p [script名]`

【直列実行】
`npm-run-all --serial [script名]`
`npm-run-all -s [script名]`
`run-s [script名]`

やってみたところ、今回は並列でも直列でもどっちでもOKみたいです。


## 6.まとめ

ここまでを踏まえてpackage.jsonを修正したのがこちら。

```json:package.json
{
  "name": "copy_clipbord",
  "version": "1.0.0",
  "main": "index.js",
  "license": "ISC",
  "devDependencies": {
    "browser-sync": "^2.26.14",
    "node-sass": "^5.0.0",
    "npm-run-all": "^4.1.5"
  },
  "scripts": {
    "start"      : "run-p start:*",
    "start:sync" : "browser-sync start --server --files *.html css/*.css *.js",
    "start:sass" : "node-sass -w -r --output-style expanded css/style.scss css/style.css"
  }
}
```

npm-run-allは`start:*`と記述することで、他の`start:`から始まるscriptをまとめて指定することができます。
今回は`start:sync`にBrowserSyncのscript、`start:sass`にnode-sassのscriptを記述し、startだけで両方を実行できるようにしました。

これで本当に完成なので、実際に動かしてみましょう。
下記の命令をターミナルで実行します。

```
$ yarn start
```

これだけです。これだけで、
①node-sassを使いSassファイルの更新を感知して、自動でcssにビルド
②BrowserSyncを使いhtml・css・jsファイルの更新を監視して、自動でブラウザをリロード
をしてくれる環境ができました！！

npm-run-allを利用するので、Mac以外でも使えるハズです。

不足や間違い、もっといい方法などありましたら、コメント等で教えていただけると幸いです。

# 参考にさせていただいた記事
- [Sass(scss) を自動ビルドしつつブラウザも自動リロードして開発速度を上げる](https://qiita.com/numanomanu/items/e00123bce471578ddfe3 "Sass(scss) を自動ビルドしつつブラウザも自動リロードして開発速度を上げる")
- [[Sy] はじめての Sass (node-sass利用）](https://utano.jp/entry/2018/02/hello-sass/ "[Sy] はじめての Sass (node-sass利用）")
- [BrowserSyncの使い方](https://qiita.com/niusounds/items/a95978f9a1cb328d3021 "BrowserSyncの使い方")
- [[Node.js] express + nodemon + BrowserSync でゲボ楽コーディング](https://qiita.com/GGnara/items/fa2e427547ed1f2e37c4 "[Node.js] express + nodemon + BrowserSync でゲボ楽コーディング")
- [Browsersyncを利用してお手軽ブラウザ確認環境をつくろう](https://tech.medpeer.co.jp/entry/2015/06/09/071758 "Browsersyncを利用してお手軽ブラウザ確認環境をつくろう")
- [npm run のスクリプトを連続実行・並列実行する (npm-run-all)](https://maku77.github.io/nodejs/npm/npm-run-all.html "npm run のスクリプトを連続実行・並列実行する (npm-run-all)")