Skip to content

hias-cli Translation Feature Design

Many frontend projects don't fully plan internationalization from the start. After some business development, pages, dialogs, buttons, status messages, and prompts are scattered across Vue, React, JSX, utility functions, and configuration objects. Manual migration at this point is labor-intensive and easy to miss.

hias-cli's translation capability is designed for this stage: it doesn't simply search for Chinese and replace it, but tries to understand syntax boundaries in different files, migrating source language text into internationalization calls and generating maintainable locale files. Source code can be Chinese or English; English source uses stricter UI text identification to avoid mistaking protocol values, class names, paths, and type values for translatable text.

Core Flow

A single hias tf roughly follows four steps:

  1. Read the source file and determine file type.
  2. Extract text based on source language, preserving each text's position in source.
  3. Generate keys, query cache or translation service, write locale files.
  4. Replace Chinese in source file with $t or t calls.

This flow seems straightforward, but the difficulty lies in "text boundaries."

Why Regex Alone Isn't Enough

Chinese can appear in many places:

vue
<button>登录</button>
vue
<input placeholder="请输入用户名" />
jsx
<h1>留言({remarkList ? remarkList.length : 0})</h1>
js
const message = '保存成功'

Their replacement syntax differs. Vue template text needs {{ $t(...) }}, attributes need dynamic binding, JSX text needs {t(...)}, JS strings need expression calls.

Using regex alone easily mishandles file paths, regex expressions, comments, style class names, TypeScript types, and interpolation punctuation.

Cache First

In real projects, machine translation only solves part of the problem. Menu names, status names, button names, and industry terminology usually need consistent expressions.

Therefore hias-cli supports importing company translation tables first:

sh
hias tci .\.hias\company.xlsx

Recommended format:

zh-CNen-USja-JP
登录Loginログイン
正常状态Normal Status正常状態

After import, the cache is organized by language direction:

json
{
  "zh-CN|en-US": {
    "登录": "Login"
  },
  "zh-CN|ja-JP": {
    "登录": "ログイン"
  }
}

This way the translation process prioritizes the human glossary, and calls the translation service or falls back to source text when missing.

Boundary-Oriented Extraction

What really affects the experience in translation migration is often the boundary details.

For example:

vue
<h1>留言({{ remarkList ? remarkList.length : 0 }})</h1>

The ideal result isn't swallowing the left parenthesis into the text:

vue
<h1>{{ $t('demo.leave_a_message') }}{{ remarkList ? remarkList.length : 0 }})</h1>

But rather:

vue
<h1>{{ $t('demo.leave_a_message') }}({{ remarkList ? remarkList.length : 0 }})</h1>

Another example is resource paths:

vue
<img src="@/assets/images/ssHome/供应商总数量.png" alt="供应商总数量" />

src is a file reference and shouldn't be translated; alt is visible semantics and can be translated.

Current extraction further handles:

  • JS/TS/JSX/TSX and Vue SFC
  • Vue <script setup lang="jsx"> and <script setup lang="tsx">
  • Template literals, optional chaining, || and ?? fallback text
  • JSX/TSX text nodes and custom display attributes
  • Vue template display text and display attributes
  • Already processed $t(...), this.$t(...), t(...) are skipped
  • Comments, regex, styles, class/className, style, resource paths, TS type syntax are skipped

When you don't want certain code processed automatically, use:

js
// @hias-i18n-ignore-next

/* @hias-i18n-ignore-start */
/* @hias-i18n-ignore-end */

// @hias-i18n-ignore-file

Reports and Consistency Checks

During batch migration, whether extraction is comprehensive, which files failed, and whether locale files are missing keys all need machine-readable results.

tf / tfo support JSON report output:

sh
hias tfo src\views views --dry-run --report .hias\reports\views.json

After translation, run:

sh
hias tcheck src --report .hias\reports\tcheck.json

It checks for keys referenced in source but missing from locale files, keys present in locale files but unreferenced in source, keys inconsistent across locale JSON files, and unparseable JSON files.

Released under the MIT License.