Vue3 に向けて - vue-i18n-bridge による移行準備
ロンラン株式会社 CEO 兼 CTO の武部です。
この記事は、私たちのチームのように「諸事情でまだ Vue2 を使っているが、Vue3 への移行のための準備はぬかりなく進めたい」方向けです。
前回は、はじめに取り掛かりたい&恩恵の大きい Vite 化対応について記しました。
今回は 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
ポイントは次の二点です。
-
legacy: falseで Vue-i18n Legacy API を無効化します。こうしないと$tとtは共存できません - Datetime フォーマッタ(すなわち
$d/d)を使う場合、dateTimeFormatsからdatetimeFormatsに修正します(違いはよーく見て!)
利用側の Vue コンポーネント
useI18n() を通じて t や d を取得します。
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' に一括置換するだけで済みそうですね。
以上です!
Discussion