使用您最喜欢的AI助手总结文档,并引用此页面和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-intlayer需要 ESLint 9 或更高版本(Flat config)。支持 ESLint 10。
使用方法
该插件可在 ESLint 和 oxlint 中运行 — 拥有相同的规则和配置选项。
或者展开某个配置并自行设置严重级别:
预设配置
在弹窗中打开表格以清晰地查看所有数据
| 配置 | 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
要求字典键必须是字符串字面量。
编译器只有在调用位置直接读取到键时,才能预加载字典。使用计算键会静默跳过优化,转而打包所有字典。
复制代码到剪贴板
// ✗ 报告错误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({ zh: "标题", en: "Title" }), // ✗ 当没有任何地方读取 `hero` 时报告 hero: { subtitle: t({ zh: "副标题", en: "Subtitle" }), }, },};与其他规则不同,此规则无法仅凭眼前的文件给出判断 — 字段是否未使用仅相对于整个项目而言。在一次 lint 运行的首次内容声明时,它会加载你的 Intlayer 配置,匹配该配置声明的源文件(build.traversePattern、compiler.transformPattern),并运行驱动 @intlayer/lsp 和 VS Code 扩展中“未使用”删除线的同一套使用情况分析器。结果会缓存 cacheTtl 毫秒,因此每次运行只会扫描一次,而不是每个文件扫描一次。
配置选项
如果你在长期运行的编辑器服务中进行 lint 且希望更快看到修改结果,可以降低 cacheTtl;当单次 lint 运行跨越 monorepo 中的多个 Intlayer 项目时,请设置 baseDir。
倾向于保持沉默。 此处的误报会导致翻译被误删,因此当字典以分析器无法跟踪的方式被使用时,不会报告任何内容:内容对象被整体传递、从中绑定的翻译函数(const t = useTranslations("home"))、通过直接导入访问的声明(useDictionary(myDictionary))、来自另一个字典的nest()、或者因 spread 展开而不详尽的字段列表。单文件组件(.vue、.svelte、.astro)计为使用了它们提及的字典中的所有字段,因为它们的脚本块在此处不会被解析。
reportDuplicateKeys 读取构建时写入 .intlayer/ 下的未合并字典,因此在项目至少构建过一次之前它会保持静默。共享一个键的两个声明会被合并,这是一种合法的模式 — 该报告之所以存在,是因为在两边同时定义的字段会静默保留两个值中的一个。
分析器从以 ESM 形式分发的 @intlayer/lsp 中加载。因此该规则需要能够 require() ES 模块的 Node 版本 — Node 20.19+ 或 22.12+。在更低版本上,它不会报错中断 lint 运行,而是什么都不报告。
框架支持
每条规则均适用于所有 Intlayer 集成,包括 Vue、Svelte 和 Angular 模板内部。你只需告诉 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检查。写在 script 块中的动态读取仍会被正常捕获。