🦔

Vue3 に向けて - vue-i18n-bridge による移行準備

nuichi2022/08/25に公開

ロンラン株式会社 CEO 兼 CTO の武部です。

この記事は、私たちのチームのように「諸事情でまだ Vue2 を使っているが、Vue3 への移行のための準備はぬかりなく進めたい」方向けです。

前回は、はじめに取り掛かりたい&恩恵の大きい Vite 化対応について記しました。

https://zenn.dev/nuichi/articles/7974bd1101fe9d

今回は Vue-i18n の移行です。

あくまでも移行中のため、次のニーズを満たせるようにします。

  • 新しい実装や移行対象の Vue ファイル:setup script または Composition API での setup() を前提とし、t を使い $t はもう使わない
  • それ以外:何も触る必要なし。$t そのまま使い、コード移行の順番を待つ

では早速はじめてゆきましょう!

パッケージ構成

あらためて確認ですが、今回は次のパッケージとバージョンで構成します。

  • Vue2
  • Vue-i18n@8
  • vue-i18n-bridge

Vue-i18n そのものは、8.x 系から 9 系へアップデートしないように気をつけましょう。

vue-i18n-bridge の導入

今回の主役、vue-i18n-bridge をインストールします。

yarn add vue-i18n-bridge

Weekly Downloads が伸びまくっていますね。同じように Vue3 移行準備を進めているプロジェクトが多いのかなと推察します。

ここから先は、注意深く vue-i18n-bridge と本家 vue-i18n のサイト両方を読み込んでゆくと紹介されている内容で、特殊なことは何ひとつありません。

main.(ts|js) 構成

main.(ts|js) が TypeScript か JavaScript かで少し異なります。

TS の場合は、castToVueI18n() しておかないと new Vue() 内で型エラーが出てしまいます。JS の場合は不要です。

import VueI18n from 'vue-i18n'
import { createI18n, castToVueI18n } from 'vue-i18n-bridge'
import i18nConfig from './your-i18n-config'

Vue.use(VueI18n, { bridge: true })
const i18n = castToVueI18n(createI18n(i18nConfig, VueI18n))
Vue.use(i18n)  // こちらも Vue.use する

// ...

new Vue({
  i18n,
  store,
  router,
  vuetify,
  // ...
}).$mount('#app')

上記例で createI18n() に渡している i18nConfig は、次のような構造のデータです。

const locales = {
  ja: {
    // 略
  },
  en: {
    // 略
  },
}

const datetimeFormats = {
  ja: // 略。DateTimeFormat 型
  en: // 略。DateTimeFormat 型
} as DateTimeFormats

const DEFAULT_LANG = navigator.language

const i18nConfig = {
  locale: DEFAULT_LANG,
  legacy: false,
  fallbackLocale: ['ja'],
  messages: locales,
  datetimeFormats,
}

export default i18nConfig

ポイントは次の二点です。

  1. legacy: false で Vue-i18n Legacy API を無効化します。こうしないと $tt は共存できません
  2. Datetime フォーマッタ(すなわち $d / d)を使う場合、dateTimeFormats から datetimeFormats に修正します(違いはよーく見て!)

利用側の Vue コンポーネント

useI18n() を通じて td を取得します。

useI18n() は setup 内でなければ実行できないことに注意してください。

setup script スタイルの場合:

<script setup lang="ts">
import { useI18n } from 'vue-i18n-bridge'

const { t } = useI18n()

Composition API スタイルの場合:

<script lang="ts">
import { useI18n } from 'vue-i18n-bridge'

export default {
  setup () {
    const { t } = useI18n()
    return { t }
  }
}

Datetime フォーマッタも必要なら const { t, d } = useI18n() のようにして取得しましょう。

これで、template 内で t が参照できるようになりました。

<h1>{{ t('messages.featureA.title') }}</h1>

既存のコードで、グローバルスコープの $t$d を使っている箇所に影響が出ていないことも確認しましょう。

おわりに

着々と Vue コンポーネントの修正を進めておければ、将来 Vue3 / Vue-i18n@9 へ移行するタイミングでは、'vue-i18n-bridge''vue-i18n' に一括置換するだけで済みそうですね。

以上です!

参考情報

ロンラン Tech Zenn

ロンランからの Zenn 的技術発信。誰かにとって役に立ちそうな気づきやノウハウをどんどん共有します。

Discussion

ログインするとコメントできます