作者:
    Creation:2025-09-22Last update:2025-09-23

    新版 Intlayer v7 - 新特性介绍

    欢迎使用 Intlayer v7!此次重大版本发布带来了性能、类型安全和开发者体验的显著提升。以下是主要亮点,包括迁移说明和实用示例。

    目录

    亮点

    • 缓存策略以加快构建速度
    • 改进的 TypeScript 类型生成,支持基于语言环境的类型
    • 包优化:语言环境使用字符串而非枚举
    • 新的路由模式:prefix-no-defaultprefix-allno-prefixsearch-params
    • 符合 GDPR 的语言环境存储,默认使用 localStorage
    • 灵活的存储配置:支持 cookies、localStorage、sessionStorage 或多种组合
    • 视觉编辑器包体积缩小 30%
    • 增强的中间件配置选项
    • 更新的 fill 命令行为,提升内容管理
    • 通过完整内容声明文件更新增强稳定性
    • 智能重试管理,提升翻译准确性
    • 并行处理,加快翻译速度
    • 智能分块,处理大型文件以适应 AI 上下文限制

    性能:缓存以加快构建速度

    v7 通过实现缓存策略来加快构建过程,而不是在每次构建时都使用 esbuild 重新构建内容声明。

    bash
    npx intlayer build

    新的缓存系统:

    • 存储已编译的内容声明以避免重复处理
    • 检测更改并仅重新构建修改过的文件
    • 显著减少大型项目的构建时间

    TypeScript:基于语言环境的类型生成

    TypeScript 类型现在按语言环境生成,提供更强的类型支持,消除了跨所有语言环境的联合类型。

    v6 行为:

    tsx
    const content = getIntlayer("my-title-content", "en");// typeof content = { title: "My title" } | { title: "Mon titre" } | { title: "Mi título" }

    v7 行为:

    tsx
    const content = getIntlayer("my-title-content", "en");// typeof content = { title: "My title" }

    优点:

    • 在您的 IDE 中提供更精确的自动完成
    • 更好的类型安全,避免跨语言环境的类型污染
    • 通过减少类型复杂性提升性能

    包优化:将 Locales 作为字符串

    Locales 类型不再是枚举,这意味着它现在完全支持摇树优化,不会因为包含数千个未使用的语言环境记录而使您的包膨胀。

    v6:

    typescript
    import { Locales } from "intlayer";// 包含所有语言环境的枚举 -> 不支持摇树优化const locale: Locales = Locales.ENGLISH;

    v7:

    typescript
    import { Locales, Locale } from "intlayer";// 字符串类型 -> 完全支持摇树优化const locale: Locale = Locales.ENGLISH;
    因为 Locales 不再是枚举类型,所以你需要将类型从 Locales 改为 Locale 来获取作为类型的语言环境。

    更多信息请参见实现细节


    新的路由模式以实现更大灵活性

    v7 引入了统一的 routing.mode 配置,取代了之前的 prefixDefaultnoPrefix 选项,提供了对 URL 结构更细粒度的控制。

    可用的路由模式

    • prefix-no-default(默认):默认语言环境无前缀,其他语言环境有前缀
      • /dashboard(英文)或 /fr/dashboard(法文)
    • prefix-all:所有语言环境都有前缀
      • /en/dashboard(英文)或 /fr/dashboard(法文)
    • no-prefix:URL 中没有语言前缀(语言通过存储/请求头处理)
      • 所有语言均为 /dashboard
    • search-params:语言作为查询参数传递
      • /dashboard?locale=en/dashboard?locale=fr

    基本配置

    typescript
    // intlayer.config.tsexport default {  internationalization: {    locales: ["en", "fr", "es"],    defaultLocale: "en",  },  routing: {    mode: "prefix-no-default", // 默认值  },};

    GDPR 合规性:localStorage / cookies 存储

    v7 优先考虑用户隐私,默认使用 localStorage 作为存储机制,而非 cookies。此更改有助于避免因语言偏好设置而触发的 cookie 同意要求,从而更好地符合 GDPR 规定。

    存储配置选项

    新的 routing.storage 字段可用,作为之前 middleware.cookieNamemiddleware.serverSetCookie 选项的补充,提供灵活的存储配置:

    typescript
    // 禁用存储storage: false// 简单存储类型storage: 'cookie'storage: 'localStorage'storage: 'sessionStorage'// 带自定义属性的 Cookiestorage: {  type: 'cookie',  name: 'custom-locale',  domain: '.example.com',  secure: true,  sameSite: 'strict'}// 带自定义键的 localStoragestorage: {  type: 'localStorage',  name: 'custom-locale'}// 多种存储类型以实现冗余storage: ['cookie', 'localStorage']

    符合 GDPR 的配置示例

    针对需要在功能性和 GDPR 合规之间取得平衡的生产应用:

    typescript
    typescript;// intlayer.config.tsexport default {  internationalization: {    locales: ["en", "fr", "es"],    defaultLocale: "en",  },  routing: {    mode: "prefix-no-default",    storage: [      {        type: "localStorage", // 主要存储(无需同意)        name: "user-locale",      },      {        type: "cookie", // 可选的 Cookie 存储(需要同意)        name: "user-locale",        secure: true,        sameSite: "strict",        httpOnly: false,      },    ],  },};

    使用 React / Next.js 的示例:

    可以全局定义:

    typescript
    <IntlayerProvider isCookieEnabled={false}>  <App /></IntlayerProvider>

    可以为每个 hook 本地覆盖:

    ts
    const { setLocale } = useLocale({ isCookieEnabled: false });setLocale("en");

    注意: Cookies 默认是启用的。 注意: 请根据您的具体使用场景查看 GDPR Cookie 要求


    可视化编辑器:包体积减小30%

    可视化编辑器包经过优化,比之前版本体积减少了30%,得益于:

    • 代码编辑器性能提升
    • 移除对 Intlayer 核心包的不必要依赖
    • 更好的摇树优化和模块打包

    这带来了更快的下载速度和更优的运行时性能。


    自动代码格式化:formatCommand 配置

    v7 在编辑器配置中引入了 formatCommand 选项,允许你在 Intlayer 写入内容文件时自动格式化这些文件。这确保了内容声明文件的代码风格和格式的一致性。

    如果未设置,Intlayer 将尝试自动检测格式化命令。通过尝试解析以下命令:prettier、biome、eslint。

    配置

    formatCommand 选项接受一个字符串模板,其中 {{file}} 将被替换为实际的文件路径:

    intlayer.config.ts
    export default {  content: {    formatCommand: 'bun x biome format "{{file}}" --write --log-level none',  },};

    支持的格式化工具

    你可以使用任何接受文件路径作为参数的代码格式化工具:

    使用 Biome:

    typescript
    formatCommand: 'bun x biome format "{{file}}" --write --log-level none';

    使用 Prettier:

    typescript
    formatCommand: 'npx prettier --write "{{file}}" --log-level silent';

    使用 ESLint:

    typescript
    formatCommand: 'npx eslint --fix "{{file}}" --quiet';

    使用 Bun 的内置格式化工具:

    typescript
    formatCommand: 'bun format "{{file}}"';

    优势

    • 一致的格式化:所有内容文件都根据您的项目风格指南自动格式化
    • 开发者体验:Intlayer 写入文件后无需手动格式化
    • 团队一致性:确保所有团队成员对内容文件应用相同的格式化
    • CI/CD 集成:内容文件在自动化工作流中保持一致的格式化

    工作原理

    当 Intlayer 写入或更新内容声明文件(.content.ts.content.js 等)时,它会自动在该文件上运行指定的格式化命令。{{file}} 占位符被替换为实际的文件路径,命令在项目的基础目录中执行。


    字典配置:更好的组织和结构

    v7 引入了一个新的专属 dictionary 配置部分,为字典相关设置和改进的内容管理提供了更好的组织。

    新的字典配置结构

    fill 属性已从 content 部分移到新的 dictionary 部分,提供了更清晰的关注点分离:

    v6 配置:

    intlayer.config.ts
    export default {  content: {    autoFill: "./{{fileName}}.content.json",    contentDir: ["src"],  },};

    v7 配置:

    intlayer.config.ts
    export default {  content: {    contentDir: ["src"],  },  dictionary: {    fill: "./{{fileName}}.content.json",  },};

    新结构的优势

    • 更清晰的组织: 字典特定的设置现在被分组在一起
    • 更好的关注点分离: 内容发现与字典操作清晰分离
    • 增强的可维护性: 更容易理解和修改字典相关的配置
    • 未来的可扩展性: 字典部分可以容纳额外的字典特定设置
    • 全面的字典管理: 包括 titleliveprioritytagsversiondescription 等属性,用于创建和管理新的字典

    配置使用

    字典配置有两个主要目的:

    1. 默认值:在创建内容声明文件时定义默认值
    2. 回退行为:当未定义特定字段时提供回退值,允许您全局定义字典操作行为

    字典部分包含用于字典管理的全面属性:

    • fill:内容生成的自动填充行为
    • title:新字典的默认标题
    • live:用于实时更新的实时同步配置
    • priority:字典解析的优先级设置
    • tags:用于内容组织的默认标签
    • version:字典更新的版本管理
    • description:新内容的默认描述

    有关内容声明文件以及如何应用配置值的更多信息,请参阅内容文件文档


    fill 命令:更新行为以更好地管理内容

    v7 引入了 fill 命令的改进行为,提供了更可预测和灵活的内容管理:

    新的 fill 行为

    • fill: true - 用所有语言的填充内容重写当前文件
    • fill: "path/to/file" - 填充指定文件而不修改当前文件
    • fill: false - 完全禁用自动填充

    对复杂内容结构的增强支持

    fill 命令现在支持复杂的内容声明结构,包括:

    • 组合对象:引用其他对象的内容声明
    • 解构内容:使用解构模式的内容
    • 嵌套引用:对象在复杂层级中相互调用
    • 动态内容结构:具有条件或计算属性的内容

    优势

    • 意图更明确:行为现在更清晰地表明了哪些内容会被修改
    • 更好的分离:内容文件可以与已填充的翻译文件分开保存
    • 改进的工作流程:开发者可以更好地控制翻译存储的位置
    • 复杂结构支持:处理具有多个相互关联对象的复杂内容架构

    示例用法

    typescript
    // 使用所有语言重写当前文件const content = {  key: "example",  fill: true, // 重写此文件  content: {    title: "Hello World",  },};// 填充单独文件而不修改当前文件const content = {  key: "example",  fill: "./translations.json", // 创建/更新 translations.json  content: {    title: "Hello World",  },};// 禁用自动填充const content = {  key: "example",  fill: false, // 不自动填充  content: {    title: "Hello World",  },};// 复杂内容结构与组合对象const sharedContent = {  buttons: {    save: "保存",    cancel: "取消",  },};const content = {  key: "complex-example",  fill: true,  content: {    // 对其他对象的引用    sharedContent,    // 解构内容    ...sharedContent,    // 嵌套引用    sections: [      {        ...sharedContent.buttons,        header: "第1部分",      },    ],  },};

    增强的稳定性和翻译管理

    v7 引入了多项改进,使内容翻译更加可靠和高效:

    完整的内容声明文件更新

    系统现在更新 .content.{ts,js,cjs,mjs} 文件,而不是部分更新,确保:

    • 数据完整性:完整的文件重写防止部分更新导致内容损坏
    • 一致性:所有语言版本以原子方式更新,保持同步
    • 可靠性:降低内容文件不完整或格式错误的风险

    智能重试管理

    新的重试机制防止以错误格式推送内容,并避免单个请求失败时破坏整个填充过程。

    并行处理以加快速度

    翻译操作现在在队列中运行,实现并行处理。这显著加快了处理速度。

    大文件的智能分块

    先进的分块策略处理大型内容文件,避免超出 AI 上下文窗口限制:

    示例工作流程

    typescript
    // 大型内容文件自动进行分块const content = {  key: "large-documentation",  fill: true,  content: {    // 大型内容自动分块以供 AI 处理    introduction: "..." // 5000+ 字符    sections: [      // 多个大型章节    ]  }};

    系统自动执行:

    1. 分析内容大小和结构
    2. 适当分块内容
    3. 并行处理各个块
    4. 验证并在需要时重试
    5. 重建完整文件

    从 v6 版本迁移说明

    移除的配置项

    • middleware.cookieName:被 routing.storage 替代
    • middleware.serverSetCookie:被 routing.storage 替代
    • middleware.prefixDefault:被 routing.mode 替代
    • middleware.noPrefix:被 routing.mode 替代

    新配置

    • editor.formatCommand: 用于自动格式化内容文件的新选项

    迁移映射

    配置映射

    v6 配置 v7 配置
    autoFill: xxx fill: xxx
    prefixDefault: false mode: 'prefix-no-default'
    prefixDefault: true mode: 'prefix-all'
    noPrefix: true mode: 'no-prefix'
    cookieName: 'my-locale' storage: { type: 'cookie', name: 'my-locale' }
    serverSetCookie: 'never' storage: false 或从存储数组中移除 cookie`

    迁移示例

    迁移前 (v6):

    typescript
    export default {  middleware: {    headerName: "x-intlayer-locale",    cookieName: "intlayer-locale",    prefixDefault: false,    basePath: "",    serverSetCookie: "always",    noPrefix: false,  },};

    升级后 (v7):

    typescript
    export default {  routing: {    mode: "prefix-no-default",    storage: "localStorage", // 如果需要使用 cookie 存储,可以改为 'cookie'    headerName: "x-intlayer-locale",    basePath: "",  },};

    字典内容映射

    v6 字典内容 v7 字典内容
    autoFill: xxx fill: xxx

    升级示例

    升级前 (v6):

    typescript
    const content = {  key: "example",  autoFill: true, // 重写此文件  content: {    title: "你好,世界",  },};

    之后 (v7):

    typescript
    const content = {  key: "example",  fill: true, // 重写此文件  content: {    title: "你好,世界",  },};

    从 v5 到 v6 的迁移说明

    更多信息请查看 从 v5 到 v6 的迁移说明


    有用的链接