【日記】lesscコマンドが効かない！→対処したら色々勉強になった

環境：macOS Mojave
MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)

結論：インストール方法を変えたら解決したよ
`sudo npm i less --save`→`npm install -g less`
でもPATHが通ってないことが原因だから、パスを指定して実行した方がいいね。

---

最近、この本でWebアプリ開発を学んでいます。
[JavaScriptでのWeb開発 ~ Node.js + Express + MongoDB + ReactでWebアプリを開発しよう ~ その２（iOS対応版）](https://www.amazon.co.jp/JavaScript%E3%81%A7%E3%81%AEWeb%E9%96%8B%E7%99%BA-Node-js-Express-React%E3%81%A7Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E9%96%8B%E7%99%BA%E3%81%97%E3%82%88%E3%81%86-%E3%81%9D%E3%81%AE%EF%BC%92%EF%BC%88iOS%E5%AF%BE%E5%BF%9C%E7%89%88%EF%BC%89-ebook/dp/B07F3XT7DB?_encoding=UTF8&redirect=true&ref_=ku_mi_rw_edp)

途中、LESSファイルからCSSファイルを生成するためのlesscコマンドを実行しようとしたところ、ターミナルでエラーが発生しました。

```
$ lessc less/app.less css/app.css
bash: lessc: command not found
```

LESSそのものは正しくインストールできているはず。
何がいけないのでしょうかとグーグル先生に尋ねてみたところ、どうにもPATHが通っていないのが原因の模様。PATHって自動で通してくれるものだとばかり思っていました。

lessが入っている場所を確認してみると、ありましたありました。
<img width="611" alt="スクリーンショット 2019-05-30 12.18.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/8def9487-5c1f-791a-6146-2abc651da0c9.png">
`/usr/bin/less`に存在することを無事確認です。

んで、PATHを通すってどうやるのかなと調べていたら、下記の記事を発見。
[MacでPATHを通す](https://qiita.com/nbkn/items/01a11392921119fa0153)
なるほど、`.bash_profile`というファイルに書き込めばいいみたいです。

```
$ ls -a
.			.gitignore_global	Applications
..			.gitkraken		Desktop
.CFUserTextEncoding	.hgignore_global	Documents
.DS_Store		.lesshst		Downloads
.Trash			.local			Google ドライブ
.bash_history		.mongorc.js		Library
.bash_profile		.npm			Movies
.bash_sessions		.pylint.d		Music
.config			.ssh			Pictures
.dbshell		.stCommitMsg		Public
.gitconfig		.viminfo
.gitflow_export		.vscode
```

ありますね。
PATHの通し方は`export PATH=$PATH:新しく設定するPATH`というコマンドを実行すればいいみたいです。
その後`source`コマンドで変更を反映させるのも忘れないように。
最後に、中身を再度確認して反映が通っているかどうか確認します。

```
$ export PATH=$PATH:/usr/bin/
atsushinoMacBook-Pro:~ anaakikutsushita$ source ~/.bash_profile
atsushinoMacBook-Pro:~ anaakikutsushita$ printenv PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/bin/
```

`/usr/bin/`が新たに追加されているのが確認できました。
しかし既に`/usr/bin`が存在していたみたいですね・・・。これはダブっちゃってるみたいだけどいいのかな？

とにもかくにも、PATHが通っている状態にはなったはず。
これでlesscコマンドくんも効いてくれるでしょう。

```
$ lessc less/app.less css/app.css
bash: lessc: command not found
```

**だめやんけ**

さらに調べていると、どうやらインストールの方法からしてちょっと違っていたみたい。
私は技術書通りに`sudo npm i less --save`でlessをインストールしていました。
ところがネットの情報を見る限り、`npm install -g less`のように`-g`オプションをつけてインストールしている方法も多く見受けられました。

実際のところこの差がどういう違いになるのかは分かりませんが、とりあえずやってみることにしました。

```
$ npm install -g less
/usr/local/bin/lessc -> /usr/local/lib/node_modules/less/bin/lessc
+ less@3.9.0
added 60 packages from 123 contributors in 2.057s
```

あっ、なんだかインストール場所が変わりましたよ的な表示が出ている。
もしかしてこれで正しくPATHが通るようになったりしてないかしら。
もう一度lesscコマンドを試してみましょう。

```
$ lessc less/app.less css/app.css
atsushinoMacBook-Pro:hoge anaakikutsushita$ cd css
atsushinoMacBook-Pro:css anaakikutsushita$ ls -a
.       ..      app.css
```

なんとすんなり実行できました。
生成されたCSSの中身を確認しても特に問題なさそうです。

となると、やはり`-g`オプションをつけてインストールしたことが決め手だったのでしょうか。
このオプションは何を指定するものなのか、ちょっと調べてみましょう。
すぐに次のような記事を見つけることができました。

[僕がnpm installに-gをつけないわけ](https://qiita.com/DeployCat/items/cd456d6bea72937464f8)

私が知りたいところだけ抜き出してみると、次のような感じでしょうか。

- `-g`をつけるとグローバル領域へのインストールとなり、自動的にPATHが設定される。
- `-g`をつけない場合は、実行時にパスを指定する必要が出てくる。
- 一方、インストール先がグローバル領域じゃなかったらどうなるのと言うと、`--save`オプションを付けた場合`package.json`に記載されることになる。

なんとなくわかったようなわからんような感じです。とりあえず今後はなるべく`-g`オプションは使わない方がいいなと思いました。
package.jsonとかグローバル領域とはなんなんでしょう。こう言うように知らない概念が何個も何個も並列で出てくるとすっごい疲れるんですがいい方法ないものでしょうか。

ざっと説明を読んでみたところ、`package.json`はnpmでインストールしたライブラリの情報をまとめておくファイルのようですね。
確かに、プロジェクトがどのライブラリに依存しているのかと言う情報はどこかにまとめられていないと非常に面倒なので、このファイルのありがたさは理解できます。
そしてこの`package.json`ファイルが存在していれば、プロジェクトをcloneした時なんかに依存関係にあるライブラリをまとめてインストールしてくれる機能もあると言うことみたいですね。先の記事でポータビリティを議論していたのはそのためでしたか。

じゃあ、なんでもかんでもpackage.jsonに書くようにしちゃった方が平和じゃね？
確かにPATHを通せる利点はあるけど、グローバルにインストールする利点ってなに？
少し調べた限りではグローバルインストールのデメリットばかりが目につきます。
メリットらしいメリットはPATHが自動的に通ること以外には見つけられませんでした。
それどころか、グローバルインストールだとライブラリのバージョンを厳密に指定できないみたいな不都合さもあることがわかりました。

一つ賢くなったので、グローバルにインストールしてしまったlessは一旦アンインストールしておきます。

```
$ npm uninstall -g less
removed 60 packages in 0.623s
$ lessc less/app.less css/app.css
bash: /usr/local/bin/lessc: No such file or directory
```

これでよし。
グローバルにインストールしたことで実行できていた`lessc`も、アンインストールしたことで実行できなくなったことが確認できました。

改めてパス指定して`lessc`コマンドを実行してみましょう。
`lessc`がインストールされている場所をあらかじめ確認しておきます。
<img width="820" alt="スクリーンショット 2019-05-30 14.21.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/70850519-4a3b-275d-99fb-2eaef7d1a788.png">
`node_modules/less/bin/lessc`にありますね。
早速実行してみましょう。

```
$ node_modules/less/bin/lessc less/app.less css/app.css
$
```

実行できました。
`app.css`の方も正常に作成されました。

思いがけず知らないことがたくさん出てきてお勉強が大変でしたが、この機会に知っておけてよかったです。
今後もグローバルインストールはナシの方向でやっていきましょう。

実はローカルインストールした後でもパスを直接指定せずにラクな方法でコマンドを実行するワザがあるみたいですね。
しかしそこまでは流石に頭が回らなかったため、パス指定の方法が面倒でやってられない時がきた時にまた改めて調べてみたいと思います。