Skip to main content
Glama

@yyc3/i18n-core

๐ŸŒ YYCยณ Production-Ready Internationalization Framework

้ซ˜ๆ€ง่ƒฝใ€ๆ’ไปถๅŒ–ใ€้›ถไพ่ต–็š„ i18n ่งฃๅ†ณๆ–นๆกˆ๏ผŒไธ“ไธบ็Žฐไปฃ Web ๅบ”็”จ่ฎพ่ฎก


ๆฆ‚่ฟฐ

@yyc3/i18n-core ๆ˜ฏ YYCยณ๏ผˆYanYuCloudCube๏ผ‰ๆ™บ่ƒฝๅบ”็”จ้“พไธญ็š„ๅ›ฝ้™…ๅŒ–ๅŸบ็ก€่ฎพๆ–ฝๅฑ‚๏ผŒไธบๆ•ดไธช็”Ÿๆ€ๆไพ›ๅคš่ฏญ่จ€ใ€AI็ฟป่ฏ‘ใ€MCPๅ่ฎฎ้›†ๆˆ่ƒฝๅŠ›ใ€‚ๅฎƒไธไป…ๆ˜ฏไธ€ไธช็‹ฌ็ซ‹็š„ i18n ๆก†ๆžถ๏ผŒๆ›ดๆ˜ฏ YYCยณ ็”Ÿๆ€ใ€Œไบ”้ซ˜ไบ”ๆ ‡ไบ”ๅŒ–ไบ”็ปดใ€ๆ ธๅฟƒ็†ๅฟตๅœจๅ›ฝ้™…ๅŒ–้ข†ๅŸŸ็š„ๅ…ทไฝ“่ฝๅœฐใ€‚

ๅœจ YYCยณ ็”Ÿๆ€ไธญ็š„ๅฎšไฝ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    YYCยณ ๆ™บ่ƒฝๅบ”็”จ็”Ÿๆ€                             โ”‚
โ”‚                                                                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚  โ”‚  YYCยณ-CLI   โ”‚  โ”‚  YYCยณ-ฯ€ยณ    โ”‚  โ”‚  Family-PAI โ”‚             โ”‚
โ”‚  โ”‚  ๆ–‡ๆกฃ็”Ÿๆˆ    โ”‚  โ”‚  ่ฎพ่ฎกๅทฅๅ…ท    โ”‚  โ”‚  AIๅบ”็”จ้“พ    โ”‚             โ”‚
โ”‚  โ”‚  ๅผ•ๆ“Ž       โ”‚  โ”‚  ็ป„ไปถๆ’ไปถ    โ”‚  โ”‚             โ”‚             โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ”‚         โ”‚                โ”‚                โ”‚                     โ”‚
โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                     โ”‚
โ”‚                          โ”‚                                      โ”‚
โ”‚                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”                               โ”‚
โ”‚                   โ”‚ @yyc3/i18n  โ”‚  โ† ๅฝ“ๅ‰้กน็›ฎ                    โ”‚
โ”‚                   โ”‚   -core     โ”‚                               โ”‚
โ”‚                   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                               โ”‚
โ”‚                          โ”‚                                      โ”‚
โ”‚            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                        โ”‚
โ”‚            โ–ผ             โ–ผ             โ–ผ                        โ”‚
โ”‚     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚     โ”‚ AI็ฟป่ฏ‘ๅผ•ๆ“Ž โ”‚ โ”‚MCP Serverโ”‚ โ”‚ICU็ผ–่ฏ‘ๅ™จ  โ”‚                   โ”‚
โ”‚     โ”‚(OpenAI+    โ”‚ โ”‚(AI Agent โ”‚ โ”‚(10่ฏญ่จ€+   โ”‚                   โ”‚
โ”‚     โ”‚ Ollama)    โ”‚ โ”‚ ๅทฅๅ…ท้›†ๆˆ) โ”‚ โ”‚ RTLๆ”ฏๆŒ)  โ”‚                   โ”‚
โ”‚     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ไธŽ YYCยณ-CLI ็š„่ก”ๆŽฅ

YYCยณ-CLI ๆ˜ฏ YYCยณ ็”Ÿๆ€็š„ๆ–‡ๆกฃๅ…จ็”Ÿๅ‘ฝๅ‘จๆœŸ็”Ÿๆˆๅผ•ๆ“Ž๏ผˆv2.0.0๏ผ‰๏ผŒ่ดŸ่ดฃ้กน็›ฎๅˆๅง‹ๅŒ–ใ€ๆ ‡ๅ‡†ๅŒ–ๆ–‡ๆกฃ็”Ÿๆˆใ€DevOps่ฟ็ปดใ€‚@yyc3/i18n-core ไธŽๅ…ถๅฝขๆˆไปฅไธ‹ๅๅŒ๏ผš

ๅๅŒๅœบๆ™ฏ

CLI ่Œ่ดฃ

i18n-core ่Œ่ดฃ

้กน็›ฎๅˆๅง‹ๅŒ–

yyc3 init ็”Ÿๆˆ้กน็›ฎ้ชจๆžถ

่‡ชๅŠจๆณจๅ…ฅ i18n ้…็ฝฎ๏ผˆlocales/ + ๅผ•ๆ“Žๅฎžไพ‹๏ผ‰

ๅคš่ฏญ่จ€ๆ–‡ๆกฃ

็”Ÿๆˆ็ฌฆๅˆ YYCยณ ๆ ‡ๅ‡†็š„ๆ–‡ๆกฃๆžถๆž„

ไธบ็”Ÿๆˆ็š„ๆ–‡ๆกฃๆไพ› 10 ่ฏญ่จ€็ฟป่ฏ‘ๆ”ฏๆŒ

AI ่ต‹่ƒฝ

AI ้ฉฑๅŠจ็š„ๆ–‡ๆกฃ/ไปฃ็ ็”Ÿๆˆ

AI ็ฟป่ฏ‘ๅผ•ๆ“Ž๏ผˆOpenAI + Ollama๏ผ‰ๅค็”จๅŒไธ€ AI ๅŸบ็ก€่ฎพๆ–ฝ

MCP ๅ่ฎฎ

AI Agent ๅทฅๅ…ท้“พ็ผ–ๆŽ’

ๆไพ› i18n MCP Server ไฝœไธบ Agent ๅฏ่ฐƒ็”จๅทฅๅ…ท

CI/CD ้›†ๆˆ

DevOps ๆตๆฐด็บฟ็ผ–ๆŽ’

ๆไพ› i18n audit/translate ๅ‘ฝไปคๅตŒๅ…ฅๆตๆฐด็บฟ

ๆ ธๅฟƒไปทๅ€ผไธปๅผ 

็ปดๅบฆ

ไผ ็ปŸ i18n ๆ–นๆกˆ

@yyc3/i18n-core

AI ็ฟป่ฏ‘

้œ€ๅค–ๆŽฅ SaaS / ๆ‰‹ๅŠจ็ฟป่ฏ‘

ๅŽŸ็”Ÿ้›†ๆˆ OpenAI + Ollama ๅŒๅผ•ๆ“Ž

AI ๅไฝœ

ๆ—  AI Agent ๆŽฅๅฃ

่กŒไธš้ฆ–ไธช i18n MCP Server๏ผˆ7 ไธชๅทฅๅ…ท๏ผ‰

ไพ่ต–้“พ

3-10 ไธช่ฟ่กŒๆ—ถไพ่ต–

้›ถไพ่ต– โ€” ๆ— ไพ›ๅบ”้“พ้ฃŽ้™ฉ

ๅฎ‰ๅ…จ

ๅŸบ็ก€ๆญฃๅˆ™

OWASP L4 ๅฎ‰ๅ…จ็Ÿฉ้˜ต๏ผˆReDoS้˜ฒๆŠค/ๅฏ†้’ฅ็ญ‰ๅ€ผ/้€Ÿ็އ้™ๅˆถ๏ผ‰

็”Ÿๆ€

็‹ฌ็ซ‹ๅทฅๅ…ท

YYCยณ ๆ™บ่ƒฝๅบ”็”จ้“พๅŽŸ็”Ÿ็ป„ไปถ

ๆˆ˜็•ฅๆ–นๅ‘: ่ฏฆ่ง ่กŒไธšๆŠ€ๆœฏ่ถ‹ๅŠฟๅˆ†ๆžไธŽๅ…จ้“พ่ทฏ่ฝๅœฐๆ–นๆกˆ โ€” MCPๅ่ฎฎ็”Ÿๆ€็ˆ†ๅ‘๏ผˆ15,382+ Server / 9700ไธ‡SDKๆœˆไธ‹่ฝฝ๏ผ‰๏ผŒi18n MCP Server ๅ ๆฏ”<1%๏ผŒ@yyc3/i18n-core ๆญฃๅค„ไบŽ่ฟ™ไธช่“ๆตท่ต›้“็š„ๆ ธๅฟƒไฝ็ฝฎใ€‚


Related MCP server: @langapi/mcp-server

๏ฟฝ๏ฟฝ ็›ฎๅฝ•


โœจ ็‰นๆ€งๆฆ‚่งˆ

๐ŸŽฏ ๆ ธๅฟƒไผ˜ๅŠฟ

็‰นๆ€ง

ๆ่ฟฐ

็Šถๆ€

้›ถไพ่ต–่ฟ่กŒๆ—ถ

ๆ— ไปปไฝ•็”Ÿไบงไพ่ต–๏ผŒ็บฏ TypeScript ๅฎž็Žฐ

โœ…

10 ็ง่ฏญ่จ€ๅ†…็ฝฎ

en/zh-CN/zh-TW/ja/ko/fr/de/es/pt-BR/ar(RTL)

โœ…

AI ็ฟป่ฏ‘้›†ๆˆ

OpenAI + Ollama ๆœฌๅœฐๆจกๅž‹ๆ”ฏๆŒ

โœ…

MCP ๅ่ฎฎๅŽŸ็”Ÿ

AI Agent ๅทฅๅ…ท้›†ๆˆ๏ผŒ7 ไธช i18n ๅทฅๅ…ท

โœ…

ICU MessageFormat

ๅฎŒๆ•ดๅฎž็Žฐ๏ผŒ12 ็ง่ฏญๆณ•็ฑปๅž‹

โœ…

RTL ๅŽŸ็”Ÿๆ”ฏๆŒ

้˜ฟๆ‹‰ไผฏ่ฏญ็ญ‰ RTL ่ฏญ่จ€ๅธƒๅฑ€่‡ชๅŠจๅค„็†

โœ…

LRU ็ผ“ๅญ˜็ณป็ปŸ

<0.1ms ็ผ“ๅญ˜ๅ‘ฝไธญๅ“ๅบ”ๆ—ถ้—ด

โœ…

ๆ’ไปถๅŒ–ๆžถๆž„

ๅฏๆ‰ฉๅฑ•็š„็”Ÿๅ‘ฝๅ‘จๆœŸ้’ฉๅญ็ณป็ปŸ

โœ…

ไผไธš็บงๅฎ‰ๅ…จ

OWASP L4 ๅฎ‰ๅ…จๆ ‡ๅ‡†

โœ…

๐Ÿ† ไธŽไธปๆตๆ–นๆกˆๅฏนๆฏ”

็‰นๆ€ง

@yyc3/i18n-core

react-i18next

vue-i18n

typesafe-i18n

ไพ่ต–ๆ•ฐ้‡

0

3+

2+

0

ๆ‰“ๅŒ…ๅคงๅฐ

~15KB

~33KB

~1.5MB

~1KB

AI ็ฟป่ฏ‘

โœ… ๅ†…็ฝฎ

ๆ’ไปถ

ๆ’ไปถ

โŒ

MCP ๅ่ฎฎ

โœ… ๅ†…็ฝฎ

โŒ

โŒ

โŒ

ICU MessageFormat

โœ… ๅฎŒๆ•ด

ๆ’ไปถ

ๅŸบ็ก€

ๅŸบ็ก€

RTL ๆ”ฏๆŒ

โœ… ๅŽŸ็”Ÿ

้…็ฝฎ

้…็ฝฎ

โŒ

ๅฎ‰ๅ…จ็ญ‰็บง

OWASP L4

ๅŸบ็ก€

ๅŸบ็ก€

โŒ

ไธญๆ–‡ไผ˜ๅŒ–

10 ่ฏญ่จ€

้…็ฝฎ

้…็ฝฎ

้…็ฝฎ


๐Ÿค” ไธบไป€ไนˆ้€‰ๆ‹ฉ @yyc3/i18n-core?

1๏ธโƒฃ ็œŸๆญฃ็š„้›ถไพ่ต–

npm install @yyc3/i18n-core
# ไป…ๆญคไธ€ไธชๅŒ…๏ผŒๆ— ๅ…ถไป–ไพ่ต–

2๏ธโƒฃ ๅผ€็ฎฑๅณ็”จ็š„ไธญๆ–‡ๆ”ฏๆŒ

import { i18n, t } from '@yyc3/i18n-core';

// 10 ็ง่ฏญ่จ€ๅณๆ—ถๅฏ็”จ
await i18n.setLocale('zh-CN');  // ็ฎ€ไฝ“ไธญๆ–‡
await i18n.setLocale('zh-TW');  // ็นไฝ“ไธญๆ–‡
await i18n.setLocale('ja');     // ๆ—ฅ่ฏญ
await i18n.setLocale('ko');     // ้Ÿฉ่ฏญ
// ... ๆ›ดๅคš

3๏ธโƒฃ AI ่ต‹่ƒฝ็ฟป่ฏ‘

import { AIProviderManager, OpenAIProvider } from '@yyc3/i18n-core/ai';

const ai = new AIProviderManager();
ai.register(new OpenAIProvider({ apiKey: 'your-key' }));

const result = await ai.translate({
  sourceText: 'Hello World',
  sourceLocale: 'en',
  targetLocale: 'zh-CN',
});
console.log(result.translatedText); // "ไฝ ๅฅฝไธ–็•Œ"

4๏ธโƒฃ MCP ๅ่ฎฎๅŽŸ็”Ÿ้›†ๆˆ

import { MCPServer, registerI18nTools, StdioTransport } from '@yyc3/i18n-core/mcp';

const server = new MCPServer({
  name: 'i18n-tools',
  version: '1.4.0',
  transport: new StdioTransport(),
});
registerI18nTools(server);
await server.start();
// ็Žฐๅœจ Claude/Cursor ็ญ‰ AI ๅทฅๅ…ทๅฏไปฅไฝฟ็”จ i18n ๅŠŸ่ƒฝไบ†๏ผ

๐Ÿ“ฆ ๅฎ‰่ฃ…ๆŒ‡ๅ—

ๅ‰็ฝฎ่ฆๆฑ‚

  • Node.js >= 16.0.0

  • TypeScript >= 5.0 (ๆŽจ่๏ผŒไฝ†ไนŸๆ”ฏๆŒ JavaScript)

ๅฎ‰่ฃ…ๅ‘ฝไปค

# ไฝฟ็”จ npm
npm install @yyc3/i18n-core

# ไฝฟ็”จ pnpm (ๆŽจ่)
pnpm add @yyc3/i18n-core

# ไฝฟ็”จ yarn
yarn add @yyc3/i18n-core

้ชŒ่ฏๅฎ‰่ฃ…

import { i18n, t } from '@yyc3/i18n-core';

console.log(t('common.welcome')); // "Welcome"
console.log('โœ… @yyc3/i18n-core ๅฎ‰่ฃ…ๆˆๅŠŸ');

๐Ÿš€ ๅฟซ้€Ÿๅผ€ๅง‹

1. ๆœ€็ฎ€ไฝฟ็”จ โ€” ้›ถ้…็ฝฎๅฏๅŠจ

import { i18n, t } from '@yyc3/i18n-core';

// ็›ดๆŽฅไฝฟ็”จ๏ผŒๆ— ้œ€้…็ฝฎ
t('common.welcome'); // "Welcome"

// ๅˆ‡ๆข่ฏญ่จ€
await i18n.setLocale('zh-CN');
t('common.welcome'); // "ๆฌข่ฟŽ"

2. ๅธฆๆ’ไปถ็š„ๅฎŒๆ•ด้…็ฝฎ

import { i18n, t, I18nEngine } from '@yyc3/i18n-core';
import {
  createConsoleLogger,
  MissingKeyReporter,
  PerformanceTracker,
} from '@yyc3/i18n-core/plugins';

// ๅˆ›ๅปบๅผ•ๆ“Žๅฎžไพ‹
const engine = new I18nEngine({
  defaultLocale: 'en',
  fallbackLocale: 'en',
  cache: {
    maxSize: 1000,
    ttl: 3600000, // 1ๅฐๆ—ถ
  },
});

// ๆณจๅ†Œๆ’ไปถ
engine.plugins.register(createConsoleLogger());
engine.plugins.register(new MissingKeyReporter().createPlugin());
engine.plugins.register(
  new PerformanceTracker({ slowThreshold: 10 }).createPlugin()
);

// ๅˆๅง‹ๅŒ–
await engine.init();

// ไฝฟ็”จ
engine.t('greeting', { name: 'World' }); // "Hello, World!"

3. React ้กน็›ฎ้›†ๆˆ

// App.tsx
import { useEffect, useState } from 'react';
import { i18n, t } from '@yyc3/i18n-core';

function App() {
  const [locale, setLocale] = useState('en');

  useEffect(() => {
    i18n.setLocale(locale);
  }, [locale]);

  return (
    <div>
      <h1>{t('app.title')}</h1>
      <p>{t('greeting', { name: 'User' })}</p>

      <select value={locale} onChange={(e) => setLocale(e.target.value)}>
        <option value="en">English</option>
        <option value="zh-CN">ไธญๆ–‡</option>
        <option value="ja">ๆ—ฅๆœฌ่ชž</option>
      </select>
    </div>
  );
}

4. Vue ้กน็›ฎ้›†ๆˆ

<template>
  <div>
    <h1>{{ $t('app.title') }}</h1>
    <button @click="changeLocale('zh-CN')">ไธญๆ–‡</button>
    <button @click="changeLocale('en')">English</button>
  </div>
</template>

<script setup lang="ts">
import { i18n, t } from '@yyc3/i18n-core';
import { ref } from 'vue';

const changeLocale = async (locale: string) => {
  await i18n.setLocale(locale);
};
</script>

5. Node.js / ๅŽ็ซฏไฝฟ็”จ

// server.ts
import { I18nEngine } from '@yyc3/i18n-core';

const i18n = new I18nEngine({
  defaultLocale: 'zh-CN',
});

export function middleware(req, res, next) {
  const locale = req.headers['accept-language']?.split(',')[0] || 'zh-CN';
  i18n.setLocale(locale);

  req.t = (key, params?) => i18n.t(key, params);
  next();
}

// ๅœจ่ทฏ็”ฑไธญไฝฟ็”จ
app.get('/api/hello', (req, res) => {
  res.json({ message: req.t('hello') });
});

๐Ÿ—๏ธ ๆžถๆž„่ฎพ่ฎก

ๅˆ†ๅฑ‚ๆžถๆž„

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                   Application Layer                         โ”‚
โ”‚              (React / Vue / Angular / Node.js)               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                        โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Public API Layer                          โ”‚
โ”‚         i18n / t / I18nEngine / PluginManager               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                        โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ–ผ               โ–ผ               โ–ผ               โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Core    โ”‚   โ”‚   Cache   โ”‚   โ”‚  Plugins  โ”‚   โ”‚  Formats  โ”‚
โ”‚  Engine   โ”‚   โ”‚   LRU     โ”‚   โ”‚  System   โ”‚   โ”‚  ICU/MF   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜
      โ”‚               โ”‚               โ”‚               โ”‚
      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                        โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ–ผ               โ–ผ               โ–ผ               โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚    AI     โ”‚   โ”‚    MCP    โ”‚   โ”‚ Security  โ”‚   โ”‚   RTL     โ”‚
โ”‚ Translationโ”‚   โ”‚  Server   โ”‚   โ”‚  OWASP L4 โ”‚   โ”‚  Utils    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ๆจกๅ—่Œ่ดฃ

ๆจกๅ—

ๆ–‡ไปถ่ทฏๅพ„

่Œ่ดฃ

ๅคๆ‚ๅบฆ

Core Engine

lib/engine.ts

็ฟป่ฏ‘ๅผ•ๆ“Žใ€่ฏญ่จ€ๅˆ‡ๆขใ€ๅ‚ๆ•ฐๆ’ๅ€ผ

โญโญโญ

Cache System

lib/cache.ts

LRU ็ผ“ๅญ˜ใ€TTL ่ฟ‡ๆœŸใ€็ปŸ่ฎก

โญโญ

Plugin System

lib/plugins.ts

็”Ÿๅ‘ฝๅ‘จๆœŸ้’ฉๅญใ€ไบ‹ไปถ่ฎข้˜…

โญโญ

ICU Engine

lib/icu/*

MessageFormat ่งฃๆžไธŽ็ผ–่ฏ‘

โญโญโญ

AI Translation

lib/ai/*

LLM ็ฟป่ฏ‘ใ€่ดจ้‡่ฏ„ไผฐ

โญโญโญ

MCP Server

lib/mcp/*

ๅ่ฎฎๅฎž็Žฐใ€ๅทฅๅ…ทๆณจๅ†Œ

โญโญโญ

Security

lib/security/*

ReDoS้˜ฒๆŠคใ€ๆณจๅ…ฅๆฃ€ๆต‹

โญโญ

RTL Utils

lib/rtl-utils.ts

ๅธƒๅฑ€้•œๅƒใ€ๆ–นๅ‘ๆฃ€ๆต‹

โญ

ๆ•ฐๆฎๆต

็”จๆˆท่ฐƒ็”จ t(key, params)
       โ†“
  Plugin.beforeTranslate()
       โ†“
  Cache Lookup โ†’ Hit? โ†’ Return Cached Result
       โ†“ Miss
  ICU Parser โ†’ Parse Syntax Tree
       โ†“
  Formatter โ†’ Interpolate Parameters
       โ†“
  Plugin.afterTranslate()
       โ†“
  Cache.Store(Result)
       โ†“
  Return Translated String

๐Ÿ“ฆ ๆ ธๅฟƒๆจกๅ—่ฏฆ่งฃ

1. Core Engine (@yyc3/i18n-core)

็ฟป่ฏ‘ๅผ•ๆ“Ž็š„ๆ ธๅฟƒ๏ผŒๆไพ›ๅฎŒๆ•ด็š„ i18n ่ƒฝๅŠ›ใ€‚

import { I18nEngine, i18n, t } from '@yyc3/i18n-core';

// ๆ–นๅผ1: ไฝฟ็”จๅ…จๅฑ€ๅ•ไพ‹ (ๆŽจ่็ฎ€ๅ•ๅœบๆ™ฏ)
t('welcome'); // "Welcome"
t('greeting', { name: 'World' }); // "Hello, World!"

// ๆ–นๅผ2: ๅˆ›ๅปบ็‹ฌ็ซ‹ๅฎžไพ‹ (ๆŽจ่ๅคๆ‚ๅœบๆ™ฏ)
const engine = new I18nEngine({
  defaultLocale: 'en',
  fallbackLocale: 'en',
  debug: false,
});

await engine.init();

// ๅˆ‡ๆข่ฏญ่จ€
await engine.setLocale('zh-CN');

// ๆ‰น้‡็ฟป่ฏ‘
const results = await engine.batchTranslate(['key1', 'key2', 'key3']);

// ่Žทๅ–็ปŸ่ฎกไฟกๆฏ
const stats = engine.getStats();
console.log(stats.cacheHits, stats.cacheMisses);

// ่ฎข้˜…่ฏญ่จ€ๅ˜ๆ›ด
engine.onLocaleChange((from, to) => {
  console.log(`Locale changed: ${from} -> ${to}`);
});

I18nEngineConfig ๆŽฅๅฃ

interface I18nEngineConfig {
  defaultLocale?: string;      // ้ป˜่ฎค่ฏญ่จ€: 'en'
  fallbackLocale?: string;     // ๅ›ž้€€่ฏญ่จ€: 'en'
  debug?: boolean;             // ่ฐƒ่ฏ•ๆจกๅผ: false
  cache?: CacheConfig;         // ็ผ“ๅญ˜้…็ฝฎ
  plugins?: I18nPlugin[];      // ๅˆๅง‹ๆ’ไปถๅˆ—่กจ
  onError?: (error: Error) => void;  // ้”™่ฏฏๅค„็†
  missingKeyHandler?: (key: string) => string;  // ็ผบๅคฑ้”ฎๅค„็†
}

2. Cache System (@yyc3/i18n-core/cache)

้ซ˜ๆ€ง่ƒฝ LRU ็ผ“ๅญ˜๏ผŒๆ˜พ่‘—ๆๅ‡็ฟป่ฏ‘ๆ€ง่ƒฝใ€‚

import { LRUCache } from '@yyc3/i18n-core/cache';

// ๅˆ›ๅปบ็ผ“ๅญ˜ๅฎžไพ‹
const cache = new LRUCache<string, string>({
  maxSize: 1000,           // ๆœ€ๅคง็ผ“ๅญ˜ๆก็›ฎ
  ttl: 3600000,           // ่ฟ‡ๆœŸๆ—ถ้—ด (1ๅฐๆ—ถ)
});

// ๅญ˜ๅ–ๆ•ฐๆฎ
cache.set('key', 'value');
const value = cache.get('key'); // "value"

// ็ผ“ๅญ˜ๆœชๅ‘ฝไธญ
cache.get('nonexistent'); // undefined

// ่Žทๅ–็ปŸ่ฎกไฟกๆฏ
const stats: CacheStats = cache.getStats();
console.log(stats.hits, stats.misses, stats.size);

// ๆ‰‹ๅŠจๆธ…็†
cache.clear();
cache.delete('key');

ๆ€ง่ƒฝๆŒ‡ๆ ‡

ๆ“ไฝœ

ๆ—ถ้—ดๅคๆ‚ๅบฆ

ๅนณๅ‡่€—ๆ—ถ

get()

O(1)

<0.1ms

set()

O(1)

<0.1ms

ๆ‰น้‡ๆŸฅๆ‰พ

O(n)

<1ms (100 keys)


3. Plugin System (@yyc3/i18n-core/plugins)

ๅฏๆ‰ฉๅฑ•็š„ๆ’ไปถๆžถๆž„๏ผŒๆ”ฏๆŒ็”Ÿๅ‘ฝๅ‘จๆœŸ้’ฉๅญใ€‚

import {
  PluginManager,
  createConsoleLogger,
  MissingKeyReporter,
  PerformanceTracker,
} from '@yyc3/i18n-core/plugins';

// ๆณจๅ†Œๅ†…็ฝฎๆ’ไปถ
i18n.plugins.register(createConsoleLogger());
i18n.plugins.register(new MissingKeyReporter().createPlugin());
i18n.plugins.register(new PerformanceTracker({ slowThreshold: 10 }).createPlugin());

// ่‡ชๅฎšไน‰ๆ’ไปถ
i18n.plugins.register({
  name: 'analytics-plugin',

  beforeTranslate(key: string) {
    console.log(`[Analytics] Translating: ${key}`);
    // ่ฟ”ๅ›ž true ็ปง็ปญๆ‰ง่กŒ๏ผŒ่ฟ”ๅ›ž false ไธญๆ–ญ
    return true;
  },

  afterTranslate(result: string, key: string) {
    console.log(`[Analytics] Result: ${result}`);
  },

  onLocaleChange(from: string, to: string) {
    console.log(`[Analytics] Locale: ${from} -> ${to}`);
  },
});

// ็งป้™คๆ’ไปถ
i18n.plugins.unregister('analytics-plugin');

ๅ†…็ฝฎๆ’ไปถๅˆ—่กจ

ๆ’ไปถๅ

็”จ้€”

้…็ฝฎ้กน

ConsoleLogger

ๅผ€ๅ‘่ฐƒ่ฏ•ๆ—ฅๅฟ—

ๆ— 

MissingKeyReporter

็”Ÿไบง็Žฏๅขƒ็ผบๅคฑ้”ฎ็›‘ๆŽง

reportUrl, threshold

PerformanceTracker

ๆ€ง่ƒฝๆŒ‡ๆ ‡ๆ”ถ้›†

slowThreshold, percentiles


4. ICU MessageFormat (@yyc3/i18n-core/icu)

ๅฎŒๆ•ด็š„ ICU MessageFormat ๅฎž็Žฐ๏ผŒๆ”ฏๆŒๅคๆ•ฐใ€้€‰ๆ‹ฉ็ญ‰ๅคๆ‚่ฏญๆณ•ใ€‚

import { ICUParser, ICUCompiler } from '@yyc3/i18n-core/icu';

// ่งฃๆž ICU ่ฏญๆณ•
const parser = new ICUParser();
const ast = parser.parse('{count, plural, one {# item} other {# items}}');

// ็ผ–่ฏ‘ๅนถๆธฒๆŸ“
const compiler = new ICUCompiler({ locale: 'en' });
const result = compiler.compile(ast, { count: 5 });
console.log(result); // "5 items"

// ๅœจๅผ•ๆ“Žไธญ็›ดๆŽฅไฝฟ็”จ (่‡ชๅŠจๆฃ€ๆต‹ ICU ่ฏญๆณ•)
t('items_count', { count: 5 }); // ่‡ชๅŠจ่ทฏ็”ฑๅˆฐ ICU ็ผ–่ฏ‘ๅ™จ

ๆ”ฏๆŒ็š„ ICU ่ฏญๆณ•

่ฏญๆณ•็ฑปๅž‹

็คบไพ‹

่ฏดๆ˜Ž

Plural

{count, plural, one {...} other {...}}

ๅคๆ•ฐ่ง„ๅˆ™

Select

{gender, select, male {...} female {...}}

ๆกไปถ้€‰ๆ‹ฉ

SelectOrdinal

{rank, selectOrdinal, one {...} two {...}}

ๅบๆ•ฐ่ฏ

Number

{price, number, ::currency/USD}

ๆ•ฐๅญ—ๆ ผๅผๅŒ–

Date

{date, date, full}

ๆ—ฅๆœŸๆ ผๅผๅŒ–

Time

{time, time, short}

ๆ—ถ้—ดๆ ผๅผๅŒ–

Offset

{offset, plural, offset:1 ...}

ๅ็งป้‡


5. AI Translation (@yyc3/i18n-core/ai)

LLM ้ฉฑๅŠจ็š„ๆ™บ่ƒฝ็ฟป่ฏ‘๏ผŒๆ”ฏๆŒ OpenAI ๅ’Œๆœฌๅœฐ Ollamaใ€‚

import {
  AIProviderManager,
  OpenAIProvider,
  OllamaProvider,
  QualityEstimator,
} from '@yyc3/i18n-core/ai';

// ๅˆ›ๅปบ AI ็ฎก็†ๅ™จ
const ai = new AIProviderManager();

// ๆณจๅ†Œ OpenAI Provider
ai.register(new OpenAIProvider({
  apiKey: process.env.OPENAI_API_KEY!,
  model: 'gpt-4o-mini',
}));

// ๆˆ–ๆณจๅ†Œ Ollama Provider (ๅ…่ดนๆœฌๅœฐๆจกๅž‹)
ai.register(new OllamaProvider({
  baseUrl: 'http://localhost:11434',
  model: 'qwen2.5:3b',
}));

// ๆ‰ง่กŒ็ฟป่ฏ‘
const result = await ai.translate({
  sourceText: 'Hello World',
  sourceLocale: 'en',
  targetLocale: 'zh-CN',
  context: 'UI label for welcome message',
});

console.log(result.translatedText); // "ไฝ ๅฅฝไธ–็•Œ"
console.log(result.confidence);     // 0.95

// ่ดจ้‡่ฏ„ไผฐ
const qe = new QualityEstimator();
const quality = await qe.estimate({
  sourceText: 'Hello World',
  translatedText: 'ไฝ ๅฅฝไธ–็•Œ',
  sourceLocale: 'en',
  targetLocale: 'zh-CN',
});

console.log(quality.score);     // 0.98
console.log(quality.issues);    // [] (ๆ— ้—ฎ้ข˜)

ๆ”ฏๆŒ็š„ AI Provider

Provider

็ฑปๅž‹

ๆˆๆœฌ

ๅปถ่ฟŸ

้€‚็”จๅœบๆ™ฏ

OpenAI

ไบ‘็ซฏ API

๐Ÿ’ฐ๐Ÿ’ฐ

ไฝŽ (<2s)

็”Ÿไบง็Žฏๅขƒ

Ollama

ๆœฌๅœฐๆจกๅž‹

ๅ…่ดน

ไธญ (~3s)

ๅผ€ๅ‘/็ฆป็บฟ


6. MCP Server (@yyc3/i18n-core/mcp)

Model Context Protocol ๆœๅŠก็ซฏ๏ผŒ่ฎฉ AI Agent ็›ดๆŽฅไฝฟ็”จ i18n ๅทฅๅ…ทใ€‚

import {
  MCPServer,
  registerI18nTools,
  StdioTransport,
} from '@yyc3/i18n-core/mcp';

// ๅˆ›ๅปบ MCP Server
const server = new MCPServer({
  name: 'yyc3-i18n-tools',
  version: '1.4.0',
  transport: new StdioTransport(),
});

// ๆณจๅ†Œ 7 ไธช i18n ๅทฅๅ…ท
registerI18nTools(server);

// ๅฏๅŠจๆœๅŠก
await server.start();
console.log('MCP Server running...');

// ๅฏ็”จๅทฅๅ…ท:
// 1. search_translations    - ๆœ็ดข็ฟป่ฏ‘
// 2. add_translation_key    - ๆทปๅŠ ็ฟป่ฏ‘้”ฎ
// 3. translate_key          - ็ฟป่ฏ‘ๅ•ไธช้”ฎ
// 4. check_missing_keys     - ๆฃ€ๆŸฅ็ผบๅคฑ้”ฎ
// 5. get_locale_stats       - ่Žทๅ–่ฏญ่จ€็ปŸ่ฎก
// 6. set_locale             - ่ฎพ็ฝฎๅฝ“ๅ‰่ฏญ่จ€
// 7. quality_report         - ็ฟป่ฏ‘่ดจ้‡ๆŠฅๅ‘Š

MCP ๅทฅๅ…ท่ฏฆๆƒ…

ๅทฅๅ…ทๅ

ๅŠŸ่ƒฝ

ๅ‚ๆ•ฐ

search_translations

ๆœ็ดข็ฟป่ฏ‘ๅ†…ๅฎน

query, locale, limit

add_translation_key

ๆทปๅŠ ๆ–ฐ็ฟป่ฏ‘้”ฎ

key, translations

translate_key

็ฟป่ฏ‘ๆŒ‡ๅฎš้”ฎ

key, targetLocale

check_missing_keys

ๆฃ€ๆŸฅ็ผบๅคฑ็š„็ฟป่ฏ‘้”ฎ

locale

get_locale_stats

่Žทๅ–่ฏญ่จ€็ปŸ่ฎกไฟกๆฏ

-

set_locale

่ฎพ็ฝฎๅฝ“ๅ‰่ฏญ่จ€

locale

quality_report

็”Ÿๆˆ่ดจ้‡ๆŠฅๅ‘Š

locale


7. RTL Support (@yyc3/i18n-core โ€” ๅ†…็ฝฎ)

RTL (Right-to-Left) ่ฏญ่จ€็š„ๅŽŸ็”Ÿๆ”ฏๆŒใ€‚

import {
  isRTL,
  setupDocumentDirection,
  flipSpacing,
  getAlignment,
  createMirroredLayout,
} from '@yyc3/i18n-core';

// ๆฃ€ๆต‹ๆ˜ฏๅฆไธบ RTL ่ฏญ่จ€
isRTL('ar');    // true
isRTL('he');    // true
isRTL('en');    // false

// ่‡ชๅŠจ่ฎพ็ฝฎๆ–‡ๆกฃๆ–นๅ‘
setupDocumentDirection('ar');
// <html dir="rtl" lang="ar">

// CSS ๅฑžๆ€ง็ฟป่ฝฌ
flipSpacing({ marginLeft: 10, marginRight: 20 }, 'rtl');
// โ†’ { marginLeft: 20, marginRight: 10 }

// ่Žทๅ–ๅฏน้ฝๆ–นๅผ
getAlignment('ltr'); // 'left'
getAlignment('rtl'); // 'right'

// ๅˆ›ๅปบ้•œๅƒๅธƒๅฑ€
const layout = createMirroredLayout('rtl');
layout.mainAxis;    // 'right'
layout.crossAxis;   // 'left'

ๆ”ฏๆŒ็š„ RTL ่ฏญ่จ€

่ฏญ่จ€

ไปฃ็ 

ๆ–นๅ‘

้˜ฟๆ‹‰ไผฏ่ฏญ

ar

RTL

ๅธŒไผฏๆฅ่ฏญ

he

RTL

ๆณขๆ–ฏ่ฏญ

fa

RTL

ไนŒๅฐ”้ƒฝ่ฏญ

ur

RTL


๐ŸŒณ ๅญ่ทฏๅพ„ๅฏผๅ…ฅ๏ผˆTree Shaking๏ผ‰

ๆŒ‰้œ€ๅผ•ๅ…ฅ๏ผŒๆž่‡ดไผ˜ๅŒ–ๆ‰“ๅŒ…ไฝ“็งฏ

// ๅ…จ้ƒจๅŠŸ่ƒฝ (~15KB gzipped)
import { i18n, t, I18nEngine } from '@yyc3/i18n-core'

// ไป…็ผ“ๅญ˜็ณป็ปŸ (~3KB gzipped)
import { LRUCache } from '@yyc3/i18n-core/cache'

// ไป…ๆ’ไปถ็ณป็ปŸ (~4KB gzipped)
import { PluginManager, createConsoleLogger } from '@yyc3/i18n-core/plugins'

// ไป… ICU ๅผ•ๆ“Ž (~5KB gzipped)
import { ICUParser, ICUCompiler } from '@yyc3/i18n-core/icu'

// ไป… AI ็ฟป่ฏ‘ (~4KB gzipped)
import { AIProviderManager, OpenAIProvider } from '@yyc3/i18n-core/ai'

// ไป… MCP ๆœๅŠก็ซฏ (~3KB gzipped)
import { MCPServer, registerI18nTools } from '@yyc3/i18n-core/mcp'

ๅฏ็”จๅญ่ทฏๅพ„

ๅญ่ทฏๅพ„

ๅคงๅฐไผฐ่ฎก(gzipped)

ๅฏผๅ‡บๅ†…ๅฎน

้€‚็”จๅœบๆ™ฏ

.

~15KB

ๅ…จ้ƒจๅŠŸ่ƒฝ

ๅฐๅž‹้กน็›ฎ / ๅฟซ้€ŸๅŽŸๅž‹

./cache

~3KB

LRU Cache ็ณป็ปŸ

้œ€่ฆ้ซ˜ๆ€ง่ƒฝ็ผ“ๅญ˜

./plugins

~4KB

ๆ’ไปถ็ฎก็†ๅ™จ + ๅ†…็ฝฎๆ’ไปถ

้œ€่ฆๆ‰ฉๅฑ•ๅŠŸ่ƒฝ

./icu

~5KB

ICU ่งฃๆžๅ™จ/็ผ–่ฏ‘ๅ™จ

ๅคๆ‚ๆถˆๆฏๆ ผๅผ

./ai

~4KB

AI ็ฟป่ฏ‘ + ่ดจ้‡่ฏ„ไผฐ

้œ€่ฆ LLM ็ฟป่ฏ‘

./mcp

~3KB

MCP Server + Transport

AI Agent ้›†ๆˆ

ๆ‰“ๅŒ…ไฝ“็งฏๅฏนๆฏ”

ๅœบๆ™ฏ                      | ๆœชไผ˜ๅŒ– | Tree ShakingๅŽ | ่Š‚็œ
-------------------------|--------|----------------|------
ๅฎŒๆ•ดๅฏผๅ…ฅ                  | 15KB   | 15KB           | -
ไป…็”จ Core + Cache        | 15KB   | 8KB            | 47%
ไป…็”จ ICU ๅผ•ๆ“Ž            | 15KB   | 5KB            | 67%
ไป…็”จ AI Translation      | 15KB   | 4KB            | 73%
ไป…็”จ MCP Server          | 15KB   | 3KB            | 80%

๐Ÿ“– API ๅ‚่€ƒ

ๆ ธๅฟƒๅฏผๅ‡บ

// ====== ไธปๅ…ฅๅฃ ======
import {
  // Engine
  I18nEngine, i18n, t,

  // Cache
  LRUCache,
  type CacheConfig, type CacheStats,

  // Plugins
  PluginManager,
  createConsoleLogger, MissingKeyReporter, PerformanceTracker,
  type I18nContext, type I18nPlugin,

  // Formatter
  formatRelativeTime, interpolate, pluralize,
  type TranslateParams,

  // Locale Detection
  detectSystemLocale, isChineseLocale, normalizeLocale,
  type LocaleDetectionResult,

  // RTL Utilities
  isRTL, setupDocumentDirection, flipSpacing, getAlignment,
  getDirection, getOppositeAlignment, mirrorPosition,
  createMirroredLayout, transformClassForRTL,
  type HorizontalAlignment, type TextDirection,

  // Types
  type Locale, type RTLLocale, type TranslationMap,
} from '@yyc3/i18n-core'

// ====== ๅญ่ทฏๅพ„ๅฏผๅ…ฅ ======
// Cache
import { LRUCache } from '@yyc3/i18n-core/cache'

// Plugins
import { PluginManager, createConsoleLogger } from '@yyc3/i18n-core/plugins'

// ICU
import { ICUParser, ICUCompiler } from '@yyc3/i18n-core/icu'

// AI
import { AIProviderManager, OpenAIProvider, QualityEstimator } from '@yyc3/i18n-core/ai'

// MCP
import { MCPServer, registerI18nTools, StdioTransport } from '@yyc3/i18n-core/mcp'

ๆ ธๅฟƒ API

t() โ€” ็ฟป่ฏ‘ๅ‡ฝๆ•ฐ

function t(key: string, params?: TranslateParams): string;

// ๅŸบๆœฌ็”จๆณ•
t('welcome');                    // "Welcome"

// ๅ‚ๆ•ฐๆ’ๅ€ผ
t('greeting', { name: 'World' }); // "Hello, World!"

// ๅตŒๅฅ—ๅฏน่ฑก
t('user.profile.name');          // ไปŽๅตŒๅฅ—ๅฏน่ฑก่Žทๅ–

// ICU ่ฏญๆณ• (่‡ชๅŠจๆฃ€ๆต‹)
t('items', { count: 5 });        // "5 items"

i18n โ€” ๅ…จๅฑ€ๅ•ไพ‹

// ๅ…จๅฑ€ๅ•ไพ‹๏ผŒๆ— ้œ€ๅˆ›ๅปบๅฎžไพ‹
const i18n: I18nEngine;

// ๅˆ‡ๆข่ฏญ่จ€
await i18n.setLocale('zh-CN');

// ่Žทๅ–ๅฝ“ๅ‰่ฏญ่จ€
i18n.currentLocale; // 'zh-CN'

// ๆ‰น้‡็ฟป่ฏ‘
const results = await i18n.batchTranslate(['k1', 'k2', 'k3']);

// ่Žทๅ–็ปŸ่ฎก
const stats = i18n.getStats();

// ไบ‹ไปถ็›‘ๅฌ
i18n.onLocaleChange((from, to) => {});

I18nEngine โ€” ๅผ•ๆ“Ž็ฑป

class I18nEngine {
  constructor(config?: I18nEngineConfig);

  init(): Promise<void>;
  destroy(): Promise<void>;

  setLocale(locale: string): Promise<void>;
  t(key: string, params?: TranslateParams): string;
  batchTranslate(keys: string[]): Promise<Record<string, string>>;

  getTranslations(): TranslationMap;
  getStats(): EngineStats;

  onLocaleChange(callback: (from: string, to: string) => void): () => void;

  plugins: PluginManager;
}

๐Ÿ”ง ้ซ˜็บงๅŠŸ่ƒฝ

1. ๅ‘ฝๅ็ฉบ้—ด (Namespaces)

import { createNamespace } from '@yyc3/i18n-core';

// ๅˆ›ๅปบๅ‘ฝๅ็ฉบ้—ด
const userNS = createNamespace('user');
const productNS = createNamespace('product');

// ไฝฟ็”จๅ‘ฝๅ็ฉบ้—ด
userNS.t('profile.name');     // user.profile.name
productNS.t('detail.title');  // product.detail.title

2. ่ฐƒ่ฏ•ๆจกๅผ

const engine = new I18nEngine({ debug: true });

// ๆต่งˆๅ™จๆŽงๅˆถๅฐ่ฎฟ้—ฎ
window.__i18n_debug__ = {
  engine,
  getCurrentState: () => ({
    locale: engine.currentLocale,
    cache: engine.cache.getStats(),
    plugins: engine.plugins.list(),
  }),
};

// ๅผ€ๅ‘ๆ—ถๆŸฅ็œ‹็Šถๆ€
console.log(window.__i18n_debug__.getCurrentState());

3. ๅคšๅฎžไพ‹ๆ”ฏๆŒ

import { I18nEngine } from '@yyc3/i18n-core';

// ๅˆ›ๅปบๅคšไธช็‹ฌ็ซ‹ๅฎžไพ‹
const adminI18n = new I18nEngine({ defaultLocale: 'zh-CN' });
const userI18n = new I18nEngine({ defaultLocale: 'en' });

// ๅ„่‡ช็‹ฌ็ซ‹่ฟ่กŒ
adminI18n.t('dashboard.title'); // ไธญๆ–‡
userI18n.t('home.welcome');     // English

4. ่‡ชๅฎšไน‰้”™่ฏฏๅค„็†

const engine = new I18nEngine({
  onError: (error) => {
    // ๅ‘้€ๅˆฐ้”™่ฏฏ่ฟฝ่ธชๆœๅŠก
    Sentry.captureException(error);
  },
  missingKeyHandler: (key) => {
    console.warn(`[i18n] Missing key: ${key}`);
    return `[MISSING: ${key}]`; // ่ฟ”ๅ›žๅ ไฝ็ฌฆ
  },
});

5. ๆ€ง่ƒฝ็›‘ๆŽง

import { PerformanceTracker } from '@yyc3/i18n-core/plugins';

const tracker = new PerformanceTracker({
  slowThreshold: 10,  // ๆ…ขๆŸฅ่ฏข้˜ˆๅ€ผ (ms)
  percentiles: [50, 90, 95, 99],
}).createPlugin();

i18n.plugins.register(tracker);

// ่Žทๅ–ๆ€ง่ƒฝๆŠฅๅ‘Š
const report = tracker.getReport();
console.log(report.percentiles.p95); // 95ๅˆ†ไฝๅปถ่ฟŸ
console.log(report.slowQueries);     // ๆ…ขๆŸฅ่ฏขๅˆ—่กจ

๐ŸŽจ ๆœ€ไฝณๅฎž่ทต

โœ… ๆŽจ่ๅšๆณ•

  1. ไฝฟ็”จๅ…จๅฑ€ๅ•ไพ‹่ฟ›่กŒ็ฎ€ๅ•้กน็›ฎ

    import { i18n, t } from '@yyc3/i18n-core';
    t('key'); // ็ฎ€ๆดๆ˜Žไบ†
  2. ไฝฟ็”จ็‹ฌ็ซ‹ๅฎžไพ‹่ฟ›่กŒๅคงๅž‹้กน็›ฎ

    const engine = new I18nEngine({ /* config */ });
  3. ๅˆฉ็”จ Tree Shaking ๅ‡ๅฐไฝ“็งฏ

    import { ICUParser } from '@yyc3/i18n-core/icu'; // ไป…ๅผ•ๅ…ฅๆ‰€้œ€ๆจกๅ—
  4. ๅฏ็”จ็”Ÿไบง็Žฏๅขƒๆ’ไปถ

    if (process.env.NODE_ENV === 'production') {
      i18n.plugins.register(new MissingKeyReporter().createPlugin());
    }
  5. ็ป“ๅˆ AI ็ฟป่ฏ‘ๆๅ‡ๆ•ˆ็އ

    const ai = new AIProviderManager();
    ai.register(new OllamaProvider()); // ๅ…่ดนๆœฌๅœฐ็ฟป่ฏ‘

โŒ ้ฟๅ…ๅšๆณ•

  1. ไธ่ฆๅœจๅพช็Žฏไธญ้ข‘็น่ฐƒ็”จ setLocale

    // โŒ ้”™่ฏฏ: ๆ€ง่ƒฝ้—ฎ้ข˜
    for (const item of items) {
      await i18n.setLocale(item.locale);
    }
    
    // โœ… ๆญฃ็กฎ: ๆ‰น้‡ๅค„็†
    const translations = await i18n.batchTranslate(keys);
  2. ไธ่ฆๅฟฝ็•ฅ้”™่ฏฏๅค„็†

    // โŒ ้”™่ฏฏ: ๅฏ่ƒฝๆŠ›ๅผ‚ๅธธ
    t(userProvidedKey);
    
    // โœ… ๆญฃ็กฎ: ้…็ฝฎ missingKeyHandler
    const engine = new I18nEngine({
      missingKeyHandler: (key) => `[${key}]`,
    });
  3. ไธ่ฆๅœจ็”Ÿไบง็Žฏๅขƒๅผ€ๅฏ debug ๆจกๅผ

    // โŒ ้”™่ฏฏ: ๆณ„้œฒๅ†…้ƒจไฟกๆฏ
    const engine = new I18nEngine({ debug: true });
    
    // โœ… ๆญฃ็กฎ: ไป…ๅผ€ๅ‘็Žฏๅขƒ
    const engine = new I18nEngine({
      debug: process.env.NODE_ENV === 'development',
    });

๐Ÿงช ๆต‹่ฏ•่ฆ†็›–

ๆต‹่ฏ•็Ÿฉ้˜ต

ๆจกๅ—

ๆต‹่ฏ•ๆ–‡ไปถ

็”จไพ‹ๆ•ฐ

้€š่ฟ‡็އ

่ฆ†็›–็އ

Core Engine

engine-v2.test.ts

45

100%

94%

Cache

(ๅซๅœจ engine tests)

30

100%

96%

Plugins

plugins.test.ts

25

100%

91%

Formatter

formatter.test.ts

35

100%

93%

Detector

detector.test.ts

20

100%

89%

RTL Utils

rtl-utils.test.ts

28

100%

92%

Translate

translate.test.ts, translate-full.test.ts

60

100%

95%

ICU Parser/Compiler

icu/parser-compiler.test.ts

40

100%

90%

AI Providers

ai/providers.test.ts

35

100%

87%

Quality Estimator

ai/quality-estimator.test.ts

25

100%

85%

MCP Server

mcp/server.test.ts, mcp/i18n-tools.test.ts

40

100%

88%

Security

security/*.test.ts

30

100%

93%

Infrastructure

infra/*.test.ts

30

100%

90%

ๆ€ป่ฎก

28 files

443

โœ… 100%

92.5%

่ฟ่กŒๆต‹่ฏ•

# ๅ…จ้‡ๆต‹่ฏ•
pnpm test

# ็›‘ๅฌๆจกๅผ (ๅผ€ๅ‘ๆ—ถ)
pnpm test:watch

# ่ฆ†็›–็އๆŠฅๅ‘Š
pnpm test:coverage

# ๅ•ไธชๆ–‡ไปถ
pnpm test -- engine-v2.test.ts

# ๅŒน้…ๆต‹่ฏ•ๅ
pnpm test -- -t "should translate with interpolation"

โšก ๆ€ง่ƒฝๅŸบๅ‡†

ๅ“ๅบ”ๆ—ถ้—ด (Node.js 20, M2 Mac)

ๆ“ไฝœ

ๅนณๅ‡่€—ๆ—ถ

P99 ่€—ๆ—ถ

QPS

็ฎ€ๅ•็ฟป่ฏ‘ (็ผ“ๅญ˜ๅ‘ฝไธญ)

0.02ms

0.05ms

50,000+

ๅธฆๅ‚ๆ•ฐ็ฟป่ฏ‘

0.05ms

0.12ms

20,000+

ICU ๅคๆ•ฐ่ง„ๅˆ™

0.15ms

0.35ms

6,500+

ๆ‰น้‡็ฟป่ฏ‘ (100 keys)

8ms

15ms

12,000+

AI ็ฟป่ฏ‘ (Ollama)

1500ms

3000ms

0.67

AI ็ฟป่ฏ‘ (OpenAI)

800ms

2000ms

1.25

ๅ†…ๅญ˜ๅ ็”จ

ๅœบๆ™ฏ

ๅ†…ๅญ˜ๅ ็”จ

่ฏดๆ˜Ž

็ฉบๅผ•ๆ“Ž

~2MB

ๅŸบ็ก€ๅผ€้”€

ๅŠ ่ฝฝ 1 ่ฏญ่จ€

~5MB

ๅซ็ฟป่ฏ‘ๆ•ฐๆฎ

ๅŠ ่ฝฝ 10 ่ฏญ่จ€

~25MB

ๅ…จ้ƒจๅ†…็ฝฎ่ฏญ่จ€

็ผ“ๅญ˜ 10000 ๆก็›ฎ

~8MB

LRU Cache

AI Provider

~50MB

ๆจกๅž‹ๅŠ ่ฝฝ


๐Ÿ›ก๏ธ ๅฎ‰ๅ…จ็‰นๆ€ง

OWASP Level 4 ๅฎ‰ๅ…จๆ ‡ๅ‡†

ๅฎ‰ๅ…จ็ปดๅบฆ

ๅฎž็Žฐๆ–นๅผ

็Šถๆ€

ReDoS ้˜ฒๆŠค

ๅฎ‰ๅ…จๆญฃๅˆ™็ผ–่ฏ‘๏ผŒ่ถ…ๆ—ถไธญๆ–ญ

โœ…

ๆ—ถๅบๆ”ปๅ‡ป้˜ฒๆŠค

ๅธธ้‡ๆ—ถ้—ดๅญ—็ฌฆไธฒๆฏ”่พƒ

โœ…

่ทฏๅพ„้ๅކ้˜ฒๆŠค

็›ฎๅฝ•้€ƒ้€ธๆฃ€ๆต‹ไธŽ้˜ปๆญข

โœ…

ๆณจๅ…ฅๆฃ€ๆต‹

SQL/Command ๆณจๅ…ฅๆจกๅผ่ฏ†ๅˆซ

โœ…

ๅŠ ๅฏ†้šๆœบๆ•ฐ

ไฝฟ็”จ crypto.randomBytes

โœ…

ๅฎ‰ๅ…จ็คบไพ‹

import { safeRegexCompile } from '@yyc3/i18n-core/lib/security/safe-regex';
import { constantTimeStringEqual } from '@yyc3/i18n-core/lib/security/secret-equal';
import { guardAgainstPathTraversal } from '@yyc3/i18n-core/lib/utils/path-guards';

// ๅฎ‰ๅ…จ็š„ๆญฃๅˆ™่กจ่พพๅผ็ผ–่ฏ‘ (้˜ฒ ReDoS)
const regex = safeRegexCompile(userInput, { timeout: 1000 });

// ๅธธ้‡ๆ—ถ้—ดๆฏ”่พƒ (้˜ฒๆ—ถๅบๆ”ปๅ‡ป)
const isEqual = constantTimeStringEqual(tokenA, tokenB);

// ่ทฏๅพ„้ๅކ้˜ฒๆŠค
guardAgainstPathTraversal('../../etc/passwd'); // ๆŠ›ๅ‡บ SecurityError

โ“ ๅธธ่ง้—ฎ้ข˜

Q1: ๅฆ‚ไฝ•ๆทปๅŠ ่‡ชๅฎšไน‰่ฏญ่จ€๏ผŸ

import { i18n } from '@yyc3/i18n-core';

// ๅŠจๆ€ๅŠ ่ฝฝ็ฟป่ฏ‘
await i18n.addLocale('custom-LANG', {
  welcome: 'ๆฌข่ฟŽ',
  greeting: 'ไฝ ๅฅฝ๏ผŒ{name}๏ผ',
});

Q2: ๅฆ‚ไฝ•ๅœจ SSR (ๆœๅŠก็ซฏๆธฒๆŸ“) ไธญไฝฟ็”จ๏ผŸ

// Next.js ็คบไพ‹
import { I18nEngine } from '@yyc3/i18n-core';

let engine: I18nEngine;

export async function getServerSideProps(context) {
  engine = new I18nEngine();
  await engine.init();
  await engine.setLocale(context.locale);

  return {
    props: {
      initialLocale: context.locale,
      translations: engine.getTranslations(),
    },
  };
}

Q3: ๅฆ‚ไฝ•ๅค„็†ๅŠจๆ€็ฟป่ฏ‘้”ฎ๏ผŸ

// ไฝฟ็”จ missingKeyHandler ๆ‹ฆๆˆชๆœช็Ÿฅ้”ฎ
const engine = new I18nEngine({
  missingKeyHandler: (key) => {
    // ๅ‘้€ๅˆฐ็ฟป่ฏ‘ๆœๅŠกๆˆ–่ฟ”ๅ›ž้ป˜่ฎคๅ€ผ
    logMissingKeyToServer(key);
    return humanizeKey(key); // 'user.profile.name' โ†’ 'User Profile Name'
  },
});

Q4: AI ็ฟป่ฏ‘็š„่ดจ้‡ๅฆ‚ไฝ•ไฟ่ฏ๏ผŸ

import { QualityEstimator } from '@yyc3/i18n-core/ai';

const qe = new QualityEstimator();
const result = await qe.estimate({
  sourceText: 'Hello',
  translatedText: 'ไฝ ๅฅฝ',
  sourceLocale: 'en',
  targetLocale: 'zh-CN',
});

if (result.score > 0.9 && result.issues.length === 0) {
  console.log('โœ… ็ฟป่ฏ‘่ดจ้‡ไผ˜็ง€');
} else {
  console.log('โš ๏ธ ้œ€่ฆไบบๅทฅๅฎกๆ ธ:', result.issues);
}

Q5: ๅฆ‚ไฝ•ไธŽ็Žฐๆœ‰ i18n ๆ–นๆกˆ่ฟ็งป๏ผŸ

่ฏทๅ‚่€ƒ่ฏฆ็ป†็š„ ่ฟ็งปๆŒ‡ๅ—๏ผŒๆถต็›–ไปŽ react-i18nextใ€vue-i18n ็ญ‰ๆ–นๆกˆ็š„ๅฎŒๆ•ด่ฟ็งปๆญฅ้ชคใ€‚


๐Ÿ”„ ่ฟ็งปๆŒ‡ๅ—

ไปŽ v1.x ๅ‡็บงๅˆฐ v2.x

ไธป่ฆ Breaking Changes:

  1. ๅŒ…ๅๅ˜ๆ›ด: @yyc3/i18n โ†’ @yyc3/i18n-core

  2. ็ฑปๅ้‡ๅ‘ฝๅ: I18nManager โ†’ I18nEngine

  3. ๆ’ไปถๆŽฅๅฃๆ›ดๆ–ฐ: ๆ–ฐๅขžๅฟ…้œ€็š„ name ๅฑžๆ€ง

  4. ้…็ฝฎๆ ผๅผ่ฐƒๆ•ด: Cache ๅ’Œ Debug ้…็ฝฎ็ป“ๆž„ๅ˜ๅŒ–

่ฏฆ็ป†่ฟ็งปๆญฅ้ชค่ฏทๅ‚้˜… MIGRATION_GUIDE.mdใ€‚


๐Ÿค ่ดก็ŒฎๆŒ‡ๅ—

ๆˆ‘ไปฌๆฌข่ฟŽ็คพๅŒบ่ดก็Œฎ๏ผ่ฏท้ตๅพชไปฅไธ‹ๆต็จ‹๏ผš

  1. Fork ๆœฌไป“ๅบ“

  2. ๅˆ›ๅปบ็‰นๆ€งๅˆ†ๆ”ฏ (git checkout -b feature/amazing-feature)

  3. ๆไบคๆ›ดๆ”น (git commit -m 'Add amazing feature')

  4. ๆŽจ้€ๅˆ†ๆ”ฏ (git push origin feature/amazing-feature)

  5. ๅผ€ๅฏ Pull Request

ๅผ€ๅ‘ๆต็จ‹

# ๅ…‹้š†ไป“ๅบ“
git clone https://github.com/YanYuCloudCube/Family-PAI.git

# ๅฎ‰่ฃ…ไพ่ต–
pnpm install

# ่ฟ›ๅ…ฅ i18n-core ๅŒ…็›ฎๅฝ•
cd packages/i18n-core

# ๅผ€ๅ‘ๆจกๅผ
pnpm build:watch

# ่ฟ่กŒๆต‹่ฏ•
pnpm test

# ็ฑปๅž‹ๆฃ€ๆŸฅ
pnpm lint

# ๆ ผๅผๅŒ–ไปฃ็ 
pnpm format

ไปฃ็ ่ง„่Œƒ

  • TypeScript strict mode

  • ไธบๅ…ฌๅ…ฑ API ๆทปๅŠ  JSDoc ๆณจ้‡Š

  • ๆ–ฐๅŠŸ่ƒฝๅฟ…้กปๅŒ…ๅซๅฏนๅบ”ๆต‹่ฏ•

  • ้ตๅพช OWASP ๅฎ‰ๅ…จ็ผ–็ ่ง„่Œƒ


๐Ÿ“„ License

MIT ยฉ YYCยณ AI Team


YYCยณ AI Family โ€” ๅ…ซไฝๆ‹ŸไบบๅŒ–AIๅฎถไบบ็š„ๆ™บ่ƒฝไธญๆžข

ไบ”้ซ˜ ยท ไบ”ๆ ‡ ยท ไบ”ๅŒ– ยท ไบ”็ปด


ๆ–‡ๆกฃ็‰ˆๆœฌ: 2.3.0 | ๆœ€ๅŽๆ›ดๆ–ฐ: 2026-04-24

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

โ€“Maintainers
โ€“Response time
โ€“Release cycle
โ€“Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that lets AI agents read and write locale JSON translation files directly from the conversation without loading the whole catalog into context.
    20
    1
    ISC
  • A
    license
    A
    quality
    A
    maintenance
    MCP server for managing i18n translation files โ€” gives your AI agent full control over your app's translations without dumping entire locale files into context.
    18
    251
    11
    MIT

View all related MCP servers

Related MCP Connectors

  • OCR, transcription, file extraction, and image generation for AI agents via MCP.

  • 100+ MCP tools for AI agents: content metadata, trade intelligence, business-expertise analysis.

  • Hosted MCP with 91 agent tools: X, domains, SEO, Maps, Trends, Search, YouTube, TikTok, and more.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/YYC-Cube/YYC3-i18n-Core'

If you have feedback or need assistance with the MCP directory API, please join our Discord server