2016年版 Node.jsで幸せになれる10の習慣

## はじめに

Herokuのブロク記事[10 Habits of a Happy Node Hacker (2016)](https://blog.heroku.com/archives/2015/11/10/node-habits-2016)を、「洋の東西を問わず、みんな『10のなんとか』って好きなんだな」と思いながら眺めていたら、結構面白かったので内容をピックアップしてみます。

以前、[Go言語で幸せになれる10のテクニック](http://qiita.com/ksato9700/items/6228d4eb6d5b282f82f6)というのをあるブログ記事を元にして書いた時には、原題の "Ten Useful Techniques in Go"を意訳して「幸せになれる」としたのだが、今回は原題にシッカリ"Happy"が入っているというおまけ付き。

なお、「2016年版」と言っているのは[2013(2014？)年版](https://blog.heroku.com/archives/2014/3/11/node-habits)があるから。これらを読み比べてみるのもまた面白いが、とりあえず今回は最新の2016年版のご紹介。

## 1. 新しいプロジェクトは npm init で始めろ

新しいプロジェクトはこう始めようよ、と言っている。

```sh
mkdir my-app; cd $_
npm init --yes
```

これは2013年版と一緒だが、`--yes`オプションが付いているのが違う。付けておくと一々質問に答えずにデフォルト値で作ってくれる。そして、こんな具合に「enginesを追加しておけ」と言っている。

```js
"engines": {
  "node": "4.2.2"
}
```


## 2. 賢く.npmrcを使え
npmでパッケージをインストールしても依存関係をpackage.jsonに入れてくれたりはしない。入れるには、`--save`オプションを附けてやる必要があるが、これだと

```js
"dependencies": {
    "request": "^2.67.0"
  }
```
こんな風に`^`付きで依存関係が記述される。これってどういう意味かというと、[ここ](https://docs.npmjs.com/misc/semver)に書いてあるように、「メジャーバージョン(ドットで句切られた一番左の数値、この場合は"2")が同じ最新のモノをインストールせよ」ってこと。つまり、現在、requestは2.67.0が最新だが、これがバージョンアップして、2.67.1 とか 2.68.0とかが出るとそちらがインストールされてしまう。開発時は良いけど、実際にリリースした後に勝手にライブラリがアップデートされるのはちと困る。

そんな場合は`npm install --save --save-exact <packag-name>`ってやると良い。すると、

```js
  "dependencies": {
    "request": "2.67.0"
  }
```
てな感じでバージョン番号固定で依存関係が記述される。

でも、npm installを呼ぶ時にこのオプションをつけるのはしんどいし、きっと忘れる。そんなあなたの為に .npmrc。

```sh
npm config set save=true
npm config set save-exact=true
```

とすると、その設定が `~/.npmrc`に書き込まれ、それ以降オプションを一々付けなくても済むようになる。

## 3. ES6の電車に飛び乗れ

ES6はご存知、ECMAScript Version 6。Node.jsもVerison 4以降はV8エンジンでサポートされているES6の機能をデフォルトでオンにしている。詳しくは[ここ](https://nodejs.org/en/docs/es6/)にある。沢山の機能追加でクラクラくるが、食わず嫌いにならずに、使えるところから使ってみなよ、と言っている。

例えばこんなの例に挙げられている。

```js
let user = users.find(u => u.id === ID);

console.log(`Hello, ${ user.name }!`);
```

これは従来のES5ではこんな風に書かなければならなかった。

```js
var user = users.find(function (u) {
  return u.id === ID;
});

console.log("Hello, " + user.name + "!");
```

ちなみに、どちらもCoffeeScriptに影響されたような表記。Coffeeだとこう書くのかな。

```coffee
user = user.find (u) -> u.id is ID
console.log "Hello, #{user.name}!"
```

## 4. ファイル名には小文字だけを使え

クラス名とファイル名を一致させておくのは良い考えな気がするが、MyClassの定義をMyClass.jsに格納するのはやめとけ、と言っている。これは、俗に[CamelCase](https://en.wikipedia.org/wiki/CamelCase)と呼ばれる表記だが、ファイル名は小文字だけで例えば "my-class"みたいにすべき。なぜかというと、WindowsとOSXではファイル名の大文字/小文字を区別せず、Linuxではするので、これらのプラットフォーム全てでちゃんと動かすためには、ファイル名を小文字で統一しておいた方が良いため！

## 5. アプリはクラスタ化しておけ

Node.jsはシングルスレッドな実行環境なのでCPUコアを一つしか使えない。さらにV8の制限でメモリも1.5GBまで。マルチコアで数GBから数十GBのメモリを載せた昨今のマシンの上で動かしてもその力を充分に発揮できないってことだ。なので、アプリはクラスタ化しておけ、と言っている。

で、クラスタ化ってなにかと言うと、[ここ](https://nodejs.org/api/cluster.html)にAPIの解説があるように、Node.jsのアプリのプロセスをforkして複数CPUコアを使えるようにするってこと。このCluster APIを使って自分でガリガリ書いても良いけど、[throng](https://github.com/hunterloftis/throng)みたいなライブラリがあるからそれを使ってでも、クラスタ化をしておいた方が良いよというお話。

## 6. 周りの環境を見ておけ

開発、QA、本番などで異なる設定をしたいことがある。それをそれぞれ別々の設定ファイルを用意してやる方法もあるけど、環境変数を使ってやった方がいいぞ、と言っている。例えば、[node-foreman](https://strongloop.github.io/node-foreman/)というアプリ起動ツールがあるが、コイツはローカルにある.envというファイルに書かれた環境変数を起動前に読み込んでから実行してくれる。この、.envファイルを.gitignoreに入れておいて、バージョンコントロールされないようにして、環境ごとに用意してやる。そこに別々の設定を書いておけば、環境ごとに異なる設定でうごかすことができる、というお話。

## 7. ゴミを避けろ

Node.jsで使っているV8というJavaScriptエンジンは、怠けグセがあり、ギリギリになるまでゴミ集め(Garbage Collection)をしないことがある。その辺り、もう少しコントロールしたいんだったらnodeの起動時にオプションをつけとけ、ってお話。例えばこんな感じに。

```sh
node --optimize_for_size --max_old_space_size=920 --gc_interval=100 server.js
```

これは、「速度よりメモリ大事に」「長生きさんの領域は920MBまで」「100回メモリ割り当てしたらガベコレ」という指定になる。もし1.5GBより少ないメモリでNodeを動かすのであれば、max_old_space_sizeをそれ以下に設定するのが望ましい。なお、V8のGarbage CollectorとNew Space, Old Spaceの考え方は[ここ](https://github.com/thlorenz/v8-perf/blob/master/gc.md)に解説がある。

## 8. 色々と引っ掛けろ

package.jsonの"scripts"セクションには"start"以外にも色々とイベント駆動な挙動を書くことができて、自動化の役に立つ。例えば、インストール前に何か実行したければ`preinstall`が使えるし、Gruntとかを使ってインストール後に何かやりたければ`postinstall`が使える。制御文の部分で環境変数を参照したり、外部のシェルスクリプトを呼び出したりもできる。

## 9. 大事なものだけGitで管理しろ

生成されるファイルはGitで管理するな、って言っている。まぁ、当り前かな。そのためにも、.gitignoreをうまく使って、うっかり作られたファイルがコミットに紛れ込まないようにするのが大事。

## 10. 簡単にしろ

だいたい、技術の予想っていうのは外れるものだが、ここで来年の予想をしてみる！って言っている。2016年は「JavaScriptが単純化される年」になる。

MVCなデカいフレームワークで全部ページを作るんじゃなくて、静的ファイルをCDNにおいて動的な部分だけJavascriptとか、BowerとかGulpとかGruntとか使わなくなってきたりだとか。それから、コードもシンプルになる。時には使う機能を制限して、時には新しい機能を使うことで。

## おわりに

ということで、ざざっと眺めてみたが、あまり驚くものはない一方で、気をつけておくと良いかもなと思う小粒だけど粒揃いな習慣が並んでいた印象でした。