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