Nuxt.js で「index.html」以外の「hoge.html」などの出力に対応する

## ことの始まり

こういうディレクトリ構成はよくありますよね。

私は、全部indexにしてしまいたい派ですが、
リニューアルだと簡単にURLを変えられないのです。

```
dist/
├── fruit
│   ├── apple.html
│   ├── banana.html
│   └── orange.html
├── hoge
│   └── index.html
└── index.html
```

今回初めて案件で、**Nuxt.js**（静的ジェネレート機能）を使って、
サイト構築をしようと思い、

**まぁ、出来るだろ**

くらいに思っていました。

元のsrcファイル ↓

```
src
├── fruit
│   ├── apple.vue
│   ├── banana.vue
│   └── orange.vue
├── hoge
│   └── index.vue
└── index.vue
```

```
npm run generate
```

:relaxed:


```
dist
├── fruit
│   ├── apple
│   │   └── index.html
│   ├── banana
│   │   └── index.html
│   └── orange
│       └── index.html
├── hoge
│   └── index.html
└── index.html

```

 :neutral_face: 

**出来てない...**

## subFolders を見つける

**generateプロパティ** の **subFoldersオプション** という素敵なものを見つけた。

https://ja.nuxtjs.org/api/configuration-generate#subfolders

```javascript:nuxt.config.js
export default {
  generate:{
    subFolders : false
  }
}
```

```
npm run generate
```

:relaxed:

```
dist
├── fruit
│   ├── apple.html
│   ├── banana.html
│   └── orange.html
├── hoge.html
└── index.html

```
 :neutral_face: 

**他のディレクトリも全部消えた...**

subFolders をそれぞれのvueファイルに個別設定してみたけど
全然ダメだった。。

https://github.com/nuxt/nuxt.js/blob/0ca99426c93e4f5b7579c12675efb4f8fbef3f8b/lib/builder/generator.js#L255

というか、そもそも、nuxt.config.js以外から個別に設定の上書きは出来ないっぽい。
(個別で上書き出来る設定と出来ない設定がある)

## hooks を見つける
Nuxt.jsにもhookがあるの？

どうやらhookがあるらしい。
ライフサイクルイベントめっちゃあるじゃん。。
https://qiita.com/teriyakisan/items/bdd7079cf4ab3f285a64
https://ja.nuxtjs.org/api/internals-generator/#%E3%83%95%E3%83%83%E3%82%AF

**そういえば、さっき...**
https://github.com/nuxt/nuxt.js/blob/0ca99426c93e4f5b7579c12675efb4f8fbef3f8b/lib/builder/generator.js#L264

**ここでhookを設定している。**

```
await this.nuxt.callHook('generate:page', page)
```
## hooks を設定してみる

```javascript:nuxt.config.js

// ファイル名を変えたいパス
const changeDirArray = [
  '/fruit/apple',
  '/fruit/banana',
  '/fruit/orange'
]

export default {
  .
  .
  .
  hooks: {
    generate: {
      page(generator) { // 色々あるけど今回はpage hook
        // generator.path にそれぞれのファイルのパス情報が入っている
        const result = changeDirArray.find(path => generator.route === path)
        if (result) { // 配列にあるパスだけ拡張子つける
          generator.path = result + '.html'
        }
        return generator
      }
    }
  }
}
```

これで、頼むな。。

```
npm run generate
```
....

```
dist
├── fruit
│   ├── apple.html
│   ├── banana.html
│   └── orange.html
├── hoge
│   └── index.html
└── index.html

```
:relaxed: 出来た！

でも、まだ終わりではなかった、、、

## 開発サーバーのルーティングにも対応する

先ほどの設定は、あくまで **generate** 時のお話なので
開発中のサーバーでurlを叩くと普通に404になります。

localhost:3000/fruit/apple.html

なので、、、 routerの設定もしてあげましょう。。

```javascript:nuxt.config.js

// ファイル名を変えたいパス
const changeDirArray = [
  '/fruit/apple',
  '/fruit/banana',
  '/fruit/orange'
]

// 環境変数 開発中とそれ以外で処理を分けたい
const dev = process.env.NODE_DEVELOPMENT === 'dev'

export default {
  .
  .
  .
  router: {
    extendRoutes(routes) {
      // routes には vueファイルのそれぞれのrouteのルールの配列が格納されている
      if (dev) { 
　　　　 // routerの設定を元に generateもしているらしいので
        // 開発中のみにしないと、 generateの際にエラーになる        
        changeDirArray.forEach(path => { // エイリアスを設定 .htmlでアクセスしても表示される
          routes.push({
            path: path + '.html',
            alias: path,
            component: '@/pages/' + path + '.vue' //ここはコンポーネントのパス
          })
        })
      }
    }
  },
  hooks: {
    generate: {
      page(generator) { // 色々あるけど今回はpage hook
        // generator.path にそれぞれのファイルのパス情報が入っている
        const result = changeDirArray.find(path => generator.route === path)
        if (result) { // 配列にあるパスだけ拡張子つける
          generator.path = result + '.html'
        }
        return generator
      }
    }
  }
}
```

ここまでで、４時間くらい使った。。:cold_sweat:

## 最後に
Nuxt.jsは 機能面も素晴らしいし、
ドキュメントもしっかり更新されていて結構普及してるイメージなので、とてもおすすめです。
でも、今回のように以外に簡単なことが出来なかったりということもあります。

JSがそこそこ書けて、ドキュメントをしっかり読めば、自由にカスタマイズ出来るかなーというイメージです。
どんな案件にも良いというわけではないですが、これからも機会があればどんどん使っていきたいです。