iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 18
0
Modern Web

30 天打造 MERN Stack Boilerplate系列 第 18

Day 18 - Infrastructure - i18n

講到 i18n 真的就是只有機掰兩個字可以形容,因為它實在是一個非常破壞程式整體結構的東西,雖然可以搭配現有 Library 讓程式稍微容易維護一點,但是,如何在網站 Scale Up 之後 Lazy Load 語言包?如何讓程式在支援 i18n 的情況下依然高效運作?如何在 Library 限制的架構下盡可能讓整個網站都支援 i18n?

根據我的經驗,最好打從一開始就讓整個 Web 支援 i18n,如果一開始直接寫死語系,後面想要轉為多國語系時幾乎是整個專案都要砍掉重新規劃架構,所以我們的 Boilerplate 也是直接內建部分 i18n,選用的 Library 是 React-Intl。

React-Intl

React-Intl 是 Yahoo 公司推出的 React 多國語系 Library,裡面有非常多的 i18n 外加 l10n 的功能,同時它也是 React 社群中最熱門的 i18n 模組。

自訂的 LocaleProvider 元件

各位可以回顧一下 Day 14 - Infrastructure - Isomorphic Routing 曾經提過在 Root Component 用到了 LocaleProvider 元件,這是我們在 Boilerplate 中包裝 React-Intl 的 IntlProvider 所使用的元件,這麼做的目的有兩個:

  1. 搭配 Redux

當 Client Side 頁面初始化或是 Server Side 收到 Request 時,我們透過 Dispatch Action 把 Locale 存入 Store 裡,也就是說 IntlProviderprops.locale 需要依賴 Redux,所以我們的 Boilerplate 額外寫了 LocaleProvider 來注入 Store 中的 locale。

  1. 增加彈性

另一方面我們也考慮到大家的 i18n 不一定會採用 React-Intl 來實作,所以我把替換 Library 的彈性保留在 LocaleProvider 中,才不至於需要同時更改 Client Side 與 Server Side 的 Root Component。大家可以參考底下 Client Side 與 Server Side 的寫法,是共用 LocaleProvider 的。

Client Side

render(
  <Provider store={store}>
    <LocaleProvider>
      <Router
        history={history}
        onUpdate={logPageView}
        {...renderProps}
      >
        {routes}
      </Router>
    </LocaleProvider>
  </Provider>
, document.getElementById('root'));

完整程式碼:src/client/index.js

Server Side

const markup = '<!doctype html>\n' + renderToString(
  <Html
    initialState={finalState}
    assets={__webpackIsomorphicTools__.assets()}
  >
    <Provider store={req.store}>
      <LocaleProvider>
        <RouterContext {...renderProps} />
      </LocaleProvider>
    </Provider>
  </Html>
);

完整程式碼:src/server/controllers/react.js

Text Component

在我們的 Boilerplate 裡其實沒有使用到太多 React-Intl 的功能,多數情況下只有用到 FormattedMessage 元件,我們另外使用自訂的 Text 元件來包裝它,這同樣也是為了日後彈性考量,例如當你想要更換 i18n Library 或是甚至直接摘掉 Library 自己刻的話。不必把每個使用到 React-Intl 或 FormattedMessage 的元件都翻修過一次,只需要修改 Text 元件即可。


上一篇
Day 17 - Infrastructure - Permission Control
下一篇
Day 19 - Infrastructure - Pagination
系列文
30 天打造 MERN Stack Boilerplate30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言