Skip to content
i18n 문서로 돌아가기

eslint-plugin-i18n

도구
@hua-labs/eslint-plugin-i18n

i18n 타입 안전성을 위한 ESLint 플러그인 — 누락된 키, 하드코딩된 텍스트, 미번역 필드를 린트 시점에 감지합니다. CLI로 프로젝트 전체 분석도 가능합니다.

설치

Terminalbash
npm install @hua-labs/eslint-plugin-i18n
Importtsx
import { eslint-plugin-i18n } from '@hua-labs/eslint-plugin-i18n';

규칙

i18n/no-missing-key
error

생성된 타입 파일에 없는 키로 t()를 호출하면 감지합니다. did-you-mean으로 유사한 키를 최대 3개까지 제안합니다.

no-missing-key.tsxtsx
// ❌ Error + did-you-mean suggestion
t('common:welcom')
// → Did you mean: "common:welcome"?

// ✅ OK
t('common:welcome')
i18n/no-unlocalized-field
warn

description, label, value 등 객체 필드에 i18n 키 대신 일반 문자열이 들어있으면 감지합니다. 메타데이터 레지스트리 파일에 필수적입니다.

no-unlocalized-field.tsxtsx
// ❌ Warn: literal string instead of i18n key
{ description: "Visual style variant" }

// ✅ OK
{ description: "docs:components.badge.props.variant" }
i18n/no-raw-text
warn

JSX에 하드코딩된 CJK 텍스트를 감지합니다. translationsDir 설정 시 역참조 맵으로 정확한 번역 키를 추천합니다. ignorePattern으로 카운터 등을 제외할 수 있습니다.

no-raw-text.tsxtsx
// ❌ Warn + key suggestion (with translationsDir)
<Button>저장</Button>
// → Use t('common:actions.save') instead

// ✅ OK
<Button>{t('common:actions.save')}</Button>

// ignorePattern: "^\\d+[가-힣]$"
<span>3건</span>  // ← ignored
i18n/no-dynamic-key
warn

t()에 정적 문자열 대신 변수나 템플릿 리터럴이 전달되면 경고합니다. 정적 키는 타입 체크와 미사용 키 감지를 가능하게 합니다.

no-dynamic-key.tsxtsx
// ❌ Warn: dynamic key
t(`${namespace}:key`)

// ✅ OK: static literal
t('common:welcome')
i18n/prefer-common-key
warn

다른 네임스페이스의 키 값이 common에도 존재하면 common 키 사용을 권유합니다. 번역 중복을 줄이고 일관성을 높입니다.

prefer-common-key.tsxtsx
// ❌ Warn: same value exists in common
t('diary:save_button')
// → Prefer "common:actions.save"

// ✅ OK: using common namespace
t('common:actions.save')
i18n/no-unused-key
info

JSON 파일의 번역 키가 코드에서 참조되지 않으면 감지합니다. 실시간 린팅보다 CLI 사용을 권장합니다.

no-unused-key.tsxtsx
// CLI usage recommended
i18n-lint unused-keys --translations-dir ./lib/translations \
  --source-dir ./app

설정

eslint.config.mjsjs
// eslint.config.mjs
import i18nPlugin from '@hua-labs/eslint-plugin-i18n';

export default [
  {
    plugins: { i18n: i18nPlugin },
    rules: {
      'i18n/no-missing-key': ['error', {
        keysFile: './types/i18n-types.generated.ts',
      }],
      'i18n/no-raw-text': ['warn', {
        translationsDir: './lib/translations',
        ignorePattern: '^\\d+[가-힣]$',
      }],
      'i18n/no-dynamic-key': 'warn',
      'i18n/prefer-common-key': ['warn', {
        translationsDir: './lib/translations',
      }],
    },
  },
  // Metadata files — validate i18n key format
  {
    files: ['registry/**/*.ts'],
    plugins: { i18n: i18nPlugin },
    rules: {
      'i18n/no-unlocalized-field': ['warn', {
        fields: ['description', 'label', 'value'],
        ignoreParentProperties: ['codeExamples'],
      }],
    },
  },
];

타입 생성

no-missing-key 규칙은 생성된 타입 파일이 필요합니다. i18n-core의 생성 스크립트를 사용하여 번역 JSON 파일에서 타입을 생성하세요.

terminalbash
# Generate i18n types for no-missing-key
pnpm --filter @hua-labs/i18n-core generate:types \
  --translations-dir apps/my-app/lib/translations/ko \
  --output apps/my-app/types/i18n-types.generated.ts

CLI (i18n-lint)

프로젝트 전체를 분석하는 CLI 도구입니다. 미사용 키 감지, common 네임스페이스 통합 후보, 언어 간 누락 번역을 리포트합니다.

unused-keys— 소스 코드에서 사용되지 않는 번역 키를 찾습니다
common-report— common 네임스페이스로 통합 가능한 중복 값을 찾습니다
missing— 언어 간 누락된 번역을 찾습니다
terminalbash
# Find unused translation keys
i18n-lint unused-keys \
  --translations-dir ./lib/translations \
  --source-dir ./app

# Find values that can be consolidated into common namespace
i18n-lint common-report \
  --translations-dir ./lib/translations

# Find translations missing across languages
i18n-lint missing \
  --translations-dir ./lib/translations \
  --languages en,ja

# JSON output for CI integration
i18n-lint unused-keys \
  --translations-dir ./lib/translations \
  --source-dir ./app \
  --format json

API 레퍼런스

옵션

이름타입기본값설명
keysFile*string-Path to generated i18n-types file (no-missing-key)
translationsDirstring-Path to translations directory (no-raw-text, prefer-common-key)
functionNamesstring[]["t", "tArray"]Function names to check
ignorePatternstring-Regex pattern for text to ignore (no-raw-text)
defaultLanguagestringkoDefault language for translation lookup
commonNamespacestringcommonCommon namespace name (prefer-common-key)

사용 사례