.nuxtignoreを使ってNuxt.jsをいい感じにビルドする

本記事は[東京学芸大学 櫨山研究室 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/hazelab)の18日目の記事になります．

# はじめに

[Nuxt.js](https://ja.nuxtjs.org/)はVueのフレームワークで個人的にはかなり気に入っています．
Nuxt.js/Vue.jsでは基本的にコンポーネントに分割して開発を進めることになります．

今回の記事ではハッカソンでNuxt.jsを使っていた時に実施したビルドプロセスについてまとめました．

ハッカソンでは短期間で成果物を仕上げる必要があります．
そこで**一つのNuxtプロジェクト上で管理者側の機能やページも開発しました．**
これにより管理者側でもユーザー側のコンポーネントなどを共通して利用できるというメリットがあります．
一方で当然ながら**管理者向けの機能やコンポーネントを本番環境には含めたくない**ですね．

そういったユースケースに対しNuxt.jsでは**ignoreプロパティを使うことによって柔軟にビルドをすることができます．**


# Nuxt.jsのignoreプロパティ

Nuxt.jsでは`.nuxtignore`ファイルを使うことでビルド時に`layout`,`page`, `store`, `middleware`において無視するファイルを指定することができます．
`.nuxtignore`ファイルの記述方法は`.gitignore`と同様になります．

他にもignoreの設定方法はありますが詳細については公式のリファレンスを参照ください．

> ignore プロパティ - NuxtJS, https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-ignore/

# 管理者向けのファイルを無視してビルドを行う

例えば同一プロジェクト内(同一SPA内)で管理者向けのページも開発していたとします．

ここでは以下のディレクトリ構成で開発を進めていたとします．

```:ディレクトリ構成
pages
├── admin // 管理者向けのpagesコンポーネント
│   └── index.vue
├── index.vue
└── inspire.vue

layouts
├── admin.vue // 管理者向けのレイアウトコンポーネント
├── default.vue
└── error.vue

store
├── admin.ts // 管理者向けの状態管理ファイル
└── index.ts
```

この状態で`yarn build`を実行すると以下のようになります．

```js:output
Built at: 2020/12/28 18:40:36
                         Asset       Size  Chunks                                Chunk Names
../server/client.manifest.json   14.2 KiB          [emitted]                     
                    0218a77.js  818 bytes       4  [emitted] [immutable]         pages/inspire
                    26ab95f.js    197 KiB       1  [emitted] [immutable]         commons/app
                    5bc8bc3.js    476 KiB       6  [emitted] [immutable]  [big]  vendors/app
                      LICENSES  450 bytes          [emitted]                     
                    a69ec92.js  302 bytes       2  [emitted] [immutable]         pages/admin/index
                    aaf0716.js   2.32 KiB       5  [emitted] [immutable]         runtime
                    cd7a169.js   21.6 KiB       3  [emitted] [immutable]         pages/index
                    e6c1fce.js   52.3 KiB       0  [emitted] [immutable]         app
 + 2 hidden assets
Entrypoint app = aaf0716.js 26ab95f.js 5bc8bc3.js e6c1fce.js

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets: 
  5bc8bc3.js (476 KiB)

Hash: bf389cb1c25fe76ffc61
Version: webpack 4.44.2
Time: 4221ms
Built at: 2020/12/28 18:40:40
               Asset       Size  Chunks             Chunk Names
pages/admin/index.js   1.15 KiB       1  [emitted]  pages/admin/index
      pages/index.js   37.2 KiB       2  [emitted]  pages/index
    pages/inspire.js   3.23 KiB       3  [emitted]  pages/inspire
           server.js    658 KiB       0  [emitted]  app
server.manifest.json  407 bytes          [emitted]  
 + 4 hidden assets
Entrypoint app = server.js server.js.map
ℹ Ready to run nuxt start                                                                                        18:40:40
✨  Done in 21.76s.
```

`pages/admin/index`といった管理者向けのファイルを本番環境には公開したくないです．
そこで以下のような`.nuxtignore`ファイルをプロジェクトルートに用意します．

```conf:.nuxtignore
# admin 配下のページをすべて無視
pages/admin/*.vue

# admin.vue レイアウトを無視
layouts/admin.vue

# admin.ts ストアを無視
store/admin.ts
```

この状態で`yarn build`を実行します．

```js:output
Built at: 2020/12/28 19:33:54
                         Asset       Size  Chunks                                Chunk Names
../server/client.manifest.json     14 KiB          [emitted]                     
                    08995cc.js    476 KiB       5  [emitted] [immutable]  [big]  vendors/app
                    17767f4.js    2.3 KiB       4  [emitted] [immutable]         runtime
                    3b550d0.js  818 bytes       3  [emitted] [immutable]         pages/inspire
                    7938437.js   52.2 KiB       0  [emitted] [immutable]         app
                    8eff219.js    197 KiB       1  [emitted] [immutable]         commons/app
                      LICENSES  450 bytes          [emitted]                     
                    db064f0.js   21.6 KiB       2  [emitted] [immutable]         pages/index
 + 2 hidden assets
Entrypoint app = 17767f4.js 8eff219.js 08995cc.js 7938437.js

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets: 
  08995cc.js (476 KiB)

Hash: c4ab081e872b6bb72cce
Version: webpack 4.44.2
Time: 4512ms
Built at: 2020/12/28 19:33:59
               Asset       Size  Chunks             Chunk Names
      pages/index.js   37.2 KiB       1  [emitted]  pages/index
    pages/inspire.js   3.23 KiB       2  [emitted]  pages/inspire
           server.js    658 KiB       0  [emitted]  app
server.manifest.json  299 bytes          [emitted]  
 + 3 hidden assets
Entrypoint app = server.js server.js.map
ℹ Ready to run nuxt start                                                                                        19:33:59
✨  Done in 23.71s.
```

先ほどとは異なり`pages/admin/index`などが含まれていないことがわかります．

# npm-scriptsで制御する

`.nuxtignore`はできれば本番のビルド時にだけ適用したいので`npm-scripts`で制御します．

まず先ほどの`.nuxtignore`を**`prod.nuxtignore`というファイル名**で用意します．

```:prod.nuxtignore
# admin 配下のページをすべて無視
pages/admin/*.vue

# admin.vue レイアウトを無視
layouts/admin.vue

# admin.ts ストアを無視
store/admin.ts
```

そして`package.json`で**`build:prod`**というコマンドを登録します．

```package.json
  "scripts": {
    "dev": "nuxt-ts",
    "build": "nuxt-ts build",
    "build:prod": "cp prod.nuxtignore .nuxtignore && nuxt-ts build && rm .nuxtignore",
    "generate": "nuxt-ts generate",
    "start": "nuxt-ts start",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "test": "jest"
  },
```

これにより`yarn build`と`yarn build:prod`というコマンドの使い分けで柔軟にビルドを行うことができます．

# おわりに

本記事では`.nuxtignore`を使ったNuxt.jsのビルドの制御について扱いました．

使う場面は少ないかもしれませんが何かの役に立てば幸いです．