Posez votre question et obtenez un résumé du document en referencant cette page et le Provider AI de votre choix
Le contenu de cette page a été traduit à l'aide d'une IA.
Voir la dernière version du contenu original en anglaisSi vous avez une idée d’amélioration pour améliorer cette documentation, n’hésitez pas à contribuer en submitant une pull request sur GitHub.
Lien GitHub de la documentationCopier le Markdown du doc dans le presse-papiers
vue-i18n VS @intlayer/vue-i18n | Même API, Bundle différent
@intlayer/vue-i18n est un adaptateur de compatibilité : il expose l'API vue-i18n (createI18n, useI18n, t(), d(), n(), $t, v-t, i18n.global.locale...) et la sert à partir des dictionnaires compilés par Intlayer. Vos fichiers .vue ne changent pas. Ce à quoi t("footer.github") est lié, si.
Cet article mesure ce changement sur la même application Vite + Vue 3, compilée une fois avec vue-i18n et une fois avec l'adaptateur. Les chiffres proviennent de Benchmark Bloom. Pour vue-i18n et Intlayer comparés en tant que bibliothèques, lisez vue-i18n vs Intlayer et le benchmark vue-i18n vs Intlayer. Celui-ci porte sur ce que l'adaptateur change lorsque vous conservez vos composants tels qu'ils sont.
tl;dr: Sur la même app Vite + Vue 3, remplacervue-i18npar@intlayer/vue-i18na réduit le JavaScript par page de 134.9 KB à 47.0 KB gzip (l'app sans i18n pèse 41.3 KB), le runtime de 24.3 KB à 7.9 KB, le composant moyen de 196 KB à 8.4 KB, et les fuites de chaînes de caractères cross-page de 90% à 0%, sans éditer aucun fichier.vue.createI18n({ messages })continue de fonctionner comme fallback ; supprimez les imports JSON pour obtenir les chiffres ci-dessus. Les blocs SFC<i18n>et lesetLocaleMessage()au runtime sont les deux features qui ne sont pas supportées.
Ce qu'est @intlayer/vue-i18n
vue-i18n est un runtime. createI18n({ messages: { en, fr, ... } }) construit une instance globale contenant chaque message de chaque locale ; useI18n() lie chaque composant à celle-ci ; t("footer.github") parcourt l'arborescence au moment du rendu. Cette conception est ce qui rend possible les blocs SFC <i18n> et setLocaleMessage(), et c'est aussi pourquoi le graphe de dépendances de chaque composant inclut l'arborescence entière.
@intlayer/vue-i18n conserve l'API et remplace l'arborescence :
- Import aliasing.
vueI18nVitePlugin()provenant de@intlayer/vue-i18n/pluginenveloppevite-intlayeret ajoute unresolve.aliasafin quevue-i18nse résolve en@intlayer/vue-i18n. Aucune importation n'est renommée. - JSON as source of truth. The
syncJSONplugin reads your existinglocales/{locale}.jsonwithformat: "vue-i18n"(so{name},{0}list interpolation and"car | cars"pipe plurals are parsed correctly) and writes translations back when the CLI or the CMS updates them. - Call-site binding. The Intlayer optimize pass rewrites
useI18n()call sites so the component receives the dictionaries its keys name, in the active locale, as imports the bundler can trace and split.
Copier le code dans le presse-papiers
Copier le code dans le presse-papiers
Le composant n'accède plus à l'arborescence globale des messages. Il accède à footer. C'est pourquoi la colonne taille du composant ci-dessous chute de 196 KB à 8 KB.
Ce que l'adaptateur conserve, ignore et ne remplace pas
Ouvrir le tableau dans une fenêtre modale pour voir tout le contenu clairement
vue-i18n API | Avec @intlayer/vue-i18n |
|---|---|
useI18n() → { t, d, n, te, tm, rt, locale, availableLocales } | ✅ Conservé. Les clés t sont typées par rapport à vos dictionnaires |
t("key", { name }), t("key", [a, b]), t("key", count) | ✅ Conservé. {name}, {0} et les pluriels séparés par des pipes se résolvent comme avant |
d(date, "long"), n(value, "currency") | ✅ Conservé. Les datetimeFormats / numberFormats issus de createI18n() sont respectés, soutenus par Intl natif |
i18n.global.locale.value = "fr" | ✅ Conservé. Une WritableComputedRef soutenue par le client d'Intlayer ; la réactivité se comporte comme avant |
$t, $tc, $te, $tm, $rt, $d, $n, $i18n (Options API) | ✅ Conservé. Enregistré sur app.config.globalProperties par app.use(i18n) |
v-t directive | ✅ Conservé |
legacy: true | ✅ Accepté |
createI18n({ messages }) | ⚠️ messages sont utilisés comme fallback à l'exécution avec un avertissement de développement. Supprimez les imports JSON pour les gains de bundle |
setLocaleMessage(), mergeLocaleMessage() | ❌ Avertissement et ne fait rien. Le chargement des messages à l'exécution est remplacé par des dictionnaires au moment de la compilation |
SFC <i18n> custom blocks | ❌ Non lu. Déplacez ces messages dans le JSON de localisation (ou un .content.ts à côté du composant) |
@nuxtjs/i18n | ⚠️ Adaptateur séparé, voir la documentation de compatibilité Nuxt |
Le benchmark
Ce qui a été mesuré
La suite Benchmark Bloom construit la même application Vite + Vue 3 avec chaque configuration : 10 pages (accueil, à propos, blog, carrières, contact, FAQ, tarification, produits, paramètres, équipe), 10 locales (en, fr, es, de, it, pt, zh, ja, ko, ru), des composants identiques et un contenu identique. Les pages sont mesurées en en et fr.
Les deux ont été construits dans la configuration statique, celle que la plupart des projets Vue livrent : pour vue-i18n, chaque JSON de locale importé et passé à createI18n({ messages }); pour l'adaptateur, les mêmes composants avec vite.config.ts et intlayer.config.ts modifiés et l'import messages supprimé. Le natif vue-intlayer est inclus pour référence.
Pour chaque build, la suite enregistre :
- Lib size : taille gzip (et minifiée) d'un composant vide qui importe uniquement la bibliothèque i18n.
- Page JS : JavaScript gzip téléchargé par page, moyenné sur toutes les pages et locales.
- Locale leak % : part des chaînes traduites dans le JS téléchargé qui appartiennent à une locale que l'utilisateur n'est pas en train de consulter.
- Page leak % : part des chaînes traduites dans le JS téléchargé qui appartiennent à une page sur laquelle l'utilisateur n'est pas.
- Component avg : taille gzip moyenne de chaque composant compilé de manière isolée.
- E2E reactivity : temps écoulé entre la sélection d'une nouvelle locale et la mise à jour de
html[lang]dans le DOM (Playwright, 5 itérations). - Page load :
PerformanceNavigationTiming.duration.
Les chiffres ci-dessous proviennent de l'exécution datée du 12-09-2026 avecvue-i18n11.4.0 et@intlayer/vue-i18n9.5.1. L'application de test est volontairement petite (quelques dizaines de chaînes par locale), donc les pourcentages de fuite décrivent un modèle : ils augmentent avec votre contenu tandis que le coût d'exécution reste fixe.
Résultats sur Vite + Vue 3
Ouvrir le tableau dans une fenêtre modale pour voir tout le contenu clairement
| Configuration | Stratégie | Taille Lib (gz) | Taille Lib (min) | Moyenne Page JS (gz) | Fuite de locale | Fuite de page | Moyenne Component (gz) | Réactivité E2E | Chargement de page |
|---|---|---|---|---|---|---|---|---|---|
| base (no i18n) | - | 0.0 KB | 0.0 KB | 41.3 KB | 0.0% | - | 1.1 KB | 1.8 ms | 10.8 ms |
vue-i18n | static | 24.3 KB | 83.2 KB | 134.9 KB | 50.0% | 90.0% | 196.0 KB | 2.8 ms | 13.6 ms |
@intlayer/vue-i18n | static | 7.9 KB | 23.2 KB | 47.0 KB | 15.0% | 0.0% | 8.4 KB | 1.5 ms | 9.3 ms |
vue-intlayer (native) | static | 3.9 KB | 11.1 KB | 57.1 KB | 56.8% | 0.0% | 7.7 KB | 4.5 ms | 13.8 ms |
vue-intlayer (native) | dynamic | 3.9 KB | 11.1 KB | 59.8 KB | 50.0% | 0.0% | 6.5 KB | 4.0 ms | 15.8 ms |
La colonne page-leak de l'application de base est laissée vide : sans bibliothèque i18n, l'empreinte digitale détecte les chaînes codées en dur dans les chunks partagés et le nombre n'est pas significatif.
Comment le lire
- 88 KB de moins par page, mêmes composants.
vue-i18nprend l'application de 41.3 KB à 134.9 KB. La build de l'adaptateur des mêmes composants atterrit à 47.0 KB, 5.7 KB au-dessus de l'application de base. La plupart de la différence est les 74.9 KB desrc/localesquecreateI18n({ messages })intègre dans chaque page et que l'adaptateur ne regroupe jamais en bloc. - Le runtime se réduit 3x. Un composant vide qui importe seulement
vue-i18ncoûte 24.3 KB gzip / 83.2 KB minifié :@intlify/core-base, le compilateur de messages et le runtime. L'adapter coûte 7.9 KB / 23.2 KB, la plupart étant le core d'Intlayer plus la surface APIvue-i18n. - Composants : 23x plus petits. Un composant
useI18n()compilé en isolation fait en moyenne 196 KB, parce quetest lié à l'instance qui contient chaque message de chaque locale. Avec l'adapter, le même composant fait en moyenne 8.4 KB : il accède à son propre dictionnaire. - Fuite.
vue-i18nenvoie chaque locale et les strings de chaque page sur chaque page : 50% de fuite de locale (sur les deux locales avec empreinte ; avec dix locales bundlées, le vrai gaspillage est plus élevé), 90% de fuite de page. L'adapter réduit la fuite de page à 0% parce que chaque composant n'importe que ses dictionnaires. La fuite de locale s'élève à 15% dans cette exécutionstatic;importMode: 'dynamic'est le paramètre qui la supprime, et cette configuration ne faisait pas partie de cette exécution Vue. - Réactivité et chargement de page. Le changement de locale est peu coûteux pour les deux (1,5-2,8 ms) ; le système de réactivité de Vue le rend possible une fois que les messages sont en mémoire. Le chargement de page passe de 13,6 ms à 9,3 ms, en ligne avec 88 KB de JavaScript en moins à analyser.
- À propos des lignes natives.
vue-intlayerdans cette exécution a regroupé chaque locale en modestaticet a atteint 57,1 KB avec un runtime de 3,9 KB ; les dictionnaires synchronisés de l'adaptateur contenaient moins de chaînes de locale étrangère, d'où la figure inférieure par page. Le runtime natif reste le plus léger des trois, et son modèle.content.tsest l'équivalent des blocs SFC<i18n>.
Pourquoi les chiffres changent
Rien dans src/components/ n'a changé, donc les gains proviennent de ce à quoi useI18n est lié.
Avec vue-i18n, la liaison est l'instance globale. createI18n({ messages: { en, fr, ... } }) est une seule importation qui contient tout ; chaque composant qui appelle useI18n() peut y accéder en entier, donc le bundler ne peut pas diviser en dessous de l'instance. L'optimisation signifie que vous divisez en.json par route, appelez setLocaleMessage() dans un garde de routeur, et gardez la carte route-vers-fichier correcte au fur et à mesure que les composants se déplacent.
Copier le code dans le presse-papiers
Avec @intlayer/vue-i18n, la liaison est le dictionnaire. syncJSON transforme chaque clé de premier niveau de en.json en dictionnaire; la passe d'optimisation fournit au composant ceux dont les clés sont nommées, en tant qu'imports que le bundler trace et divise par page.
Copier le code dans le presse-papiers
L'import messages dans i18n.ts est la seule ligne à supprimer. C'est les 88 KB.
Migration en trois étapes
Installer
Copier le code dans le presse-papiers
La commande détecte vue-i18n, installe intlayer, vue-intlayer, @intlayer/vue-i18n et @intlayer/sync-json-plugin, et pré-remplit intlayer.config.ts. Gardez vue-i18n installé : c'est une peer dependency et elle fournit les types.
Pointer Intlayer vers vos fichiers de locale
Copier le code dans le presse-papiers
locales/{locale}.json reste à sa place. Chaque clé de haut niveau (footer, hero...) devient un dictionnaire.
Ajouter le plugin et supprimer l'importation des messages
Copier le code dans le presse-papiers
Copier le code dans le presse-papiers
vueI18nVitePlugin() enveloppe vite-intlayer (surveillance du contenu, compilation du dictionnaire, l'étape d'optimisation) et crée un alias de vue-i18n vers l'adaptateur. La suppression de l'importation messages est ce qui réduit les 88 KB ; la laisser conserve le fonctionnement de l'application mais expédie les deux.
Ce que vous pouvez supprimer par la suite
Ouvrir le tableau dans une fenêtre modale pour voir tout le contenu clairement
| Fichier / pattern | Pourquoi |
|---|---|
import en from "./locales/en.json" et consorts | Utilisé uniquement comme fallback par l'adaptateur. C'est là que venaient les 88 KB |
setLocaleMessage() dans les gardes de router | Sans effet. Le chargement par route est maintenant le travail du compilateur |
@intlify/unplugin-vue-i18n | Non nécessaire : il précompile les messages et les blocs SFC que l'adaptateur ne lit pas |
Blocs SFC <i18n> | Non lus ; déplacez-les vers le JSON des locales ou vers un .content.ts par composant |
Ce que vous gagnez au-delà des octets
- Clés typées.
t("footer.github")est typé par rapport au dictionnairefootercompilé ; un mauvais chemin est une erreur TypeScript au lieu que la clé soit rendue comme texte. npx intlayer testéchoue dans CI si une clé manque dans n'importe quelle locale.npx intlayer filltraduit les clés manquantes avec votre propre clé de fournisseur (OpenAI, Anthropic, Mistral, Gemini...) et les réécrit danslocales/{locale}.json.- Visual Editor et CMS opèrent sur le même JSON, donc les non-développeurs éditent via une interface utilisateur et les fichiers se mettent à jour.
- Passage progressif à
.content.ts. Tout composant peut passer deuseI18n()àuseIntlayer("footer")avec un fichier de contenu co-localisé. Les dictionnaires JSON et.content.tscoexistent et fusionnent.
Limitations à connaître avant de commencer
- Les blocs SFC
<i18n>ne sont pas lus. Si vos messages se trouvent à l'intérieur des composants, ils doivent être déplacés vers les fichiers de locale (ou vers.content.ts, qui est la même idée avec les types). - Le chargement des messages à l'exécution a disparu.
setLocaleMessage()etmergeLocaleMessage()avertissent et retournent. Les traductions récupérées d'un CMS à l'exécution nécessitent le CMS d'Intlayer, ou les commandesintlayer pull/push. messagesest un fallback, pas gratuit. Garder les imports JSON danscreateI18n()maintient les 75 KB dans le bundle. Supprimez-les une fois queintlayer testpasse.- L'adaptateur n'est pas le runtime natif. 7.9 KB contre 3.9 KB pour
vue-intlayer. Une fois que chaque composant a migré versuseIntlayer, supprimez-le.
Quand utiliser quoi ?
- Restez sur
vue-i18nsi votre app dépend des blocs SFC<i18n>, des flux runtimesetLocaleMessage(), ou si 90 KB par page n'est pas une préoccupation pour votre audience. - Utilisez
@intlayer/vue-i18nsi vous êtes survue-i18net souhaitez les 88 KB économisés, les composants 23x plus petits, 0% de fuite de page, les clés typées et les vérifications CI sans éditer un fichier.vue. C'est le point d'entrée pour une codebasevue-i18nexistante. - Allez au natif (
vue-intlayer) pour les nouveaux projets, ou une fois que l'adaptateur a fait son travail. Il dispose du runtime le plus léger (3.9 KB) et du modèle.content.tspar composant qui remplace les blocs<i18n>par du contenu typé.
Comparaisons associées
- vue-i18n vs Intlayer (features et DX)
- vue-i18n vs Intlayer benchmark (les libraries, même benchmark)
- next-intl vs @intlayer/next-intl (même série d'adapter)
- i18next vs @intlayer/i18next (même série d'adapter)
- Lingui vs @intlayer/lingui (même série d'adapter)
- Guide de migration : vue-i18n vers Intlayer
- Référence de l'adaptateur de compatibilité : vue-i18n, Nuxt i18n
Conclusion
@intlayer/vue-i18n change ce à quoi useI18n() est lié : d'une instance globale contenant chaque message de chaque locale à un dictionnaire compilé pour ce composant. Sur la même application Vite + Vue 3 qui est 88 KB moins lourde par page, un runtime 3x plus petit, des composants 23x plus petits et 0% de fuite de page, pour un fichier de configuration, une ligne de plugin et une importation supprimée. Les blocs SFC <i18n> et le chargement de messages au runtime sont les deux choses qu'il ne gère pas, et le runtime vue-intlayer natif reste moitié moins volumineux.
Toutes les données brutes, les applications de test et les scripts se trouvent dans le référentiel Benchmark Bloom. Exécutez-le vous-même.
Reportez-vous à la documentation 'Pourquoi Intlayer ?' pour plus de détails.
Commentaires
Aucun commentaire pour le moment. Soyez le premier à partager vos pensées.
