【第1032期】前端國際化
前言
第一次了解到這個概念,之前在QQ群也有人聊前端國際化如何做的問題,不知道這篇對他有幫到嗎?今日早讀文章來自阿里@sundway分享。
正文從這開始~
何為國際化
國際化(Internationalization)通常在很多地方會用 i18n 代替,意思就是 I 加18個字母加 n。跟國際化還有一個類似的概念叫做本地化(Localization)通常用 L10n 表示。這是兩個比較接近的概念,它之間有什麼區別呢?W3C 的 Localization vs. Internationalization 這篇文檔詳細了介紹了這一點,對國際化理解還不是特別清晰的強烈建議讀一下這篇文章。簡單的理解就是,國際化就是為本地化做很多的前期工作,可以根據所做的事情是否屬於只是為某一地區來區分國際化和本地化。國際化包含的東西很多,對於前端,最常接觸到的就是將可本地化的元素與源代碼或內容分開,以便可以根據需要根據用戶的國際偏好來載入或選擇本地化的替代。但國際化的工作遠不止這些,例如國際化CDN 部署,Unicode 編碼都可以算作國際化的範疇。
國際化 API
其實在 2012 年就已經擬定了國際化 API,詳盡的內容可以參考 《ECMAScript Internationalization API Specification》。下面重點介紹幾個 API 的使用:
Intl.Collator
Intl.Collator 是用於語言敏感字元串比較的 collators構造函數。語法:
newIntl.Collator([locales[,options]])
Intl.Collator.call(this[,locales[,options]])
上述語法中,locales 是可選參數,locales 的參數必須遵從 BCP 47 規範,locales 標記必須是 "en-US" 和 "zh-Hans-CN 等,這個標記包含了語言、地區和國家。完整的列表可以查看 IANA language subtag registry。options 也是可選參數,它包含了特定比較選項的對象。
示例:
varco1=newIntl.Collator(["de-DE-u-co-phonebk"]);
varco2=newIntl.Collator(["de-DE"]);
varco3=newIntl.Collator(["en-US"]);
vararr=["?","ad","af","a"];
if(console&&console.log){
console.log(arr.sort(co1.compare));// Returns a,ad,?,af
console.log(arr.sort(co2.compare));// Returns a,?,ad,af
console.log(arr.sort(co3.compare));// Returns a,?,ad,af
}
Intl.DateTimeFormat
Intl.DateTimeFormat是根據語言來格式化日期和時間的類的構造器類。
newIntl.DateTimeFormat([locales[,options]])
Intl.DateTimeFormat.call(this[,locales[,options]])
Intl.DateTimeFormat是根據語言來格式化日期和時間的類的構造器類。可以使用 options 參數來自定義 日期時間格式化方法返回的字元串。
vardate=newDate(Date.UTC(2012,11,20,3,,));
// 下面是假定的所在時區
// 洛杉磯(America/Los_Angeles for the US)
// 美式英語(US English) 使用 month-day-year 格式
console.log(newIntl.DateTimeFormat( en-US ).format(date));
// "12/19/2012"
// 英式英語(British English) 使用 day-month-year 格式
console.log(newIntl.DateTimeFormat( en-GB ).format(date));
// "20/12/2012"
// 韓國使用 year-month-day 格式
console.log(newIntl.DateTimeFormat( ko-KR ).format(date));
// "2012. 12. 20."
//大部分阿拉伯國家使用阿拉伯字母(real Arabic digits)
console.log(newIntl.DateTimeFormat( ar-EG ).format(date));
// "???/???/????"
//在日本,應用可能想要使用日本日曆,
//2012 是平成24年(平成是是日本天皇明仁的年號,由1989年1月8日起開始計算直至現在)
console.log(newIntl.DateTimeFormat( ja-JP-u-ca-japanese ).format(date));
// "平成24/12/20"
//當請求一個語言可能不支持,如巴厘(ban),若有備用的語言印尼語(id),
//那麼將使用印尼語(id)
console.log(newIntl.DateTimeFormat([ ban , id ]).format(date));
// "20/12/2012"
Intl.NumberFormat
Intl.NumberFormat是對語言敏感的格式化數字類的構造器類。
newIntl.NumberFormat([locales[,options]])
Intl.NumberFormat.call(this[,locales[,options]])
示例:
varnumber=123456.789;
// 德語使用逗號作為小數點,使用.作為千位分隔符
console.log(newIntl.NumberFormat( de-DE ).format(number));
// 123.456,789
// 大多數阿拉伯語國家使用阿拉伯語數字
console.log(newIntl.NumberFormat( ar-EG ).format(number));
// ??????????
// India uses thousands/lakh/crore separators
console.log(newIntl.NumberFormat( en-IN ).format(number));
// 1,23,456.789
// 通過編號系統中的nu擴展鍵請求, 例如中文十進位數字
console.log(newIntl.NumberFormat( zh-Hans-CN-u-nu-hanidec ).format(number));
// 一二三,四五六.七八九
//當請求的語言不被支持,例如巴里,包含一個回滾語言印尼,這時候就會使用印尼語
console.log(newIntl.NumberFormat([ ban , id ]).format(number));
// 123.456,789
這個例子顯示了一些本地化的數字格式的一些變化。為了獲得用於您的應用程序的用戶界面的語言格式,請確保設定了語言(可能還有一些回退語言)參數。
以下各瀏覽器的支持情況:
可以看到個瀏覽器對 Intl API 的支持已經相當不錯了。對於一些不兼容的瀏覽器,我們可以引入 Intl polyfill。
生產環境中的應用
在生產環境中我們一般會引用第三方庫,不同的技術方案引入的庫也會不同。以下是幾個主流的庫/框架的解決方案:
下面以 react 為例,這裡建議直接可以使用阿里開源的 react-intl-universal,相比於 Yahoo react-intl API,它不僅支持 react 組件,同時也支持原生 js。
importintlfrom react-intl-universal ;
// locale data
constlocales={
"en-US":require( ./locales/en-US.js ),
"zh-CN":require( ./locales/zh-CN.js ),
};
classAppextendsComponent{
state={initDone:false}
componentDidMount(){
this.loadLocales();
}
loadLocales(){
// init method will load CLDR locale data according to currentLocale
// react-intl-universal is singleton, so you should init it only once in your app
intl.init({
currentLocale: en-US ,// TODO: determine locale here
locales,
})
.then(()=>{
// After loading CLDR locale data, start to render
this.setState({initDone:true});
});
}
render(){
return(
this.state.initDone&&
{intl.get( SIMPLE )}
);
}
}
當然有些項目沒有使用上面任何一個庫/框架,例如阿里小蜜。也有相應地方案去解決。主要思路:
通過構建工具去完成樣式, 圖片替換, class屬性等的替換工作。
通用的翻譯函數去完成靜態文案及動態文案的翻譯工作。
阿里小蜜中使用的是 nunjucks 模版引擎,那麼這裡可以使用 nunjucks-intl。如果是其他模版工具,也可以自己在 polyfill 上寫一個簡單的實現。
最後,推薦一下 Yahoo 的 FormatJS,官方給出的解釋是一系列 JavaScript 庫的集合,主要用來格式化數字,日期和字元串。它包含一系列核心代碼,而這些代碼建立在 JS 原生 Intl 以及各種 i18n 標準之上的。
關於本文
作者:@sundway
原文:https://github.com/sundway/blog/issues/9
點擊展開全文
※咦?瀏覽器都能做人臉檢測了?
※你應該知道的Debug技巧
※ES8 新特性一覽
※【第1025期】理解Service Worker
※你與阿里雲就差一份簡歷?撩P6/P7前端工程師
TAG:前端早讀課 |
※【每日說明書 , 第1032期】資生堂 HAKU 美白淡斑精華 2018年新版 45g
※東方海外國際中期業績由盈轉虧1032萬美元
※各國核試驗次數,美國1032次,俄國715,我國卻那麼少!
※復星醫藥擬斥不超1.06億美元認購1032.1萬股BNI優先股
※蘋果公司有多少現金?10326個億!
※美國三大股指全面下跌 道瓊斯指數暴跌1032點
※你不知道的事實,美國人扼殺自己1032次,美本土1.1萬人死
※購彩者膽拖票中1032萬:仍有遺憾!
※道指暴跌1032點或創最大單周跌幅 投資人士稱是長期買入絕佳機會