Nuxt.js ソースコードリーディング事始め

# 概要

Nuxt.jsのアドベントカレンダー9日目です。
今回は、Nuxt.jsのソースコードリーディングをこと始める時に必要な認識をまとめる。

# 対象者

* Nuxt.jsを書いてみて、ちょっと実装できるようになってきた方
* 他の言語やっていたけれど、ちょっとNuxt.jsを始めた方
* バックエンド系のフレームワークなどのソースコードリーディングをやったことがあるけれど、フロントエンドはまだやったことがない方
* ソースコードリーディングやったことがないけど、やってみようかな思っている方

# 始める前に

ソースコードを手元に置いて定義ジャンプしていけると楽に読んでいけるため、手元にclone。
また、私の場合、読む際は、VSCodeを使っている。

```sh:手元にソースコードを用意する
$ git clone https://github.com/nuxt/nuxt.js.git
$ cd nuxt.js
$ yarn install
$ code .
```

ここで `yarn install` をしておくのは、VSCode内で、読み進めていく際に、参照先がなく、エラー表示される箇所が出てくるため。

# わかっておくと良い前提

JavaScriptなどで書いてあるライブラリは、一定の前提のようなものが存在するため、知っていた方が読み進めやすい。

## これから書く、または変更予定がある箇所について

OSSにおいては、当然のことかもしれないが、これから処理を記述、変更していく箇所は、基本的に `TODO` で管理されている。
例えば、Vue-nextなどもそのような進め方となっている。

#### VSCodeのパッケージTODOSで表示している内容

![スクリーンショット 2019-12-09 23.23.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183308/cc4190fb-588e-b886-2b34-2de328589824.png)

#### ↑の実際の記述内容

![スクリーンショット 2019-12-09 23.24.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183308/def4e76f-f47e-eca9-11e8-6d2749245fb8.png)

## ディレクトリ構成について

```sh:1階層目の構成
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── RELEASE_PLAN.md
├── azure-pipelines.yml
├── babel.config.js
├── benchmarks
├── distributions
├── examples
├── jest.config.js
├── lerna.json
├── package.json
├── packages
├── renovate.json
├── scripts
├── test
└── yarn.lock
```

実質普段読んでいるところの処理を読み進めたい方は以下のディレクトリを見ると良い。

```sh:packages内のディレクトリ構成
├── packages
│   ├── babel-preset-app
│   ├── builder
│   ├── cli
│   ├── config
│   ├── core
│   ├── generator
│   ├── server
│   ├── utils
│   ├── vue-app
│   ├── vue-renderer
│   └── webpack
```

`packages`を読み進めることで、普段私たちが利用している処理について読むことができる。

## 基本構成

* 1階層目のディレクトリには、各役割ごとにディレクトリを用意
* index.js というファイルが随所に用意されている
* index.jsにおいて、同ディレクトリ内のファイルをexportするという構成 → 普段かくNuxt.jsのpagesでも見る構成。JavaScriptではよく見る
* 実際の処理の内容は、packagesというディレクトリ内に格納。JavaScriptのライブラリなりフレームワークなりでよく見るが、Nuxt.jsもその構成
* 特に**普段書いている部分を読みたい**という方は、`packages/core`を読み進めるのがお勧め。

## 利用されているライブラリ

### rollup - [GitHub](https://github.com/rollup/rollup) - [Documentation](https://rollupjs.org/guide/en/)

複数ファイルに書かれたJavaScriptを、モジュールなどを読み込みつつ、ひとつのバンドルにしてくれるツール - [参考](https://qiita.com/cognitom/items/e3ac0da00241f427dad6)
Nuxt.js内のファイル群をまとめてくれています。最近いろんなフレームワークなりライブラリなりに導入されている模様です。

他には以下のようなものと一緒に利用されることも多い模様。

> rollup-plugin-node-resolve
rollup-plugin-commonjs
rollup-plugin-json
とBabel関連。後者はプラグインではないですが、バベるときに必要なので一緒に。
rollup-plugin-babel
babel-preset-es2015-rollup

↑参考より引用。

### consola - [GitHub](https://github.com/nuxt/consola) - [Documentation](https://devstore.io/js/consola)

consolaはNode.jsとブラウザーのコンソールロガー。
コマンドライン上でカラーとアイコンが付いたアウトプットを出力。普段見るNuxt.jsの出力周りについてはこのライブラリのお世話になっている。
見やすいので、他のライブラリや自分で何か作成する際にも使いやすい。

### istanbul

テストのカバー率を調べることができるライブラリ。
プログラムにテストを行えていない箇所があれば、その箇所をエラーで教えてくれるため、テストを網羅するのに役立つ。
以下のように記述すると無視する箇所を指定もできるため、重宝されている。

```javascript
/* istanbul ignore if */
if (serverMiddlewarePaths.includes(fileName)) { // ←このifの処理部分はテスト実行時のカバレッジからは、無視される。
  consola.debug(`Clear cache for ${fileName}`)
  clearRequireCache(fileName)
}
```

# 実際に読んでみる

ここでは例として、`packages/core`の一部を切り出して読み進めることとする。

#### packages/core のディレクトリ構成

![スクリーンショット 2019-12-09 23.30.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183308/83f9f9d1-0d70-5515-938c-c0bc1719dea1.png)

src側を読み進めていく。まずまとめてexport処理が書かれているはずのindex.jsをみると

![スクリーンショット 2019-12-09 23.31.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183308/2944a8f2-933b-beda-d59f-64d13a75288c.png)

予想通り、exportが記述されている。
Nuxtについては、時々Vue.jsのDevToolsでみるものなので、一旦そちらを確認してみる。

![スクリーンショット 2019-12-09 23.34.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183308/aae7cf8c-6d89-b272-fb7b-e8f12a55e780.png)

どうやら古いエイリアスが存在するらしいことがわかった。
自分は今まで知らなかったが、古いバージョンを利用していると存在するようだ。

「resolveAlias nuxt」などで調べると、`resolveAlias`が記述されたNuxt.jsのコードがいくらか見つかる。
将来的に消えそうだなというところは少なくともわかる。

次にmodule.jsを読み進めてみる。すると、ここで初めて、公式ドキュメントでも見たことのある記述が出てくる。

![スクリーンショット 2019-12-09 23.53.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183308/e5b6059f-2e3d-000e-e5d8-91a5ce87dd7b.png)

上記を読むと、addVendorやaddTemplateなどが見える。これは、[こちら](https://ja.nuxtjs.org/api/internals-module-container/#addtemplate-template-)にも載っているような普段利用されるメソッドということがわかる。こういったように公式ドキュメントと紐づけながら読んでいくとわかりやすい。

# 処理の追い方はわかったが、使い方がわからない場合

この場合は、実は、テストやexampleをみるとわかりやすい。

## module.jsのaddTemplateメソッドのテスト

![スクリーンショット 2019-12-09 23.56.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183308/3c64e7d6-ead3-b8d3-f2b5-8457d6639ab0.png)

こことセットで、公式ドキュメントを読むことで、自分の場合は、理解が深まったのでオススメする。

# 読むことで得られた効能

1. 一般的に、JavaScriptで書く際の書き方を学べた
2. 普段書いている処理のさらに中の処理順を知れたことで、避ける書き方を学べた
3. それぞれの書き方のオプションがすぐにわかるようになってきた
4. 今後削除されそうなメソッドなどがすぐにわかる
4. 参考になる実装を導入することができる→独自のloadingIndicatorを書く際などは参考になった
5. これまで知らなかったライブラリを知ることができた

これらのメリットがある。井の中の蛙状態にならずに済むのが一番のメリットだなと感じる次第。
まだ自分も始めたばかりであるので、コツコツと頑張っていきたい。

# お願い

ちょくちょくこの記事は更新していく予定ですが、もし、こんな方法あるよ！オススメだよ！といったことがありましたら、コメントいただけますと嬉しいです。
よろしくお願いします。