verbatra extract
Analyse le code de ton application à la recherche des appels de traduction et ajoute les nouvelles clés au fichier de la locale source.
Page traduite automatiquement
Disponible à partir de 0.11.0
Toutes les autres commandes partent d'un fichier de locale qui existe déjà. extract est la seule qui part de ton code : elle parcourt les racines de code que tu configures, y trouve les appels de traduction et ajoute chaque clé qui ne figure pas encore dans le fichier de la locale source. C'est ce qui rend verbatra utilisable sur un projet qui n'est pas encore internationalisé, là où le catalogue est précisément ce qui te manque.
Elle ne dépense rien. Aucun fournisseur n'est construit, aucune variable d'environnement contenant une clé d'API n'est lue et aucune requête réseau n'est faite : une exécution sans clé configurée fonctionne donc.
Synopsis
verbatra extract [flags]Configuration
extract est pilotée par le bloc extract de ta config. Une exécution sans ce bloc échoue avec EXTRACT_NOT_CONFIGURED et le code de sortie 2.
import { defineConfig } from "@verbatra/sdk";
export default defineConfig({
sourceLocale: "en",
targetLocales: ["de", "fr"],
format: "i18next-json",
files: { pattern: "locales/{locale}.json" },
provider: { id: "gemini", options: { model: "gemini-2.5-flash", maxOutputTokens: 4096 } },
extract: {
framework: "i18next",
roots: ["src"],
},
});Options
| Option | Argument | Défaut | Effet |
|---|---|---|---|
--cwd | <path> | répertoire courant | résout la config, les racines de code et les fichiers de locale depuis ce répertoire |
--config | <path> | recherche automatique | charge ce fichier de config au lieu d'en chercher un |
--dry-run | aucun | désactivé | signale ce qui serait ajouté sans rien écrire |
--json | aucun | désactivé | affiche une enveloppe JSON sur stdout portant le résultat sous result |
Ce qu'elle trouve
Le framework i18next lit les formes d'appel t(...), $t(...) et <object>.t(...) dans les fichiers .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts et .cts, chacune aussi en appel optionnel et avec une liste explicite d'arguments de type. La clé est le premier argument. Une valeur par défaut est soit le deuxième argument, soit un champ defaultValue sur l'objet d'options :
t("nav.home"); // key only, written with an empty value
t("nav.away", "Away"); // positional default
t("nav.help", { defaultValue: "Help" }); // default on the options object
t?.("nav.back"); // optional call
t<string>("nav.next"); // explicit type argumentLes commentaires, les chaînes et les expressions régulières sont compris : un appel écrit dans un commentaire n'est pas repris, et un t( entre guillemets dans une chaîne ne devient pas une clé.
La clé et la valeur par défaut doivent toutes deux être un littéral complet. t("user." + id) est signalé comme dynamique plutôt qu'écrit sous la clé user., et t("nav.home", { defaultValue: "Home" + suffix }) ajoute la clé sans valeur par défaut plutôt qu'avec une valeur tronquée.
La clé doit aussi nommer un chemin adressable. t("user."), t(".lead") et t("a..b") sont des littéraux complets, mais chacun porte un segment vide, et les formats en arbre découpent une clé sur le . : la clé atterrirait donc sous un enfant sans nom que ton application ne lit jamais. Celles-là sont signalées comme dynamiques elles aussi.
Les espaces de noms ne sont pas encore résolus
Une clé qualifiée par un espace de noms, la forme t("common:nav.home"), est signalée comme dynamique et n'est jamais écrite. Une config verbatra s'adresse à un seul fichier de catalogue : il n'y a donc nulle part où mettre common:nav.home qui veuille dire ce que ta configuration i18next entend par là.
Sache ce que cela coûte avant de la lancer : si ton projet nomme un espace de noms à chaque appel, chaque appel est dynamique et l'exécution n'ajoute rien. C'est volontaire pour cette première version. extract est utile aujourd'hui sur un projet qui s'en tient à un seul espace de noms et écrit ses clés sans le préfixe ; lever cette limite est la première chose prévue après le deuxième framework.
Ce qu'elle écrit
Uniquement le fichier de la locale source, et uniquement les clés réellement nouvelles :
- Une clé déjà présente dans le catalogue conserve sa valeur telle quelle. Une valeur par défaut laissée sur un appel n'écrase jamais une valeur que toi ou un traducteur avez modifiée.
- Une clé du catalogue qu'aucun appel ne mentionne reste intacte.
extractajoute et signale ; elle ne supprime jamais.verbatra diff --unusedliste ces clés. - Une exécution qui ne trouve rien de nouveau n'écrit rien du tout : le fichier reste identique octet pour octet et sa date de modification ne change pas.
- Un fichier de locale cible n'est jamais écrit. Lance
verbatra translateaprèsextractpour remplir les nouvelles clés.
Deux formats ne sont jamais créés à partir de rien, ni ici ni ailleurs dans verbatra : xliff a besoin d'un fichier de destination existant, et apple-xcstrings d'un catalogue créé dans Xcode. Pour ces deux-là, crée d'abord le catalogue source ; extract y ajoute ensuite.
Ce qu'elle signale plutôt que de deviner
Tout ce que l'analyse ne peut pas résoudre revient sous forme de données, pour qu'un fichier récalcitrant n'interrompe jamais l'exécution :
| Signalé comme | Quand |
|---|---|
dynamic | l'argument de la clé n'est pas une seule chaîne statique complète, ou il nomme un chemin que verbatra ne peut pas adresser : une variable, un accès à une propriété, un template literal contenant une expression, une concaténation, une clé qualifiée par un espace de noms ou une clé avec un segment de chemin vide. Elle n'est jamais écrite avec une clé devinée, tronquée ou non adressable. |
conflicts | une clé est trouvée sur deux appels qui ne s'accordent pas sur sa valeur par défaut. Aucune des deux valeurs n'est écrite, car en choisir une ferait dépendre ton catalogue de l'ordre de parcours des répertoires. |
withoutDefault | une clé a été ajoutée avec une valeur vide, parce que son appel ne fournissait aucune valeur par défaut. Remplis-la, puis traduis. |
diagnostics | un fichier ou un répertoire n'a pas pu être lu jusqu'au bout : il a disparu, il dépasse la limite de taille, l'analyse a échoué dessus, un commentaire de bloc ou un template literal non fermé a abandonné le reste, ou, dans un fichier .tsx, .jsx ou .js, un élément JSX n'est jamais fermé ou une chaîne entre guillemets dans le code atteint la fin de sa ligne. Ce qui a été lu avant ce point est tout de même signalé. |
Rien de tout cela ne change le code de sortie. Ce sont des constats, pas des échecs.
Limites de l'analyse
Rien en dehors des roots configurées n'est jamais lu. node_modules, .git, .next, .turbo, .verbatra, dist, build et coverage sont toujours ignorés, et extract.exclude ajoute tes propres noms de répertoire à cet ensemble. Les liens symboliques ne sont pas suivis : un lien ne peut donc pas faire sortir l'analyse d'une racine.
Le résultat ne porte que des clés, des valeurs et des emplacements fichier et ligne. Le contenu d'un fichier source n'y voyage jamais.
Exemples
# add every new key found in your source to the source locale file
verbatra extract
# preview the keys that would be added, write nothing
verbatra extract --dry-run
# machine-readable result for a CI step
verbatra extract --jsonUne exécution ressemble à ceci :
verbatra extract
42 files scanned, 18 keys already present
added 3 keys to locales/en.json
new keys (3):
nav.home src/components/Nav.tsx:14
nav.away src/components/Nav.tsx:15
cart.empty src/routes/cart.tsx:31
dynamic keys (1):
src/routes/product.tsx:88Codes de sortie
| Code | Signification |
|---|---|
0 | l'analyse s'est exécutée, quoi qu'elle ait trouvé |
2 | exécution impossible : une erreur d'utilisation, aucun bloc extract, un format qui ne résout pas, un catalogue source illisible ou un catalogue source qui n'a pas pu être écrit |
Il n'y a pas de code de sortie 1. Les appels dynamiques et les valeurs par défaut en conflit sont signalés, pas traités comme une exécution en échec : extract en CI n'échoue donc que lorsqu'elle n'a vraiment pas pu faire son travail.
Voir aussi
- Le fichier de configuration documente le bloc
extract. verbatra translateremplit les locales cibles une fois les nouvelles clés en place.verbatra checksignale l'écart que les nouvelles clés créent.- Le SDK expose la même capacité sous le nom
extract().