
번역 파일 동기화: 로케일 간 i18n 키를 일관되게 유지하는 방법
개발자가 원본 로케일에 키를 추가할 때마다 다른 로케일 파일 15개의 동기화가 깨져요. 누락된 키는 사용자에게 원시 경로를 보여 주고 오래된 키는 번역가의 시간을 낭비하며 번들 크기를 불필요하게 늘려요. 자동 동기화로 모든 항목을 일치시키세요.
동기화 문제
번역 파일은 계속 서로 어긋나요. 한 개발자가 en.json에 'settings.notifications.title'을 추가하지만 다른 로케일 파일 15개에는 추가하지 않아요. 다른 개발자는 코드에서 'onboarding.welcome'을 삭제하지만 모든 로케일 파일에는 남겨 둬요. 또 다른 개발자는 영어에서 'user.name'을 'user.displayName'으로 바꾸지만 다른 로케일에서는 바꾸지 않아요. 몇 달이 지나면 로케일마다 키가 누락되거나 오래되거나 서로 일치하지 않게 돼요.
// The problem: translation files drift out of sync
// Developer adds a new feature with new keys:
// en.json (source of truth)
{
"nav.home": "Home",
"nav.about": "About",
"nav.pricing": "Pricing", // NEW
"nav.changelog": "Changelog" // NEW
}
// de.json (out of sync - missing new keys)
{
"nav.home": "Startseite",
"nav.about": "Über uns"
// nav.pricing - MISSING
// nav.changelog - MISSING
}
// de.json also has stale keys from deleted features:
{
"nav.home": "Startseite",
"nav.about": "Über uns",
"nav.legacy_page": "Alte Seite" // STALE - removed from en.json
}누락된 키 감지
누락된 키는 원본 로케일에는 있지만 대상 로케일에는 없는 키예요. 가장 흔하고 피해가 큰 동기화 문제예요. 사용자에게 번역 텍스트 대신 'settings.notifications.title' 같은 원시 키 경로가 보여요. i18n-validate는 각 로케일의 키 구조를 원본과 비교해 누락된 키를 찾아요.
# Detect missing and stale keys
npx i18n-validate sync \
--source locales/en.json \
--targets 'locales/*.json'
# Output:
# locales/de.json:
# Missing keys (2):
# - nav.pricing
# - nav.changelog
# Stale keys (1):
# - nav.legacy_page
# Coverage: 66.7% (2/3 keys)
#
# locales/ja.json:
# Missing keys (5):
# - nav.pricing
# - nav.changelog
# - settings.theme
# - settings.language
# - settings.notifications
# Coverage: 50.0% (5/10 keys)오래된 키 감지
오래된 키는 번역 파일에는 있지만 코드에서 더 이상 참조하지 않는 키예요. 아무도 보지 않는 문자열을 번역하게 해 번역가의 시간을 낭비하고 번들 크기를 늘리며 유지 관리를 복잡하게 해요. 오래된 키를 찾으려면 로케일 파일과 코드 참조를 교차 확인해야 해요.
# Step 1: Check which files are out of sync
npx i18n-validate sync --source locales/en.json --targets 'locales/*.json'
# Step 2: Auto-fill missing keys with source values (as placeholders)
npx i18n-validate sync \
--source locales/en.json \
--targets 'locales/*.json' \
--fill-missing \
--fill-value "[NEEDS TRANSLATION] {{source}}"
# Step 3: Remove stale keys no longer in source
npx i18n-validate sync \
--source locales/en.json \
--targets 'locales/*.json' \
--remove-stale
# Step 4: Sort keys to match source order (cleaner diffs)
npx i18n-validate sync \
--source locales/en.json \
--targets 'locales/*.json' \
--sort-keys
# All at once:
npx i18n-validate sync \
--source locales/en.json \
--targets 'locales/*.json' \
--fill-missing \
--remove-stale \
--sort-keys동기화 자동화
가장 효과적인 동기화 전략은 세 계층을 결합해요. 1) 커밋마다 동기화를 검증하는 pre-commit 훅. 2) 동기화 문제가 있으면 병합을 차단하는 CI 파이프라인 검사. 3) 긴급 수정과 수동 편집으로 누적된 차이를 찾는 정기적인 전체 점검.
# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# Check if source locale file changed
SOURCE_CHANGED=$(git diff --cached --name-only | grep -c 'locales/en.json')
if [ "$SOURCE_CHANGED" -gt 0 ]; then
echo "Source locale changed - checking sync..."
npx i18n-validate sync \
--source locales/en.json \
--targets 'locales/*.json' \
--fail-on-missing \
--min-coverage 90
if [ $? -ne 0 ]; then
echo ""
echo "Translation files are out of sync!"
echo "Run: npx i18n-validate sync --fill-missing"
exit 1
fi
fi# .github/workflows/i18n-sync.yml
name: Translation Sync Check
on:
pull_request:
paths:
- 'locales/**'
jobs:
sync-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check translation sync
run: npx i18n-validate sync \
--source locales/en.json \
--targets 'locales/*.json' \
--fail-on-missing \
--min-coverage 95
- name: Comment on PR if out of sync
if: failure()
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: 'Translation files are out of sync. Please run npx i18n-validate sync --fill-missing and commit.'
})번역률 보고
번역률은 각 대상 로케일에서 번역된 원본 키의 비율이에요. i18n-validate는 로케일별 번역률을 보여 주고 뒤처지는 로케일을 강조하는 보고서를 생성해요. CI에 번역률 임곗값을 설정하면 허용 수준 아래로 떨어질 때 병합을 차단할 수 있어요.
// Split large translation files by feature/namespace
// locales/
// ├── en/
// │ ├── common.json (nav, footer, errors)
// │ ├── auth.json (login, register, reset)
// │ ├── dashboard.json (dashboard-specific)
// │ └── settings.json (settings page)
// ├── de/
// │ ├── common.json
// │ ├── auth.json
// │ ├── dashboard.json
// │ └── settings.json
// Sync with namespace support:
npx i18n-validate sync \
--source 'locales/en/*.json' \
--targets 'locales/*/%.json' \
--namespace-pattern '{locale}/{namespace}.json'
// Benefits:
// - Smaller files, easier to review
// - Feature teams own their translations
// - Lazy-load only needed namespaces
// - Parallel translation workflows지금 i18n Agent 사용해 보기
번역 파일을 여기에 드롭
JSON, YAML, PO, XML, CSV, Markdown, Properties
또는 클릭하여 파일 선택
대상 언어