Mac初心者がM1MacでイチからHomebrew, anyenv, nodenvを導入しTypeScript+Express.jsの環境構築してみた(Rosetta2不要)

# 初Mac買いました
Macbook Air(M1チップ搭載)をやっと手に入れました🎉
正月あたりに注文したので結局1ヶ月掛かってしまいました…(カスタムしたからしょうがない)

初めてのMacだったのでWindowsとの違いにいちいちリアクションしつつ色々触ってみれたので、そろそろ開発環境を整えていきたいと思っている次第です。

周知の通りCPUアーキテクチャが従来と異なるため特に開発環境を整える上で障壁となるものはあると思いますが、自分の場合はまず「Macの開発環境のあれこれ」からなので初歩的な部分故ご了承ください。

# 結論、今回できたこと
まず、色々やろうとしてみたのですが結局できたのは以下の通りです。

- VSCode(Insiders Edition)のインストール
- Homebrewの導入
- Homebrewからanyenvの導入
- anyenvからnodenvの導入
- nodenvからNode.js(v15.5.0)のインストール
- TypeScript+Express.js+EJSのサンプルWebアプリで動作確認

一応、**これらは全てRosetta2を使わずして出来ました**。
つまりこれらはM1に対応しています。
順を追って解説します。

# VSCode(Insiders Edition)のインストール
まだ、Insiders Editionしか対応してないみたいです(2021/2/7現在)
[こちらのページ](https://code.visualstudio.com/insiders/)からzipをダウンロードします。

![スクリーンショット 2021-02-07 23.02.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961112/a803811e-7df4-1a49-362f-7f9796413400.png)

`Apple Silicon Chip`って書いてあった！
なんか安心しますね。というわけでこっちをダウンロードしました。

Finderでダウンロードされたものをクリックするとインストール出来たので簡単でいいですね。

VSCodeの拡張機能も問題なくインストールできる感じです。
実際、いくつか必要なものをインストール出来ました。

# Homebrewの導入
Macを手に入れる前に噂に聞いてたアレです。
Macのデファクトスタンダードなパッケージマネージャーですね。

これはプリインストールではありませんので、どこかからインストールしてくる必要があります。
今回はGitHubから入れていこうと思います。
とは言っても`curl`で入れるので`git`コマンドは使用しません。

でもここでGitを思い出してGitを入れたので余談ですが手順を書いておきます。

> というわけでここからは関係ないGitの話です。
> この時てっきりGitはプリインストールだと思っており以下のコマンドを実行しました。
>
> ```shell
> git --version
> ```
> 
> …プリインストールではありませんでした。
> しかし！このコマンドを実行した際にGitをインストールしますか？的なポップアップが出たので無事インストール出来ました> (スクショなくてすみません)
> ポップアップでクリックするだけだから実質プリインストールですね！！😅
>
> 以上です。失礼しました！

話を戻してHomebrewを入れていきます。
が、一つだけ注意点としてM1対応のためにはHomebrewを`/opt/homebrew/`のパスに入れる必要があるそうです。
それだけ注意していれば普通に使えるのでいいですね！

というわけで入れるディレクトリを作成します。

```shell
cd /opt
sudo mkdir homebrew
sudo chown $USER:admin homebrew
```

この時`chown`とやっているようにディレクトリ権限を変更しています。
これで準備が整いましたのでHomebrewをここに入れます。

```shell
curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
```

これでHomebrewが入りました。
でもまだやることが残っています。**パスを通すこと**です。

そのためにまず、ユーザホームディレクトリに`.zshrc`というファイルを作成します。

```shell
vi ~/.zshrc
```

`vi`で作成したのでviエディタモードになったと思います。
`A`キーで挿入モードにしたら次のように記述します。

```text
export PATH=/opt/homebrew/bin:$PATH
```

記述できたら今度は`esc`(エスケープ)キーで挿入モードを解除し、`:wq`と入力したら保存して終了です。
これでユーザホームディレクトリに`.zshrc`ファイルができました。

> このファイルはシェル起動時に呼ばれて実行されるみたいです。
> なのでここにパスを通すコマンドを記述しておくわけですね。
>
> ここで気づいたのですが、純正のターミナルはbashではなくzshというやつだったんですね。
> bashの場合だと`.bashrc`というファイルになるそうです。

これでHomebrewが使えるようになったはずなのでバージョン確認でもしてみましょう！

```shell
brew -v
```

これに対する結果は以下の通りでした。

```shell
Homebrew >=2.5.0 (shallow or no git repository)
Homebrew/homebrew-core N/A
```

N/Aってなってしまってます。
そこでHomebrewのアップデートコマンドを叩いてみました。

```shell
brew update
```

そしてもう一度`brew -v`を叩いた結果です。

```shell
Homebrew 3.0.0-17-g0d1aa33
Homebrew/homebrew-core (git revision 2de085; last commit 2021-02-06)
```

今度こそ良さそうですね！
これでHomebrewが使えるようになりました！

# anyenvの導入
前項のHomebrewのインストールで少し疲れてしまったのですが、Homebrewをインストールしてしまえば無敵です。
なんとこちら、Homebrewからインストール出来ます！

> anyenvはnodenvやpyenvなどの〇〇env系のものをインストール&管理できるものです。
> nodenvやpyenvなどはHomebrewから直接インストールもできますが一括管理できるならということでこちらを入れていきます。

まず、インストールするanyenvについての情報を見ていきます。

```shell
brew info anyenv
```

```shell
anyenv: stable 1.1.2 (bottled)
All in one for **env
https://anyenv.github.io/
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/anyenv.rb
License: MIT
==> Analytics
install: 1,400 (30 days), 4,317 (90 days), 15,063 (365 days)
install-on-request: 1,400 (30 days), 4,318 (90 days), 15,061 (365 days)
build-error: 0 (30 days)
```

`Not installed`ということでまだインストールしていないのと、anyenvについての情報を見ることができました。

では続いてインストールしていきます。

```shell
brew install anyenv
```

インストール出来たらHomebrewでインストールしたものの一覧を確認してanyenvがあるかどうか確認します。

```shell
brew list
```

```shell
anyenv
```

`anyenv`と返ってきたのでインストール出来ていますね。

バージョン確認もしてみます。

```shell
anyenv -v
```

```shell
anyenv 1.1.2
```

`1.1.2`であると正しく返ってきました。

このように自然と`anyenv`コマンドが使用できていますが本当は手動でパスを通したりする必要があるんですよね。
今回その必要はなかったので楽でいいですよね！

また、もしコマンドが打てなかった時には次のようにシェルをリフレッシュしてあげるといいみたいです。

```shell
exec $SHELL -l
```

ではちょっとanyenvを使ってみましょう。
まず、使うために初期化をする必要があるみたいなのでやっておきます。

```shell
anyenv install --init
```

次にanyenvを使用してインストールできるものの一覧を確認してみましょう。

```shell
anyenv install -l
```

```shell
  Renv
  crenv
  denv
  erlenv
  exenv
  goenv
  hsenv
  jenv
  jlenv
  luaenv
  nodenv
  phpenv
  plenv
  pyenv
  rbenv
  sbtenv
  scalaenv
  swiftenv
  tfenv
```

結構主要な言語は揃っている感じでいいですね〜

これでanyenvの導入は完了なのですが、今後anyenvで〇〇env系を入れる際にやっておいた方がいい設定などをやっておきます。

まず、〇〇env毎にパスを設定してくれるように`.zshrc`ファイルに追記していきます。
もうviエディタを使わずに一発のコマンドでやっちゃいましょう。

```shell
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(anyenv init -)"' >> ~/.zshrc
```

二発でしたね。
まぁ分けているだけですので…

これでパスの設定は終了です。
これさえあればPythonもNode.jsも何もかもパスの設定をしなくていいっぽいので激ヤバです。
anyenvいいですね！

最後にもう一つ、`anyenv update`というコマンドを叩くだけで〇〇env系も全てアップデートされるようにしてくれるプラグインを導入します。

```shell
git clone https://github.com/znz/anyenv-update.git ~/.anyenv/plugins/anyenv-update
```

`git`でクローンしました。
前項でした余談が活きる時が来ました😅

これでanyenvが捗るようになりました！

# nodenvの導入
前項でanyenvを導入できたのでそれを使用して入れていきます。
先程の作業から見ると拍子抜けしてしまうくらい簡単です。

```shell
anyenv install nodenv
exec $SHELL -l
```

`exec $SHELL -l`でシェルのリフレッシュもやっておきました。

続いてnodenvのバージョン確認を行います。

```shell
nodenv -v
```

```shell
nodenv 1.4.0+3.631d0b6
```

前項でやったパスの設定が効いているのでコマンドがしっかり叩けますね。

ではnodenvを使用してインストールできるものの一覧を確認します。

```shell
nodenv install -l
```

```shell
...(省略)
15.4.0
15.5.0
15.5.1
15.6.0
15.7.0
15.8.0
...(省略)
```

上記は省略していますが、大量に出てきます。
最新版である`15.8.0`も確認できました。

今回はM1チップということで同じ境遇の人に合わせたバージョンでインストールしたかったのでネット記事で見つけたM1 MacでNode.jsをインストールしている人が入れていたバージョンである`15.5.0`でやってみます。

```shell
nodenv install 15.5.0
```

ちょっとこれは時間がかかります。
熱くならないと言われるM1 Macがほんのり暖かくなりました。

インストール出来たら、すぐコマンドが使えるように更新します。

```shell
nodenv rehash
```

そして、nodenvは複数バージョンをインストールすることが前提のためデフォルトで使うバージョンを指定しておきます。

```shell
nodenv global 15.5.0
```

これで異なるバージョンをインストールしてもこの設定を変更するまでは`15.5.0`のバージョンです。

というわけでNode.jsのいつものコマンドを叩いて確認しましょう。
ドキドキしますね。

```shell
% node -v
v15.5.0

% npm -v
7.3.0
```

おぉー素晴らしい！
これでNode.jsが動きましたね！

# TypeScript+Express.js+EJSのサンプルWebアプリで動作確認
やっと環境が整ったのでサンプルアプリを作ることができます。
まぁどうせ動くでしょ。いや動いてくれよ…

まず、TypeScriptだけはグローバルでインストールします。

```shell
npm install -g typescript
```

シェルを再起動してtscコマンドを叩いたところきちんと反応したのでパスも通ってます！

プロジェクトフォルダを作成しその中で以下のコマンドでプロジェクト内に色々入れていきます。

```shell
npm init -y
npm install --save express ejs
npm install --save types@express
tsc --init
```

さて、この後作成された設定ファイル(package.jsonやtsconfig.json)の設定やソースファイルのコーディングを行いましたが簡単な表示だけのWebアプリなので割愛します。

またこの際、以下のコマンドを叩くことでプロジェクト内に`.node-version`というファイルが作成されます。

```shell
nodenv local 15.5.0
```

これはnodenvで複数バージョンをインストールしている際に当該プロジェクト内で実行するバージョンを指定できます。
これをやっておくとわざわざプロジェクト毎にバージョンを切り替えることを手動で行う必要がなく非常にシームレスです。


では肝心の実行結果ですが、TypeScriptのコンパイルもNode.jsの実行もWebアプリをSafariから閲覧も全て正しく実行できました！
他のライブラリはまだわからないけど、とりあえず大元が動くならよかった！

# まとめ
結果として今回目指していたことはできたので良かったです。
手探り状態だったので記事が長くなってしまいました。

本当はnodenvをやる前にpyenvをやろうとしていたのですが、pyenvから任意のバージョンをインストールするところでインストール出来ませんでした。MacはPythonがプリインストールなので救いだったのですが、ライブラリがOpenCVやPandasが入らなかったので(おそらくもっと入らないライブラリはある)使える状態ではありませんでした。
早く使えるようになるといいですね！

今後としてはDockerがM1に対応したと聞いたので入れてみようかなと思っています。

それにしてもMacいいですね！
まずLinuxコマンドが使えることに感激です。
M1チップはサクサクなのと電池持ちが素晴らしいです。
これからWindowsとMacの二刀流ができることにワクワクしています😄