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
-
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

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