概要
Storybookを使わず、Nuxt.jsでコンポーネントカタログを自前で作った話です。
Storybookを使わなかった主な理由
- Storybookを使うと、Nuxt.js用のConfigとは別にWebpack Configを作成・保守する必要が生じる
- 単純にコンポーネントを一覧で見れるだけで、欲しい機能として十分だった
実装
本記事で紹介する実装は次のリポジトリにあります。
https://github.com/AmatsukiKu/nuxt-catalog-sample
カタログページを元々のアプリケーション(以降、本体とする)とは別にNuxtを使ったアプリケーションとして作成します。
Nuxt.js用のConfigを使い回す
本体用のnuxt.config.jsを読み込み、srcDirを書き換えたnuxt.config.jsを用意します。
// @/catalog/nuxt.config.js
import nuxtMainConfig from '../nuxt.config'
nuxtMainConfig.srcDir = 'catalog/'
module.exports = nuxtMainConfig
package.jsonにカタログ用に作ったnuxt.config.jsを参照するコマンドを追加します。
// package.json
{
// ...
"scripts": {
// ...
"catalog": "nuxt --config-file ./catalog/nuxt.config.js -p 9001"
},
// ...
}
カタログ用のページを作成する
catalogディレクトリ配下に普段のNuxt.jsでの開発と同じようpagesディレクトリと、ページコンポーネントを作成します。
<template>
<!-- @/catalog/pages/index.vue -->
<section class="container">
<div>
<h1 class="title">
Nuxt Catalog Page
</h1>
<link-button to="/">Default</link-button>
<link-button to="/" theme="red">Red</link-button>
<link-button to="/" theme="blue">Blue</link-button>
<link-button to="/" theme="black">Black</link-button>
<link-button to="/" theme="blue" :disabled="true">Disabled</link-button>
</div>
</section>
</template>
<script>
import LinkButton from '@/components/LinkButton.vue'
export default {
components: {
LinkButton
}
}
</script>
<style>
// ...
</style>
ここで参照しているLikeButtonコンポーネントは本体側で実装されたコンポーネントです。
元のnuxt.config.jsを少し手直しする
今までの実装で十分動作しそうですが、実際にはパス内の@
や~
のaliasの解決に失敗します。
これは、Nuxt.jsのソースコード内で利用されるWebpack Configを見てみるとわかるのですが、これらのaliasの解決にsrcDir参照していること原因です。
なので、aliasの解決方法をnuxt.config.js側で上書きます。
const path = require('path')
module.exports = {
// ...
build: {
extend(config, ctx) {
config.resolve.alias['~'] = path.join(__dirname, './')
config.resolve.alias['@'] = path.join(__dirname, './')
}
}
}
これでカタログ側でsrcDirを変更してもaliasの解決方法は変わりません。
結果
yarn catalog
まとめ
最低限のConfigの変更で、コマンドで本体とカタログの立ち上げを切り替えられるようにしました。
補足
本体側でmodulesやpluginsを利用している場合には、カタログページの立ち上げにも、それらの実装が要求されます。
その場合はシンボリックリンクを使うと、再実装することなく、カタログページを立ち上げることができます。