Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fwh1990/i18n-chain
High performance i18n with typescript that support React, React-Native, Taro and NodeJs
https://github.com/fwh1990/i18n-chain
i18n i18n-typescript react-i18n react-native-i18n typescript-i18n
Last synced: about 2 hours ago
JSON representation
High performance i18n with typescript that support React, React-Native, Taro and NodeJs
- Host: GitHub
- URL: https://github.com/fwh1990/i18n-chain
- Owner: fwh1990
- License: mit
- Created: 2019-12-26T08:51:52.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2021-05-11T10:04:21.000Z (over 3 years ago)
- Last Synced: 2024-04-13T23:15:38.785Z (7 months ago)
- Topics: i18n, i18n-typescript, react-i18n, react-native-i18n, typescript-i18n
- Language: TypeScript
- Homepage:
- Size: 930 KB
- Stars: 34
- Watchers: 1
- Forks: 4
- Open Issues: 12
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
说到国际化,你是否也常年奔波于复制粘贴的重复劳动里?像 `t('home:submit')` `t('common:something:success')` 这些没有任何提示,需要脑子去记,不仅开发效率低,而且键盘敲快一点就容易打错字母,重点是你基本发现不了这种错误。
我更喜欢有提示的代码,利用`typescript`,我发明了一种使用链式操作的i18n组件,并拥有所有提示,就类似 `i18n.common.something.success` 这种,代码可以自动补全,保证不会写错。
[![License](https://img.shields.io/github/license/fwh1990/i18n-chain)](https://github.com/fwh1990/i18n-chain/blob/master/LICENSE)
[![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/fwh1990/i18n-chain/CI/master)](https://github.com/fwh1990/i18n-chain/actions)
[![Codecov](https://img.shields.io/codecov/c/github/fwh1990/i18n-chain)](https://codecov.io/gh/fwh1990/i18n-chain)# 兼容性
| IE | Edge | Chrome | Firefox | Safari | Node |
| -- | -- | -- | -- | -- | -- |
| 9+ | 12+ | 5+ | 4+ | 5+ | * |# 安装
### React | RN | Taro@3
```bash
yarn add @i18n-chain/react
```### NodeJS
```bash
yarn add @i18n-chain/node
```# 使用
### 定义本地化文件
```typescript
// ./src/i18n/locales/en.tsconst en = {
button: {
submit: 'Submit',
cancel: 'Go back',
},
user: {
profile: 'Tom',
},
};export default en;
export type Locale = typeof en;
``````typescript
// ./src/i18n/locales/zh.tsimport { Locale } from './en';
const zh: Locale = {
button: {
submit: '提交',
cancel: '返回',
},
user: {
profile: '原罪',
},
};export default zh;
```### 创建i18n实例
```typescript
// ./src/i18n/index.tsimport { createI18n } from '@i18n-chain/*';
import en from './locales/en';const i18n = createI18n({
defaultLocale: {
key: 'en',
values: en,
},
});export default i18n;
```### 导入语言
第一种, **直接定义**:
```typescript
import { createI18n } from '@i18n-chain/*';
import zh from './locales/zh';const i18n = createI18n({
defaultLocale: { ... },
});i18n.define('zh', zh);
export default i18n;
```第二种, **异步导入**。当组件检测到语言未定义时,会自动触发`loader`函数
```typescript
const i18n = createI18n({
defaultLanguage: { ... },
loader: (name) => import('./locales/' + name),
});export default i18n;
```### 切换语言
```typescript
i18n.locale('zh');
```### 字符串模板
有时候您需要在组件外预定义一系列内容,此时不得不使用字符串模板(`'button.submit'`)来代表,并在组件渲染时翻译成相应的文字。很显然,这串字符串没有任何提示,即使写错了也没人知道。别担心,框架提供了生成字符串模板的功能,现在一起试试
```typescript
const key = i18n.literal.button.submit;
key === 'button.submit' // trueconst value = i18n.translate(key);
value === 'Submit' // true
```
酷,带有提示的字符串模板也重新拥有了灵魂,不必再担心会写错了,让IDE和TS去处理吧。### 带参数的模板
当你想用参数的时候,你需要把模板写成数组的形式
```javascript
const en = {
property: ['{{property1}}template{{property2}}', { property1: value2, property2: value2 }],
};
```
数组第二个元素就是参数列表以及,你可以设置参数的默认值。```typescript
const en = {
user: {
profile: [
'My name is {{name}}, I born in {{country}}, I am {{age}} old now, my birthday is {{birthday}}',
{
country: undefined,
name: 'Tom',
age: (value: number = 20) => {
if (value <= 1) {
return `${value} year`;
} else {
return `${value} years`;
}
},
birthday: (value: Date) => {
return value.toString();
},
},
],
},
};////////////////////////////////////
// 上面的代码可以自动推导出和下面一致的类型:
interface User {
Profile {
country: string | number;
name?: string;
age?: number;
birthday: Date;
}
}
/////////////////////////////////////// 最小化调用
i18n.chain.user.profile({
country: 'Earth',
birthday: new Date(),
});// 增加可选的属性:`name` 和 `age`
i18n.chain.user.profile({
country: 'Earth',
name: 'Lucy',
age: 30,
birthday: new Date(),
});
```方法参数 `age` 和 `birthday` 的区别是,`age`的形参中含有默认值`(value: number = 20) => {...}`,而后者没有。有默认值意味着调用的时候可以不传参数。
------------
普通参数如果没有默认值,需要设置成`undefined`,这样typescript才能正确识别,并强制要求调用者输入对应的参数值。
```typescript
const en = {
template: ['Hello, {{world}}', { world: undefined }]
};
```### 在Hooks中使用
```typescript jsx
import React, { FC } from 'react';
import i18n from '../i18n';const App: FC = () => {
// 使用use使得切换语言时可以重渲染
const chain = i18n.use();return {chain.button.submit};
};export default App;
```### 在Class组件中使用
```typescript jsx
import React, { PureComponent } from 'react';
import { InjectedI18nProps } from '@i18n-chain/react';
import i18n from '../i18n';type Props = InjectedI18nProps;
class App extends PureComponent {
render() {
const { chain } = this.props;return {chain.button.submit};
}
};// 使用高阶组件使得切换语言时可以重渲染
export default i18n.hoc(App);
```# 在线Demo
[CodeSandbox](https://codesandbox.io/s/sleepy-dream-s7uqh)