ymmooot

nuxt-i18n module を使ったコンポーネントを Storybook で確認する

nuxt-i18n を使うと Nuxt.js に vue-i18n をインストールした上で、国ごとの routing や meta タグ周りまで面倒を見てくれてとても助かる。
nuxt-i18n を入れたプロジェクトを Storybook 見るときの設定メモ。

Storybook 用の webpack.config.js

Storybook 用の webpack.config.js にカスタムブロック <i18n> の loader を指定する。

webpack.config.jsconfig.module.rules.push({
  resourceQuery: /blockType=i18n/,
  type: 'javascript/auto',
  loader: ['@kazupon/vue-i18n-loader', 'yaml-loader'], // json で書いてあるなら yaml-loader は不要
});

Storybook の config を編集

  • i18n を追加する global mixin
  • ロケール切り替え用の knob を追加する decorator
  • クリック時に to の内容を表示する action を持った nuxt-link のスタブ

を追加する。

config.tsimport Vue from 'vue';
import VueI18n from 'vue-i18n';
import { configure, addDecorator } from '@storybook/vue';
import { withKnobs, select } from '@storybook/addon-knobs';

Vue.use(VueI18n);

Vue.mixin({
  i18n: new VueI18n({ locale: 'sg' }),
  methods: {
    // action で見れるようにそのまま返す
    localePath: (route: RawLocation, locale?: string | undefined) => ({ route, locale }),
  },
});

// ロケール切り替え用の knob を追加
addDecorator(() => ({
  template: `<story/>`,
  props: {
    $storybookLocale: {
      type: String,
      default: select('Locale', ['sg', 'th', 'id'], 'sg'),
    },
  },
  watch: {
    $storybookLocale: {
      handler(locale) {
        this.$i18n.locale = locale;
      },
      immediate: true,
    },
  },
}));

Vue.component('nuxt-link', {
  props: ['to'], // eslint-disable-line vue/require-prop-types
  methods: {
    log() {
      action('nuxt-link to')(this.to)
    },
  },
  template: '<a href="#" @click.prevent="log"><slot/></a>',
})

addDecorator(withKnobs);
// ...以下略
ちゃんと切り替えられてる(文章用意してないので中身日本語だけど)

以上。


refs: