5分鐘前端國際化

做者簡介 Kid 螞蟻金服·數據體驗技術團隊css

背景

須要國際化的react項目已經迭代了1年多,文件衆多,包含了jsx和普通的js對象文件。粗略估計有幾千個中文詞條。本文先介紹了採用的國際化方案,而後給出了國際化的過程和一個本身開發的腳本i18n-pick,按照教程,能夠幫助前端jsx項目5分鐘快速國際化。html

方案選擇

先大致上介紹下我選擇的國際化方案。國際化方案不少,我這裏列舉主要的幾種:前端

  • 編譯期間轉化:例如wepack的i18n-webpack-plugin,打包的時候對_('key')進行轉義
  • 運行期間轉化:react-intl等,把中文詞條寫成intl.get()的方式,在運行時獲取中文文案
  • wordpress的getText方案:gettext是一個filter 鉤子, 用來替換和本地化翻譯文本, 替換 __()、_e()、_x()、_ex() 和 _n() 函數包含的文本

因爲項目中我選擇了antd做爲視覺組件庫。因此想和antd提供的官方的國際化方式保持統一。antd推薦的是react-intl,不過另外一款相似的react-intl-universal也有很多人推薦,二者都比較成熟。因此我對兩種進行了比較:node

react-intl react-intl-universal
切換不刷新頁面
js文件支持(重要)
名詞單雙數,默認值,html
無破壞性 劣(裝飾器的代碼實現會改變ref)

名詞單雙數,默認值,html這種功能二者都有。我這裏就很少說了,具體的功能感興趣的能夠去看下API。比較關注的實際上是js文件支持那塊。react-intl只支持在jsx文件的內容中使用,可是因爲項目配置化編程的緣故,不少中文是寫在js對象中的。react-intl不支持在普通js對象中使用,很不方便。並且他的裝飾器實現會改變組件的ref。他惟一的好處是他的切換不須要刷新頁面,不過這種低頻的操做刷新頁面倒也無妨。react

針對以上的緣由,最終選擇了react-intl-universal做爲國際化方案。不事後來真實使用的時候,發現他提供的支持js對象的方式不是很好,因而仍是直接採起了react-intl-universal的思想。簡單的包裝了下他們的依賴intl-messageformat~這裏不詳細描述了,他的api官網文檔能夠查到。webpack

國際化方案選擇完了以後,開始執行階段。以上不管是選擇哪一種方案,編碼時基本都要求一種特殊的形式。要麼intl.get(),要麼是文案前加上_#這種。對於已經迭代了好久的項目,這就涉及到了一項力氣活。對中文文案進行提取以及替換。在這裏就直接分享腳本i18n-pick,描述下整個的國際化過程了。git

使用教程

主要分爲3步,安裝,掃描和提取,而後使用翻譯工具來進行詞條的翻譯,具體步驟以下:github

安裝

cnpm i i18n-pick cnpm用的淘寶鏡像,會快一些。web

掃描

./node_modules/i18n-pick/bin/i18n-pick.js scan [path] 命令最後的path選擇你的代碼目錄,運行完成後會在項目根目錄生成i18n-messages文件夾,包含jsx.text,text.text和zh-CH.json三個文件。具體實現是調用了babel的transformFileSync方法,在編譯成語法樹的時候,解析下面幾種babel-typenpm

  • JSXAttribute
  • JSXText
  • AssignmentExpression
  • ObjectProperty
  • ArrayExpression

這裏的基本含括了全部的狀況,若是有遺漏的,歡迎聯繫我。將解析的這幾種的value與/[\u4e00-\u9fa5]/進行比對。將包含中文文案的文件名,行數,文案內容記錄下來。JSX內的中文文案存到jsx.text,通常JS內的中文文案存到text.text。

分開存的緣由是由於替換的時候,JSX內的文案須要加上大括號才行。

同時我會把提取出來的文案內容存到了zh-CH.json中。這裏爲了配合翻譯工具atool-i10n的使用,json中的存儲格式也是按照他的要求提供的。這裏有個小tip,參見附錄。

提取

./node_modules/i18n-pick/bin/i18n-pick.js pick 而後執行pick操做,就是將jsx.text,text.text文件的內容按行分析,對文件進行內容替換。這裏最開始我將key值定爲了自增加的數字。爲了保證源碼必定的閱讀性,我同時將原文案以/**/註釋的形式標在文末。後來,吸收了評論區lany9527同窗的建議。將中文做爲了key值~~而後我會在文件頭部import一下依賴。效果以下:

base/reactIntlUnicersal這個文件須要本身放到本身的項目中,代碼能夠參考連接

翻譯

而後建議安裝atool-l18n這種翻譯工具,直接翻譯成英文文案。就能夠編譯運行了~固然後續還得有一些css的調整工做。 cnpm i atool-l10n

node_modules/.bin/atool-l10n

總結

本文主要是分享了一個文案提取的腳本,來讓前端jsx項目快速國際化。若有使用上的問題,歡迎在評論區詢問~

tip

多謝評論區lany9527同窗的建議,腳本已經更新。再也不以自增加的數字做爲key值了。換成以中文名做爲key進行提取,已經更新腳本~

附錄:

1.目前腳本不支持中文中有換行的狀況,因此得修正下scan以後的三個文件的內容。而且這部份內容得手動去替換。不過這種狀況不多,個人項目掃出2000個詞條只有兩條有這個問題。

2.第二種是pick操做執行以後可能會編譯出錯,那是由於你的項目中可能手寫了\n這樣的文案,得手動處理下這種狀況。

3.第三種是不支持中文中含有\"的狀況,這部分也得本身處理,緣由是我以中文做爲key,爲了提取後的值過eslint,得用單引號引發來。就得對雙引號單引號進行轉義。沒法處理已經轉義過的內容。在完成了文案的轉化以後能夠再用scan命令掃描一遍,看下哪些沒有處理好的,再手動處理下~

感興趣的同窗能夠關注專欄或者發送簡歷至 'yifei.pyf####alibaba-inc.com'.replace('####', '@'),歡迎有志之士加入~

原文地址:github.com/ProtoTeam/b…

相關文章
相關標籤/搜索