Posted at

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


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 を設定してみる


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の設定もしてあげましょう。。


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
}
}
}
}


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


最後に

Nuxt.jsは 機能面も素晴らしいし、

ドキュメントもしっかり更新されていて結構普及してるイメージなので、とてもおすすめです。

でも、今回のように以外に簡単なことが出来なかったりということもあります。

JSがそこそこ書けて、ドキュメントをしっかり読めば、自由にカスタマイズ出来るかなーというイメージです。

どんな案件にも良いというわけではないですが、これからも機会があればどんどん使っていきたいです。