亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

實(shí)戰(zhàn)React App的i18n

arashicage / 3374人閱讀

摘要:而就是產(chǎn)品具體實(shí)現(xiàn)某一種語(yǔ)言和文化的過(guò)程。貨幣的符號(hào),以及數(shù)字分割方式各個(gè)國(guó)家都存在不同。那么有沒(méi)有其他的復(fù)數(shù)形式回答當(dāng)然是肯定的,比如波蘭語(yǔ)。但這個(gè)是自己的語(yǔ)法,并非標(biāo)準(zhǔn),同時(shí)這個(gè)語(yǔ)法還會(huì)破壞的測(cè)試,并不是一個(gè)很好的選擇。

記得我剛來(lái)我們公司的時(shí)候,接手現(xiàn)在負(fù)責(zé)的項(xiàng)目的時(shí)候,我就發(fā)覺(jué)了一個(gè)問(wèn)題:所有的文本資源都是硬編碼在代碼里面。這當(dāng)然會(huì)帶來(lái)很多問(wèn)題。但考慮到我負(fù)責(zé)的這個(gè)項(xiàng)目是公司內(nèi)部的管理工具,同時(shí)大部分用戶都是中國(guó)人,因此抽離文本資源,做i18n的需求并不是十分強(qiáng)烈。

這周公司招了一位外籍員工。我并不確定她是哪一國(guó)人,不過(guò)從口音上來(lái)判斷,以及言談間她曾經(jīng)提到的加利福尼亞州,我想應(yīng)該是一位美國(guó)女性。老大說(shuō)她會(huì)和其他的PM一樣,居住在廈門(mén),遠(yuǎn)程工作,偶爾來(lái)辦公室上班。并且她也會(huì)使用我負(fù)責(zé)的這個(gè)工具。

現(xiàn)在i18n就有比較強(qiáng)烈的需求了。有必要出一個(gè)合理的架構(gòu),一勞永逸的解決問(wèn)題。

i18n的主要關(guān)注點(diǎn)

i18n是Internationalization的縮寫(xiě),實(shí)際上i18n應(yīng)該是指創(chuàng)建或者調(diào)整產(chǎn)品,使得產(chǎn)品具有能輕松適配指定的語(yǔ)言和文化的能力。當(dāng)然,我們還有另外一個(gè)概念,叫做Localization(簡(jiǎn)寫(xiě)L10n),也就是本地化。L10n正確的說(shuō)是指已經(jīng)全球化的產(chǎn)品,適配某一個(gè)具體語(yǔ)言和文化的這一個(gè)過(guò)程。

有點(diǎn)繞口,簡(jiǎn)單說(shuō)就是,i18n就是給產(chǎn)品添加新特性,使產(chǎn)品能夠支持對(duì)多種語(yǔ)言和文化(貨幣,時(shí)間等等)。而L10n就是產(chǎn)品具體實(shí)現(xiàn)某一種語(yǔ)言和文化的過(guò)程。

回過(guò)頭來(lái),i18n有這么幾個(gè)主要的關(guān)注點(diǎn):

Date and times formatting

Number formatting

Language sensitive string comparison

Pluralization

Date and times formatting

不同國(guó)家對(duì)應(yīng)的日期格式其實(shí)都是不同的,盡管我不覺(jué)得十分復(fù)雜,不過(guò)細(xì)節(jié)的處理上也是有很多選擇:

weekday,你可以設(shè)置成顯示全名字,比如zh-CN的星期四,en-US的Thursday等等

month,你可以設(shè)置成數(shù)字形式,全名,短名,類(lèi)似于12,December,Dec

...

完整的例子:

var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

// Results below use the time zone of America/Los_Angeles (UTC-0800, Pacific Standard Time)

// US English uses month-day-year order
console.log(new Intl.DateTimeFormat("en-US").format(date));
// → "12/19/2012"

// British English uses day-month-year order
console.log(new Intl.DateTimeFormat("en-GB").format(date));
// → "19/12/2012"

// Korean uses year-month-day order
console.log(new Intl.DateTimeFormat("ko-KR").format(date));
// → "2012. 12. 19."

// Arabic in most Arabic speaking countries uses real Arabic digits
console.log(new Intl.DateTimeFormat("ar-EG").format(date));
// → "???/???/????"

// for Japanese, applications may want to use the Japanese calendar,
// where 2012 was the year 24 of the Heisei era
console.log(new Intl.DateTimeFormat("ja-JP-u-ca-japanese").format(date));
// → "24/12/19"

// when requesting a language that may not be supported, such as
// Balinese, include a fallback language, in this case Indonesian
console.log(new Intl.DateTimeFormat(["ban", "id"]).format(date));
// → "19/12/2012"

var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
// request a weekday along with a long date
var options = { weekday: "long", year: "numeric", month: "long", day: "numeric" };
// an application may want to use UTC and make that visible
options.timeZone = "UTC";
options.timeZoneName = "short";
console.log(new Intl.DateTimeFormat("en-US", options).format(date));
// → "Thursday, December 20, 2012, GMT"
Number formatting以及Pluralization

數(shù)字的格式化,這個(gè)比較有趣。這里說(shuō)的數(shù)字,包含了貨幣,百分比,浮點(diǎn)數(shù)。其中貨幣的顯示應(yīng)該是相對(duì)比較復(fù)雜的。就以en-US來(lái)說(shuō),1000美元通常顯示成$1,000.00,而1000人民幣則會(huì)顯示成¥1,000.00。貨幣的符號(hào),以及數(shù)字分割方式各個(gè)國(guó)家都存在不同。

var number = 123456.789;

// German uses comma as decimal separator and period for thousands
console.log(new Intl.NumberFormat("de-DE").format(number));
// → 123.456,789

// India uses thousands/lakh/crore separators
console.log(new Intl.NumberFormat("en-IN").format(number));
// → 1,23,456.789

// the nu extension key requests a numbering system, e.g. Chinese decimal
console.log(new Intl.NumberFormat("zh-Hans-CN-u-nu-hanidec").format(number));
// → 一二三,四五六.七八九

var number = 123456.789;

// request a currency format
console.log(new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" }).format(number));
// → 123.456,79 €

// the Japanese yen doesn"t use a minor unit
console.log(new Intl.NumberFormat("ja-JP", { style: "currency", currency: "JPY" }).format(number));
// → ¥123,457

涉及到數(shù)字的,還有另外一個(gè)問(wèn)題,那就是語(yǔ)言的復(fù)數(shù)形式。中文似乎是沒(méi)有復(fù)數(shù)形式的,比如我們經(jīng)常說(shuō),一只兔子,兩只兔子。但是如果你用英語(yǔ),你就能明顯發(fā)覺(jué)不對(duì)。在英語(yǔ)里,應(yīng)該說(shuō)one rabbit,two rabbits,many rabbits。是的,英語(yǔ)里主要有兩種復(fù)數(shù)形式。

那么有沒(méi)有其他的 復(fù)數(shù)形式?回答當(dāng)然是肯定的,比如波蘭語(yǔ)。在波蘭語(yǔ),兔子一詞是królik,它的復(fù)數(shù)形式有這么幾種情況:

兔子的數(shù)量是1,那么應(yīng)該這么說(shuō),królik

如果兔子的數(shù)量在2-4之間,那么應(yīng)該說(shuō),królika

如果兔子的數(shù)量不是1,并且數(shù)量在0 - 1之間,或者5 - 9之間,或者12 - 14之間,都用królików

其他情況統(tǒng)一用króliki

解決方案的設(shè)計(jì) 項(xiàng)目背景

使用facebook官方的create-react-app腳手架創(chuàng)建的react app

關(guān)注點(diǎn)

目前我的解決方案有這么幾個(gè)關(guān)注點(diǎn):

文本資源要能夠輕易的導(dǎo)出

文本資源要孤立,避免和程序?qū)崿F(xiàn)的耦合

提供極簡(jiǎn)的接口方法設(shè)計(jì)

處理語(yǔ)言復(fù)數(shù)形式的庫(kù),應(yīng)該要能很好的拓展

技術(shù)選型

FormatJS, a modular collection of JavaScript libraries for internationalization that are focused on formatting numbers, dates, and strings for displaying to people.

解決方案 項(xiàng)目的目錄結(jié)構(gòu)
/--
  |--node_modules
  |--public
  |--src
    |--app
    |--common
    |--components
    |--configs
    |--i18n
      |--app
        |--routes
          |--setting
            |--en-US.js
            |--zh-CN.js
        |--index_en-US.js
      |--common
        |--index_en-US.js
      |--components
        |--index_en-US.js
      |--index_en-US.js
      |--index_zh-CN.js
    |--index.js
    |--logo.svg
    |--setupTests.js

如上文所示,我將所有的文本資源都獨(dú)立出來(lái),多帶帶存放在了i18n這個(gè)文件夾下。實(shí)際上,這些文本資源是有自己獨(dú)立的命名空間的,比如/src/app相關(guān)的文本資源,就會(huì)多帶帶放在這個(gè)文件夾下。其他的比如/src/common//src/components/就以此類(lèi)推。

Intl類(lèi)

這個(gè)類(lèi)很簡(jiǎn)單,封裝了處理文本資源的相關(guān)方法。getText的參數(shù)key需要特別注意,這個(gè)參數(shù)應(yīng)該是絕對(duì)路徑,比如app.routes.setting.preferences這樣。那么,相關(guān)的資源應(yīng)該是要放在/src/i18n/app/routes/setting/en-US.js文件里。

class Intl {
  static COMP_COMMON_TEXT = "components.Common";
  constructor(locale, resource) {
    this.locale = locale || "zh-CN";
    this.resource = resource;
  }
  getCommonText(key, params = {}) {
    return this.getText(`${Intl.COMP_COMMON_TEXT}.${key}`, params);
  }
  getText(key, params = {}) {
    let textResource = "";
    let source = this.resource;
    const locale = this.locale;
    const properties = key.split(".");
    const hasOwnProperty = Object.prototype.hasOwnProperty;
    properties.forEach((property, index) => {
      const stillNameSpace = index !== properties.length - 1;
      if (stillNameSpace) {
        source = source[property];
      } else if (hasOwnProperty.call(source[property], "default")) {
        textResource = source[property].default;
      } else {
        textResource = source[property] || "";
      }
    });
    const msg = new IntlMessageFormat(textResource, locale);
    return msg.format(params);
  }
}
IntlProvider

這是一個(gè)React組件。這里我們要利用React提供的Context這一特性,讓整個(gè)React App范圍內(nèi),都會(huì)從上下文中得到getText的方法。

我們都知道,Web app初始化的時(shí)候加載的Javascript腳本是越小越好,并且我們應(yīng)該盡力保證按需加載所需要的資源。這也是我們?yōu)槭裁蠢肳ebPack提供的Code Splitting機(jī)制讓W(xué)ebPack在打包的時(shí)候,切分出多帶帶的chunk,減少包的體積。

在WebPack 1.x的時(shí)候,我們可以使用require.ensure()。但這個(gè)是WebPack自己的語(yǔ)法,并非標(biāo)準(zhǔn),同時(shí)這個(gè)語(yǔ)法還會(huì)破壞Jest的測(cè)試,并不是一個(gè)很好的選擇。WebPack 2.x以后就開(kāi)始提供基于import()的Code Splitting機(jī)制。因此我們應(yīng)該利用起來(lái)。

具體的兩個(gè)文檔:

WebPack的Code Splitting with ES2015

Dynamic import() proposal

class IntlProvider extends React.Component {
  static DEFAULT_LOCALE = "zh-CN";
  static propTypes = {
    locale: PropTypes.string,
    children: PropTypes.element,
  };
  static defaultProps = {
    locale: "zh-CN",
    children: null,
  };
  static childContextTypes = {
    getText: PropTypes.func,
    getCommonText: PropTypes.func,
  };
  state = {};
  constructor(props, context) {
    super(props, context);
    this.childContext = new Intl(props.locale);
  }
  async componentWillMount() {
    const { locale } = this.props;
    const lang = await import(`../i18n/index_${locale}.js`);
    this.childContext = new Intl(locale, lang);
    this.setState({
      lang,
    });
  }
  getChildContext() {
    if (!this.childContext) {
      return {
        getText: (key, params) => "",
        getCommonText: (key, params) => "",
      };
    }
    return {
      getText: (key, params) => this.childContext.getText(key, params),
      getCommonText: (key, params) => this.childContext.getCommonText(key, params),
    };
  }
  render() {
    const comp = (!this.state.lang)
    ? null
    : React.Children.only(this.props.children);
    return comp;
  }
}
App

使用的時(shí)候也是相當(dāng)簡(jiǎn)單,不多說(shuō),直接上代碼。

class App extends React.PureComponent {
  render() {
    const { preferences } = this.props;
    return (
      
        
{this.props.children}
); } }
參考文檔

Tags for Identifying Languages

ECMAScript Internationalization API

Pluralization for JavaScript

ICU User Guide

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/89829.html

相關(guān)文章

  • 一個(gè)簡(jiǎn)單且靈活易用 React 格式化和 i18n 工具

    摘要:是一個(gè)簡(jiǎn)單且靈活易用的格式化和工具。它通過(guò)連接組件給組件一個(gè)默認(rèn)為的。是一個(gè)可以根據(jù)不同的顯示不同內(nèi)容的函數(shù)。和內(nèi)容之間的關(guān)系可以靈活地通過(guò)配置確定。在線互動(dòng)演示最簡(jiǎn)單的使用方式你好歡迎你好歡迎也可與相連 react-put 是一個(gè)簡(jiǎn)單且靈活易用的格式化和 i18n 工具。 它通過(guò)連接組件給組件一個(gè)默認(rèn)為 put 的 props。put 是一個(gè)可以根據(jù)不同的 key 顯示不同內(nèi)容的函數(shù)...

    20171112 評(píng)論0 收藏0
  • react 國(guó)際化了解一下

    摘要:先睹為快先看一下最后的成果來(lái)一發(fā)控制臺(tái)中對(duì)應(yīng)中的信息開(kāi)始原理原理其實(shí)很簡(jiǎn)單字符串替換。拉取遠(yuǎn)程的國(guó)際化文件到本地,再根據(jù)語(yǔ)言做一個(gè)映射就可以了。 背景 樓主最近新接了一個(gè)項(xiàng)目,從0開(kāi)始做,需要做多語(yǔ)言的國(guó)際化,今天搞了一下,基本達(dá)到了想要的效果, 在這里簡(jiǎn)單分享下: 一些探索 也說(shuō)不上是探索吧,就Google了一波, GitHub 上找了一個(gè)比較成熟的庫(kù) react-i18next,...

    CrazyCodes 評(píng)論0 收藏0
  • react 國(guó)際化了解一下

    摘要:先睹為快先看一下最后的成果來(lái)一發(fā)控制臺(tái)中對(duì)應(yīng)中的信息開(kāi)始原理原理其實(shí)很簡(jiǎn)單字符串替換。拉取遠(yuǎn)程的國(guó)際化文件到本地,再根據(jù)語(yǔ)言做一個(gè)映射就可以了。 背景 樓主最近新接了一個(gè)項(xiàng)目,從0開(kāi)始做,需要做多語(yǔ)言的國(guó)際化,今天搞了一下,基本達(dá)到了想要的效果, 在這里簡(jiǎn)單分享下: 一些探索 也說(shuō)不上是探索吧,就Google了一波, GitHub 上找了一個(gè)比較成熟的庫(kù) react-i18next,...

    魏明 評(píng)論0 收藏0
  • [ 一起學(xué)React系列 -- 10 ] i18n

    摘要:假如有這么一段句子這件衣服是人民幣如果我們想將一個(gè)數(shù)字以人民幣的形式寫(xiě)進(jìn)去的話可以這么做最終顯示結(jié)果是這件衣服是人民幣其實(shí)它做了兩件事一個(gè)是加符號(hào),另一個(gè)是加分隔符。同時(shí)表示人民幣,表示美元。 今天來(lái)介紹一個(gè)非常international的東西。 i18n國(guó)際化(internationalization)的簡(jiǎn)稱。之所以叫i18n,是因?yàn)樽帜竔和n之間有18個(gè)字母,所以才叫i18n。不...

    biaoxiaoduan 評(píng)論0 收藏0
  • React項(xiàng)目國(guó)際化(antd)多語(yǔ)言開(kāi)發(fā)

    摘要:本國(guó)際化方案僅針對(duì)技術(shù)棧,且不會(huì)涉及服務(wù)端國(guó)際化內(nèi)容。引入多語(yǔ)言環(huán)境的數(shù)據(jù)雖然我只用到了文本翻譯的功能,以為就不需要加載這些數(shù)據(jù),但后來(lái)發(fā)現(xiàn)這是必須的步驟。 前言 最近新接了一個(gè)項(xiàng)目,從0開(kāi)始做,需要做多語(yǔ)言的國(guó)際化,今天搞了一下,基本達(dá)到了想要的效果, 在這里簡(jiǎn)單分享下: showImg(https://segmentfault.com/img/bVbuiJB); 背景國(guó)際化方案國(guó)際...

    tracymac7 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<