npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kne/fastify-intl

v0.1.5

Published

`@kne/fastify-intl` 是一个专为 Fastify 项目设计的国际化解决方案插件。它基于业界成熟的 `@formatjs/intl` 库构建,提供了强大而灵活的多语言支持能力,帮助开发者轻松实现应用的国际化和本地化。

Downloads

615

Readme

fastify-intl

描述

@kne/fastify-intl 是一个专为 Fastify 项目设计的国际化解决方案插件。它基于业界成熟的 @formatjs/intl 库构建,提供了强大而灵活的多语言支持能力,帮助开发者轻松实现应用的国际化和本地化。

安装

npm i --save @kne/fastify-intl

概述

@kne/fastify-intl 是一个专为 Fastify 项目设计的国际化解决方案插件。它基于业界成熟的 @formatjs/intl 库构建,提供了强大而灵活的多语言支持能力,帮助开发者轻松实现应用的国际化和本地化。

该插件采用现代化的设计理念,支持按需加载语言包,完美集成 Fastify 生态系统。通过命名空间管理机制,不同模块可以独立维护自己的翻译文件,避免代码耦合。插件内置多种语言检测策略,包括查询参数、Cookie 和请求头,确保为用户提供最合适的语言体验。

@kne/fastify-intl 提供了简洁直观的 API,在请求对象上直接暴露 localeintlt 等属性,让国际化操作变得轻而易举。它还支持动态加载远程语言包,配合智能缓存机制,既保证了性能又提供了足够的扩展性。无论是小型项目还是大型企业级应用,这款插件都能满足各种国际化场景的需求。

基础使用

1. 注册插件

const fastify = require('fastify')();
const fastifyIntl = require('@kne/fastify-intl');

await fastify.register(fastifyIntl);

2. 配置默认翻译消息

await fastify.register(fastifyIntl, {
  defaultMessages: {
    'en-US': {
      hello: 'Hello World',
      welcome: 'Welcome, {name}!'
    },
    'zh-CN': {
      hello: '你好世界',
      welcome: '欢迎, {name}!'
    }
  }
});

3. 在路由中使用

fastify.get('/hello', async (request, reply) => {
  return {
    message: request.t('hello')
  };
});

fastify.get('/welcome', async (request, reply) => {
  return {
    message: request.t('welcome', { name: 'John' })
  };
});

动态加载翻译消息

await fastify.register(fastifyIntl, {
  requestMessages: async ({ locale, name }) => {
    const response = await fetch(`https://api.example.com/messages/${locale}/${name}`);
    return response.json();
  }
});

与命名空间集成

await fastify.register(require('@kne/fastify-namespace'));
await fastify.register(fastifyIntl);

fastify.namespace.user = {
  locale: {
    'en-US': {
      profile: {
        title: 'User Profile',
        settings: 'Settings'
      }
    }
  }
};

fastify.namespace.order = {
  locale: {
    'en-US': {
      title: 'My Orders'
    }
  }
};

自定义语言检测顺序

await fastify.register(fastifyIntl, {
  defaultLocale: 'en-US',
  acceptLanguage: 'en-US,zh-CN,ja-JP'
});

语言检测优先级:

  1. query.language / query.lang
  2. cookies.x-user-locale / cookies.x-client-language
  3. headers.x-user-locale / headers.x-client-language
  4. headers.accept-language
  5. defaultLocale

控制缓存大小

插件使用 LRU 缓存来优化性能,支持两个级别的缓存:

await fastify.register(fastifyIntl, {
  cacheSize: 200
});
  • intlCache: 缓存 Intl 实例,避免重复创建(LRU 策略,默认最多 100 个)
  • localeCache: 缓存请求级别的 locale 检测结果(Map 结构,无限制)

多模块支持

await fastify.register(fastifyIntl, {
  moduleName: 'app'
});

// 在请求中切换模块
fastify.get('/admin', async (request, reply) => {
  request.moduleName = 'admin';
  request.intl = await fastify.intl.createIntl(request.locale, 'admin');
  return {
    message: request.t('dashboard')
  };
});

Q: 如何处理缺失的翻译?

插件会自动回退到 defaultLocale,确保始终有可用的翻译。

Q: 如何支持嵌套的翻译消息?

消息对象支持嵌套结构:

{
  'en-US': {
    user: {
      profile: {
        title: 'User Profile',
        name: 'Full Name'
      }
    }
  }
}

使用点号访问嵌套消息:

request.t('user.profile.title')

Q: 如何处理复数形式?

使用 ICU MessageFormat 语法:

{
  'en-US': {
    itemCount: 'You have {count, plural, =0{no items} one{1 item} other{# items}}'
  }
}

request.t('itemCount', { count: 5 }) // "You have 5 items"

Q: 如何在生产环境禁用动态加载?

await fastify.register(fastifyIntl, {
  requestMessages: process.env.NODE_ENV === 'development' ? loadRemoteMessages : null
});

示例

示例代码

API

配置选项

| 属性名 | 说明 | 类型 | 默认值 | |-----|----|----|-----| | name | 插件装饰器名称 | string | 'intl' | | acceptLanguage | 接受的语言列表,* 表示接受所有语言 | string | '*' | | defaultLocale | 默认语言环境 | string | 'en-US' | | moduleName | 默认模块名称 | string | 'global' | | defaultMessages | 默认翻译消息对象 | object | {} | | requestMessages | 动态加载翻译消息的函数,支持按 locale 和 name 缓存 | function|null | null | | cacheSize | Intl 缓存大小 | number | 100 |

requestMessages 说明

requestMessages 函数用于动态加载远程翻译消息。该函数会根据 localename 参数进行缓存,避免重复加载。

函数签名:

requestMessages(params: {
  locale: string;
  name: string;
}): Promise<Record<string, string>> | Record<string, string>

缓存机制:

  • 当首次调用 createIntl(locale, name) 时,如果 message[locale][name] 不存在,会触发 requestMessages
  • 加载的消息会被缓存,后续相同 localename 的调用会直接使用缓存
  • 缓存的 key 格式为 ${locale}:${name}

示例:

await fastify.register(fastifyIntl, {
  requestMessages: async ({ locale, name }) => {
    const response = await fetch(`https://api.example.com/messages/${locale}/${name}`);
    return response.json();
  }
});

// 第一次调用会触发远程请求
const intl1 = await fastify.intl.createIntl('en-US', 'user');

// 第二次调用使用缓存,不会触发远程请求
const intl2 = await fastify.intl.createIntl('en-US', 'user');

// 不同的 locale 或 name 会触发新的请求
const intl3 = await fastify.intl.createIntl('zh-CN', 'user');

请求属性

| 属性名 | 说明 | 类型 | |-----|----|----| | request.locale | 当前请求的语言环境 | string | | request.intl | 国际化格式化对象 | IntlShape | | request.moduleName | 当前模块名称 | string |

方法

创建一个国际化格式化实例。

| 参数 | 说明 | 类型 | |-----|----|----| | locale | 语言环境代码 | string | | name | 模块名称,默认为配置的 moduleName | string |

返回值:IntlShape 对象

getRequestLocale(request)

从请求中获取语言环境。

| 参数 | 说明 | 类型 | |-----|----|----| | request | Fastify 请求对象 | Request |

返回值:语言环境字符串

检测顺序:query.language / query.lang → cookies.x-user-locale / cookies.x-client-language → headers.x-user-locale / headers.x-client-language → headers.accept-language → defaultLocale

request.t(id, values)

翻译消息的快捷方法。

| 参数 | 说明 | 类型 | |-----|----|----| | id | 消息 ID | string | | values | 格式化参数 | object |

返回值:翻译后的字符串