@wfh/translate-generator

1.1.5 • Public • Published

This package is deprecated!


Text Translation & i18n

  • Package 结构 - 哪里存放i18n资源
  • 使用国际化文件资源
  • 全局配置文件config.yaml
  • 打包编译命令
  • 打包后的输出bundle目录结构
  • 客户端Javascript API,自动跳转不同语言页面]
  • 自动收集可翻译文字并生成可翻译文件的命令
    • 扫描的规则
  • 自动替换翻译的文字到不同的语言
  • NodeJS 端i18n

Package 结构 - 哪里存放i18n资源

为你的package添加本地化的文件,可以是各种能被require()的类型文件,比如.js, .json, .yaml, .yml, 统一放在一个目录下,推荐是 <package-folder>/i18n,这样大家可以达成共识,方便代码阅读。

package root folder
	├─ browser/
	├─ server/
	├─ i18n/
	|	├─ index.js
	|	├─ message-en.yaml
	|	├─ message-zh.yaml
	|	├─ message-zh-CN.yaml
	|	├─ feature-en.js
	|	├─ styles-en/
	|	|	├─ foobar.less
	|	... ...
	├─ README.md
	└─ package.json

文件名或者子目录名需要带有locale的标识,比如"en", "zh-CN"等。

使用国际化文件资源

e.g. JS files

require('<package-name>/i18n/message-{locale}.yaml');
require('./i18n/message-{locale}.yaml'); //可以相对路径
require('<package-name>/i18n/feature-{locale}.js');
require('./i18n/feature-{locale}.js'); //可以相对路径

LESS files

// LESS i18n resource的import 路径必须是"npm://<package-name>"开始,不能是相对路径
import "npm://<package-name>/i18n/foo-{locale}-bar.less";
import "npm://<package-name>/i18n/styles-{locale}/foobar.less";

{locale} 会在编译时被替换成相应的locale string 如"en", "zh"等,只要对应的文件路径是存在。

全局配置文件config.yaml

用来告诉我们的自动化可翻译文字扫描工具,已经drcp compile命令我们有多少locale语言当前支持
config.yaml文件

locales:
    - zh # 放在第一个的是默认locale
    - en

以上也是默认的配置,所以相应package如果支持i18n至少提供这些locale的文件。

打包编译命令

打包,并且用默认locale "zh" 替换所有JS, LESS中的require, import语句中的{locale}

drcp compile
# same as:
drcp compile --locale zh

打包,并且用非默认的locale "en" 替换所有JS, LESS中的require, import语句中的{locale}

drcp compile --locale en

所以当在开发环境drcp compile的实际编译目标仅仅是当前配置的默认locale。在生产环境时我们需要对多个locale分别执行多次打包命令。

打包后的输出bundle目录结构

默认locale的drcp compile输出的JS bundle, CSS bundle, 入口Html文件在 dist/static/下。非默认locale的JS bundle, CSS bundle, 入口Html文件在dist/static/<locale>下,e.g.

dist/
	└─ static/
		├─ js/
		├─ css/
		├─ foo-package/
		|		└─  index.Html
		├─ index.html
		└─ en/
			├─ js/
			├─ css/
			├─ foo-package/
			|		└─  index.Html
			└─ index.html

所以假设某个默认locale语言的页面访问路径是http://localhost:8080/foo-package/index.html,
对应非默认locale语言的(假设是"en")页面则是 http://localhost:8080/en/foo-package/index.html

客户端Javascript API,自动跳转不同语言页面

这些API可以帮助判断当前locale和为切换locale提供信息

var api = require('__api');
var lang = api.urlSearchParam().lang; // Get URL search param "lang"
lang = api.getPrefLanguage() // Get perferred language from Browser's user setting
var locales = api.config().locales; // Get all supported locale list from config.yaml
var currLocale = api.config().buildLocale; // Get current built-out locale

其中api.getPrefLanguage() 会根据浏览器语言设置匹配一个config.yaml locales中的一个, 浏览器语言的判断优先顺序是根据:

  • navigator.languages[0]
  • navigator.language
  • navigator.browserLanguage
  • navigator.systemLanguage
  • navigator.userLanguage
  • navigator.languages[1]

页面切换语言可以通过Server 端redirect URL地址或者,浏览器端HTML Anchor element, JS window.location=等跳转的方式实现, e.g. 切换"en"

简单的来说就是:

window.location='http://localhost:8080/en/foo-package/index.html';

或者一个更全面的API

var api = require('__api');
// If your web page runs inside DR company's mobile phone app
// We have a special component "@dr/dr-js-bridge" to work with language setting
var appInfo = require('@dr/dr-js-bridge').getAppInfo();
if (api.entryPackage === api.packageName) {
	// 确保在访问你的组件内的入口页面,做语言跳转,如果有时候你的组件正在
	// 被另一个组件当成library调用,这种情况不应该做语言切换
	var lang = appInfo.isCompanyApp || api.urlSearchParam().lang || api.getPrefLanguage();
	if (!api.reloadToLocale(lang)) // 如果当前页面语言不是首选语言 api.reloadToLocale 跳转到页面,并返true
		require('./browser.js');
} else {
	require('./browser.js');
}
var lang = api.urlSearchParam().lang || api.getPrefLanguage();
// Get URL parameter "?lang=<locale>" or Browser perferred language.
if (!api.reloadToLocale(lang)) {
	// If current page shows default language and the URL is like
	// "<staticAssetsURL>/pagePath", then we switch to target "lang" by
	// executing `window.location = "<staticAssetsURL>/<lang>/pagePath"`
	require('./main.js');
	// Render page and do business logic...
}

判断当前URL parameter “lang” 或浏览器首选语言, 如果当前页面是默认配置语言,切换到目标语言的URL上

如果是Node Server端, 可以通过Request "Accept-Language" header, redirect 到相应的URL

自动收集可翻译文字并生成可翻译文件的命令

使用translate-generator 工具

drcp compile <package-name..> --translate

扫描.js, .html 文件,自动生成可翻译的文件

	<package-dir>/i18n/
		├─ index.js
		├─ messages-en.yaml
		├─ messages-zh.yaml
		└─ ... other locale files in form of messages-{locale}.yaml

message-en.yaml里已经自动填满了message key, 从此你就不用手工为每个text label添加key到locale文件了。

扫描的规则

drcp compile --translate 会扫描指定package下的所有.js, .html文件

  • .html 文件,会使用cheerio 查找所有符合query [dr-translate], [t]的element, 也就是带有属性translate的element:

     <any-element dr-translate>KEY1</any-element>
     <any-element class="dr-translate">KEY2</any-element>
     <any-element t>KEY3</any-element>
     <any-element class="t">KEY4</any-element>

    class, attribute中有名为"t", "dr-translate"的element的html内容 KEY1KEY2都会被认为是locale message key。可以翻译的文字没有字符限制,比如可以是包含html, 甚至是AngularJS之类的浏览器端template engine

     <any-element dr-translate>Hellow <b>\{\{ name \}\}</b></any-element>

    Hellow <b>\{\{ name \}\}'</b> 整个都是key。

    另外是对可翻译HTML元素属性值的扫描 所有带有属性t-a="<attribute-name> <attribute-name> ..."的HTML element, 的指定属性(标注多个属性可以用空格或,间隔), <img alt>placeholder属性被默认为可以国际化翻译的值,不需要t-a=""的属性标注, 例如,

     <meta name="mymeta" content="translatableContent" t-a="content">
     <input type="text" placeholder="translatable"/>
     <img src="" alt="translatableAlt">

    以上例子中translatableContent, translatable, translatableAlt都会在扫描和打包时被提取出来作为可以翻译文字的key

    注意,i18n工具增强@dr/translate-generator是一个Webpack loader,对html, js[x]的处理方式是不同的,React JSX中的HTML被视为JS文件处理i18n, 目前被当成html处理t, t-a等特殊属性,该功能还为开发,鼓励贡献

  • .js 文件, 会在Acorn Javascript语法分析器生成的AST里查找function name是 drTranslate 的call expression, 第一个参数被识别收集为message key:

     drTranslate('KEY1');

    请不要使用其他的表达式作为drTranslate的参数, 只能使用String literal, 无法识别收集 如 drTranslate('foo' + 'bar' + x) 等复杂表达式,对于有特定format的表达式可以使用lodash template等方式,比如, _.template(drTranslate('foobar<%=x%>'))({x: x}) 将string模板作为可以翻译的文字

    除了drTranslate 还可以配置增加自定义的被扫描function name, 比如增加"myText()", 添加到config.yaml:

     translate-generator:
     	scanMethodNames:
     			- myText

自动替换翻译的文字到不同的语言

替换文件仅包括浏览器端Browserify会打包的JS + HTML bundle文件,entry page 文件,不包含NodeJS端的JS文件,或者是ExpressJS template HTML文件! 打包时替换可翻译文字的好处是,不会与Browser端framework template engine冲突,开发国际化更简单,对搜索引擎友好,对browser的性能没有损耗。

drcp compile [--locale <locale>] 时会替换所有Entry Page, JS文件中的 drTranslate('some text') html中<any-element class="t"></any-element> 等原先符合扫描收集规则的地方将会被替换为/i18n/message-{locale}.yaml所配置的内容,依然是通过Cheerio, Acorn来实现的。 e.g.

var text = drTranslate('中文');
doSomething(drTranslate('中文'));

替换后会是

var text = '中文';
doSomething('中文');

通过组件@dr/translate-generator, @dr-core/browserify-builder .addTransform()等实现的,简单的说就是Browserify的一个transform插件,有兴趣的可以自行扩展。

NodeJS 端i18n

需要自行实现,简单的说就是基于

require('./i18n/foobar-' + locale + '.js');

Readme

Keywords

none

Package Sidebar

Install

npm i @wfh/translate-generator

Weekly Downloads

2

Version

1.1.5

License

ISC

Unpacked Size

75.6 kB

Total Files

19

Last publish

Collaborators

  • liujingbreak