I18next 是一款用JavaScript编写的国际化框架。

为什么需要国际化

一般在编写网站的时候,网页需要向用户展现一些文字,假如你的网站完全面向中国用户,那么你可以把网页里的内容写成中文。但是如果你还要面向英文用户,那么你就不能直接把内容写成中文了,你的网站需要国际化。你需要使用一些技术来让程序自动切换内容的显示,网页的总体结构是不变的,但是内容需要随着用户的改变而改变。

但是可能有人会说,各准备一个英文和一个中文的网页不就可以了吗?那么请问以后再出现法文,葡萄牙文,西班牙文的需求呢?这种需求其实很常见,比如ebay.com,它面向不同国家有不同的显示,甚至在一个国家还有多种显示(比如加拿大,分为加拿大英语区和加拿大法语区)。如果针对一种语言准备一套网站,那将是大大的代码冗余和资源的浪费。

为什么使用i18next

I18next提供了JavaScript开发中能想到的所有关于i18n的需求,它提供了一个完整的解决方案,不管是本地客户端还是服务端,移动端Web还是桌面端Web。当然,它不仅仅可以用在JavaScript平台,它还能用在其他平台,比如php,ios等。

以下是官方的一段话:

Learn once - use everywhere. The community made integrations for frameworks like react.js, angular.js, vue.js and many more. But this is not where it ends…you can use i18next with node.js, php, ios, android and other platforms.

I18next reached not only the web, but also mobile and desktop development.

翻译过来大概意思是:它的社区已经将i18next和react.js,angular.js,vue.js等热门的框架集成,而且你能在Node.js,php,ios,android等平台上使用,除了Web端,你还能在手机端桌面端的开发中使用。

开始使用

安装

1
2
3
4
5
6
7
8
# yarn
$ yarn add i18next

# npm
$ npm install i18next --save

# bower
$ bower install i18next

Hello World

这里直接修改自官网的Hello World:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var i18next = require('i18next');

var option = {
lng: 'en',
resources: {
en: {
translation: {
"hello-world": "Hello world!"
}
}
}
};

var callback = function(err, t) {
console.log(i18next.t('hello-world'));
}

i18next.init(option, callback);

执行过后会输出:

1
2
3
$ node .
Hello world!
Done in 0.18s.

这里调用的是 i18next 的 init() api 进行初始化,init()需要传入两个参数option和callback函数。

在 callback 函数中, i18next.t(‘hello-world’) 就是键 ‘hello-world’ 所对应值 ‘Hello world!’。

在 option 中,lng 表示当前采用的是 en 语言所对应的资源,而 resources 就是资源配置。那么,如果想输出中文呢?很简单,只要在 resources 中加入对应语言的键值对即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var i18next = require('i18next');

var option = {
lng: 'zh_CN',
resources: {
en: {
translation: {
"hello-world": "Hello world!"
}
},
zh_CN: {
translation: {
"hello-world": "你好世界!"
}
}
}
};

var callback = function(err, t) {
console.log(i18next.t('hello-world'));
}

i18next.init(option, callback);

再将 option.lng 改为 ‘zh_CN’,这样执行后输出:

1
2
3
$ node .
你好世界!
Done in 0.18s.

最基本的国际化方案就是这么简单,实际应用中会根据用户的某些国家属性来决定使用哪套资源,举个例子,用eBay来说,假如用户直接访问 www.ebay.com,系统会默认显示英文,假如用户访问www.ebay.ch,看上去整个网页的结构布局和 www.ebay.com 一样,只不过语言变成了德文,这里就是根据域名的不同来选择不同的服务器,而不同的服务器实际上运行的是一套代码。

当然还可以根据用户所在国家自动显示不同的语言,在这里就不多说了。

以上代码完整的项目地址是 https://github.com/henryhuang/i18next-samples/tree/master/i18next-basic-sample .

结合 Express 使用

主要的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

...

// 初始化 i18next
i18n.use(i18nMiddleware.LanguageDetector).use(i18nFsBackend).init({
lng: 'en',
preload: [
'en', 'zh-CN'
],
backend: {
loadPath: path.resolve(__dirname, './lang/{{lng}}/translation.json')
}
});
//
app.use(i18nMiddleware.handle(i18n));

...

app.get('/lang/:lang', function(req, res) {
res.cookie('i18next', req.params.lang);
res.redirect('/');
});

完整的项目代码在这里 https://github.com/henryhuang/i18next-samples/tree/master/i18next-express-sample .