이 페이지와 원하는 AI 어시스턴트를 사용하여 문서를 요약합니다
버전 기록
- "초기 히스토리"v9.3.12026. 8. 12.
이 페이지의 콘텐츠는 AI를 사용하여 번역되었습니다.
영어 원본 내용의 최신 버전을 보기If you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
ESLint x OXLint 플러그인
eslint-plugin-intlayer는 TypeScript가 감지하지 못하는 i18n 실수를 잡아냅니다:
- 사전에 등록되지 않은 하드코딩된 텍스트.
- 타입 검사를 통과하고 실행되지만 Intlayer 컴파일러가 최적화할 수 없는 동적 호출.
- 미사용 콘텐츠(Dead content) — 프로젝트 내에서 아무 곳에서도 읽지 않는 사전 및 필드(선택 사항).
알 수 없는 사전 키, 알 수 없는 필드 경로 및 누락된 로케일은 이미 컴파일 에러로 처리되므로 플러그인은 이를 중복 보고하지 않습니다.
설치
코드를 클립보드에 복사
npm install --save-dev eslint-plugin-intlayerESLint 9 이상(Flat config)이 필요합니다. ESLint 10을 지원합니다.
사용법
이 플러그인은 ESLint와 oxlint 모두에서 동일한 규칙과 옵션으로 실행됩니다.
또는 설정을 펼친 뒤 심각도를 직접 지정할 수 있습니다:
설정 (Configs)
테이블을 모달로 열어 모든 데이터를 명확하게 확인
| 설정 | no-raw-text | static-dictionary-key | no-dynamic-field-access | enforce-adapter-import | no-unused-content |
|---|---|---|---|---|---|
recommended | warn | error | error | off | off |
strict | error (+ 비 JSX 리터럴) | error | error | error | off |
contract-only | off | error | error | off | off |
recommended는 의도적으로 no-raw-text를 warn으로 유지합니다. 기존 코드베이스에 적용했을 때 번역되지 않은 모든 문자열이 한 번에 보고되어 첫날부터 빌드가 중단되는 것을 방지하기 위함입니다.
enforce-adapter-import는 기본적으로 꺼져 있습니다. 필요한 경우 명시적으로 활성화하세요.
no-unused-content는 strict를 포함한 모든 사전 설정에서 꺼져 있습니다. 이 규칙은 Intlayer 설정을 읽고 디스크의 소스 파일을 직접 순회하므로, 사전 설정에 의해 자동으로 켜지기보다는 신중한 선택에 따라 활성화해야 합니다.
규칙
no-raw-text
사전에 선언되지 않은 사용자 대면 텍스트를 보고합니다. intlayer extract와 동일한 감지 방식을 사용하므로 브랜드 이름, CSS 클래스 및 기술적 식별자는 무시됩니다.
코드를 클립보드에 복사
// ✗ 보고됨<h1>Welcome to our documentation</h1><input placeholder="Enter your email address" />// ✓ 정상const { title } = useIntlayer("home");<h1>{title}</h1>콘텐츠 선언 파일(*.content.ts, …)은 제외됩니다.
파일 전체를 한 번에 수정하려면 npx intlayer extract를 실행하여 컴파일러가 문자열을 사전으로 이동하도록 하세요.
옵션
static-dictionary-key
사전 키가 반드시 문자열 리터럴이어야 합니다.
컴파일러는 호출 위치에서 키를 직접 읽을 수 있을 때만 사전을 사전 로드(pre-load)할 수 있습니다. 계산된 키를 사용하면 최적화를 자동으로 건너뛰고 모든 사전을 번들에 포함합니다.
코드를 클립보드에 복사
// ✗ 보고됨useIntlayer(dictionaryKey);useIntlayer(`home-${suffix}`);getTranslations({ namespace: page });// ✗ 변수는 리터럴이 아닙니다const key = "home";useIntlayer(key);// ✓ 정상useIntlayer("home");getTranslations({ namespace: "home" });이는 useIntlayer, getIntlayer 및 모든 호환 어댑터(useTranslation, useTranslations, formatMessage, <FormattedMessage id>, <Trans i18nKey>, …)에 적용됩니다.
no-dynamic-field-access
사전에서 읽는 필드가 정적으로 알려져 있어야 합니다.
컴파일러는 사용되지 않는 것으로 판단되는 필드를 제거합니다. 동적 접근은 컴파일러가 감지할 수 없으므로 런타임에 읽기 작업이 undefined를 반환할 수 있습니다.
코드를 클립보드에 복사
// ✗ 보고됨const content = useIntlayer("home");content[fieldName];const t = useTranslations("home");t(messageKey);// ✓ 정상content.title;content["title"];content.items[0];t("hero.title");enforce-adapter-import
원본 패키지 대신 @intlayer/* 호환 어댑터의 사용을 권장합니다. 원본 패키지는 번들러 별칭이 설정된 경우에만 Intlayer로 확인되지만, 어댑터는 항상 확인됩니다. --fix로 자동 수정할 수 있습니다.
코드를 클립보드에 복사
// ✗ 보고됨import { useTranslation } from "react-i18next";import { getTranslations } from "next-intl/server";// ✓ 정상import { useTranslation } from "@intlayer/react-i18next";import { getTranslations } from "@intlayer/next-intl/server";no-unused-content
기본적으로 꺼져 있습니다. 프로젝트 내에서 아무 곳에서도 읽지 않는 콘텐츠와 여러 위치에서 선언된 사전 키를 보고합니다.
코드를 클립보드에 복사
export default { key: "home", // ✗ 프로젝트 내 어떤 호출자도 "home"을 요청하지 않을 때 보고됨 content: { title: t({ ko: "제목", en: "Title" }), // ✗ `hero`를 읽는 곳이 없을 때 보고됨 hero: { subtitle: t({ ko: "소제목", en: "Subtitle" }), }, },};다른 규칙과 달리 이 규칙은 현재 파일 하나만으로 판단할 수 없습니다. 필드 사용 여부는 전체 프로젝트와의 관계에서만 파악할 수 있기 때문입니다. 린트 실행 시 첫 번째 콘텐츠 선언을 만났을 때 Intlayer 설정을 로드하고, 해당 설정에 선언된 소스 파일(build.traversePattern, compiler.transformPattern)을 수집한 후 @intlayer/lsp 및 VS Code 확장의 "미사용" 취소선을 지원하는 동일한 사용량 분석기를 실행합니다. 결과는 cacheTtl 밀리초 동안 캐시되므로 파일마다 검사하지 않고 1회 실행당 한 번만 검사를 수행합니다.
옵션
오랫동안 실행되는 에디터 서버에서 린트를 수행하며 변경 사항을 더 빨리 반영하고 싶을 때는 cacheTtl을 줄이세요. 모노레포에서 단일 린트 실행이 여러 Intlayer 프로젝트에 걸쳐 있을 때는 baseDir을 설정하세요.
침묵을 우선합니다. 여기서 거짓 양성(false positive)이 발생하면 필요한 번역이 삭제될 수 있으므로, 분석기가 추적할 수 없는 방식으로 사전을 소비할 때는 아무것도 보고하지 않습니다: 콘텐츠 객체 전체를 그대로 전달, 객체에서 바인딩된 번역 함수(const t = useTranslations("home")), 직접 가져오기를 통한 선언 접근(useDictionary(myDictionary)), 다른 사전에서의nest(), 또는 스프레드 연산자로 불완전해진 필드 목록 등입니다. 단일 파일 컴포넌트(.vue,.svelte,.astro)는 스크립트 블록이 여기서 파싱되지 않으므로 언급된 사전의 모든 필드를 사용하는 것으로 간주됩니다.
reportDuplicateKeys는 빌드 시 .intlayer/에 기록되는 병합되지 않은 사전을 읽으므로 프로젝트가 최소 한 번 빌드될 때까지는 동작하지 않습니다. 키를 공유하는 두 선언은 병합되며 이는 올바른 패턴입니다. 다만 양쪽에 정의된 필드가 조용히 둘 중 하나의 값만 유지하기 때문에 이 보고 기능이 제공됩니다.
분석기는 ESM으로 제공되는 @intlayer/lsp에서 로드됩니다. 따라서 이 규칙은 ES 모듈을 require()할 수 있는 Node 버전(Node 20.19+ 또는 22.12+)이 필요합니다. 이전 버전에서는 린트 실행을 실패시키는 대신 아무것도 보고하지 않습니다.
프레임워크
모든 규칙은 Vue, Svelte 및 Angular 템플릿 내부를 포함하여 모든 Intlayer 통합 환경에서 작동합니다. ESLint에 각 파일 형식을 읽을 파서만 지정해 주면 됩니다.
테이블을 모달로 열어 모든 데이터를 명확하게 확인
| 프레임워크 | 파일 | 파서 |
|---|---|---|
| React, Preact, Solid, Lit | .jsx .tsx | typescript-eslint |
| Next.js | .jsx .tsx | typescript-eslint |
| Vue, Nuxt | .vue | vue-eslint-parser |
| Svelte, SvelteKit | .svelte | svelte-eslint-parser |
| Angular | .ts | typescript-eslint |
| Angular 템플릿 | .component.html | @angular-eslint/template-parser |
| Astro | .astro | astro-eslint-parser |
프로젝트에 필요한 파서만 설치하세요.
알려진 제한 사항. Vue 및 Angular 템플릿에서{{ content[key] }}와 같은 표현식은no-dynamic-field-access에 의해 검사되지 않습니다. 스크립트 블록에 작성된 동적 읽기는 정상적으로 감지됩니다.