成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

前端通用國(guó)際化解決方案

lingdududu / 1164人閱讀

摘要:前端通用國(guó)際化解決方案背景前端技術(shù)日新月異,技術(shù)棧繁多。接下來(lái)針對(duì)這幾塊內(nèi)容并結(jié)合日常的開發(fā)流程說(shuō)明國(guó)際化的通用解決方案。

文章首發(fā)于個(gè)人blog,歡迎大家關(guān)注。

DI18n

前端通用國(guó)際化解決方案

背景

前端技術(shù)日新月異,技術(shù)棧繁多。以前端框架來(lái)說(shuō)有React, Vue, Angular等等,再配以webpack, gulp, Browserify, fis等等構(gòu)建工具去滿足日常的開發(fā)工作。同時(shí)在日常的工作當(dāng)中,不同的項(xiàng)目使用的技術(shù)棧也會(huì)不一樣。當(dāng)需要對(duì)部分項(xiàng)目進(jìn)行國(guó)際化改造時(shí),由于技術(shù)棧的差異,這時(shí)你需要去尋找和當(dāng)前項(xiàng)目使用的技術(shù)棧相匹配的國(guó)際化的插件工具。比如:

vue + vue-i18n

angular + angular-translate

react + react-intl

jquery + jquery.i18n.property

等等,同時(shí)可能有些頁(yè)面沒有使用框架,或者完全是沒有進(jìn)行工程化的靜態(tài)前端頁(yè)面。

為了減少由于不同技術(shù)棧所帶來(lái)的學(xué)習(xí)相關(guān)國(guó)際化插件的成本及開發(fā)過(guò)程中可能遇到的國(guó)際化坑,在嘗試著分析前端國(guó)際化所面臨的主要問(wèn)題及相關(guān)的解決方案后,我覺得是可以使用更加通用的技術(shù)方案去完成國(guó)際化的工作。

國(guó)際化所面臨的問(wèn)題

1.語(yǔ)言翻譯

靜態(tài)文案翻譯(前端靜態(tài)模板文案)

動(dòng)態(tài)文案翻譯(server端下發(fā)的動(dòng)態(tài)數(shù)據(jù))

2.樣式

不同語(yǔ)言文案長(zhǎng)度不一樣造成的樣式錯(cuò)亂

圖片的替換

3.map表維護(hù)

4.第三方服務(wù)

SDK

5.本地化

貨幣單位

貨幣匯率

時(shí)間格式

6.打包方案

運(yùn)行時(shí)

編譯后

解決方案

在日常的開發(fā)過(guò)程當(dāng)中,遇到的最多的需要國(guó)際化的場(chǎng)景是:語(yǔ)言翻譯,樣式,map表維護(hù)打包方案。接下來(lái)針對(duì)這幾塊內(nèi)容并結(jié)合日常的開發(fā)流程說(shuō)明國(guó)際化的通用解決方案。

首先來(lái)看下當(dāng)前開發(fā)環(huán)境可能用的技術(shù)棧:

1.使用了構(gòu)建工具

webpack

gulp

fis

browserify

...

基于這些構(gòu)建工具,使用:

Vue

Angular

React

Backbone

...

未使用任何framework

2.未使用構(gòu)建工具

使用了jqueryzepto等類庫(kù)

原生js

其中在第一種開發(fā)流程當(dāng)中,可用的國(guó)際化的工具可選方案較多:

從框架層面來(lái)看,各大框架都會(huì)有相對(duì)應(yīng)的國(guó)際化插件,例如:vue-i18n, angular-translate, react-intl等,這些插件可以無(wú)縫接入當(dāng)前的開發(fā)環(huán)節(jié)當(dāng)中。優(yōu)點(diǎn)是這些框架層面的國(guó)際化插件使用靈活,可以進(jìn)行靜態(tài)文案的翻譯,動(dòng)態(tài)文案的翻譯。缺點(diǎn)就是開發(fā)過(guò)程中使用不同的框架還需要去學(xué)習(xí)相對(duì)應(yīng)的插件,存在一定的學(xué)習(xí)成本,同時(shí)在業(yè)務(wù)代碼中可能存在不同語(yǔ)言包判斷邏輯。

從構(gòu)建工具層面來(lái)看, webpack有相對(duì)應(yīng)的i18n-webpack-plugin, gulpgulp-static-i18n等相應(yīng)的插件。這些插件的套路一般都是在你自定義map語(yǔ)言映射表,同時(shí)根據(jù)插件定義好的需要被編譯的代碼格式,然后在代碼的編譯階段,通過(guò)字符串匹配的形式去完成靜態(tài)文案的替換工作。這些插件僅僅解決了靜態(tài)文案的問(wèn)題,比如一些樣式,圖片替換,class屬性,以及動(dòng)態(tài)文案的翻譯等工作并沒有做。
事實(shí)上,這些插件在編譯過(guò)程中對(duì)于樣式,圖片替換, class屬性等替換工作是非常容易完成的,而動(dòng)態(tài)文案的翻譯因?yàn)槿鄙?b>context,所以不會(huì)選擇使用這些編譯插件去完成動(dòng)態(tài)文案的翻譯工作。相反,將動(dòng)態(tài)文案的翻譯放到運(yùn)行時(shí)去完成應(yīng)該是更加靠譜的。

但是換個(gè)角度,拋開基于這些構(gòu)建工具進(jìn)行開發(fā)的框架來(lái)說(shuō),構(gòu)建工具層面的國(guó)際化插件可以很好的抹平使用不同框架的差異,通過(guò)將國(guó)際化的過(guò)程從運(yùn)行時(shí)轉(zhuǎn)到編譯時(shí),在編譯的過(guò)程中就完成大部分的國(guó)際化任務(wù),降低學(xué)習(xí)相對(duì)應(yīng)國(guó)際化插件的成本,同時(shí)在構(gòu)建打包環(huán)節(jié)可實(shí)現(xiàn)定制化。不過(guò)也存在一定的缺點(diǎn),就是這些構(gòu)建工具層面的國(guó)際化插件只能完成一些基本的靜態(tài)文案的翻譯,因?yàn)槿鄙?b>context,并不能很好的去完成動(dòng)態(tài)文案的翻譯工作,它比較適用于一些純靜態(tài),偏展示性的網(wǎng)頁(yè)。

在第二種開發(fā)流程當(dāng)中,可使用的國(guó)際化工具較少,大多都會(huì)搭配jquery這些類庫(kù)及相對(duì)應(yīng)的jquery.i18ni18next等插件去完成國(guó)際化。

綜合不同的構(gòu)建工具,開發(fā)框架及類庫(kù),針對(duì)不同的開發(fā)環(huán)境似乎是可以找到一個(gè)比較通用的國(guó)際化的方案的。

這個(gè)方案的大致思路就是:通過(guò)構(gòu)建工具去完成樣式, 圖片替換, class屬性等的替換工作,在業(yè)務(wù)代碼中不會(huì)出現(xiàn)過(guò)多的因國(guó)際化而多出的變量名,同時(shí)使用一個(gè)通用的翻譯函數(shù)去完成靜態(tài)文案動(dòng)態(tài)文案的翻譯工作,而不用使用不同框架提供的相應(yīng)的國(guó)際化插件。簡(jiǎn)單點(diǎn)來(lái)說(shuō)就是:

依據(jù)你使用的構(gòu)建工具 + 一個(gè)通用的翻譯函數(shù)去完成前端國(guó)際化

首先,這個(gè)通用的語(yǔ)言翻譯函數(shù): di18n-translate。它所提供的功能就是靜態(tài)和動(dòng)態(tài)文案的翻譯, 不依賴開發(fā)框架及構(gòu)建工具。

  npm install di18n-translate
// 模塊化寫法
  const LOCALE = "en"
  const DI18n = require("di18n-translate")
  const di18n = new DI18n({
    locale: LOCALE,     // 語(yǔ)言環(huán)境 
    isReplace: false,   // 是否開始運(yùn)行時(shí)(適用于沒有使用任何構(gòu)建工具開發(fā)流程) 
    messages: {         // 語(yǔ)言映射表 
      en: {
        你好: "Hello, {person}"
      },
      zh: {
        你好: "你好, {person}"
      }
    }
  })

  di18n繼承于一個(gè)翻譯類,提供了2個(gè)方法`$t`, `$html`:
 
  di18n.$t("你好", {person: "xl"})   // 輸出: Hello, xl
  di18n.$html(htmlTemp)   // 傳入字符串拼接的dom, 返回匹配后的字符串,具體示例可見下文

// 外鏈形式
  
  

這個(gè)時(shí)候你只需要將這個(gè)通用的翻譯函數(shù)以適當(dāng)?shù)姆绞郊傻侥愕拈_發(fā)框架當(dāng)中去。

接下來(lái)會(huì)結(jié)合具體的不同場(chǎng)景去說(shuō)明下相應(yīng)的解決方案:

使用MVVM類的framework

使用了MVVM類的framework時(shí),可以借助framework幫你完成view層的渲染工作, 那么你可以在代碼當(dāng)中輕松的通過(guò)代碼去控制class的內(nèi)容, 以及不同語(yǔ)言環(huán)境下的圖片替換工作.

例如vue, 示例(1):

main.js文件:

window.LOCALE = "en"
app.vue文件:
  

  

這個(gè)時(shí)候你再加入翻譯函數(shù),就可以滿足大部分的國(guó)際化的場(chǎng)景了,現(xiàn)在在main.js中添加對(duì)翻譯函數(shù)di18n-translate的引用:

main.js文件:

import Vue from "vue"

window.LOCALE = "en"
const DI18n = require("di18n-translate")
const di18n = new DI18n({
    locale: LOCALE,       // 語(yǔ)言環(huán)境
    isReplace: false,   // 是否進(jìn)行替換(適用于沒有使用任何構(gòu)建工具開發(fā)流程)
    messages: {         // 語(yǔ)言映射表
      en: {
        你好: "Hello, {person}"
      },
      zh: {
        你好: "你好, {person}"
      }
    }
  })

Vue.prototype.d18n = di18n

翻譯函數(shù)的基本使用, 當(dāng)然你還可以使用其他的方式集成到你的開發(fā)環(huán)境當(dāng)中去:

app.vue文件:
  

  

使用mvvm framework進(jìn)行國(guó)際化,上述方式應(yīng)該是較為合適的,主要是借助了framework幫你完成view層的渲染工作, 然后再引入一個(gè)翻譯函數(shù)去完成一些動(dòng)態(tài)文案的翻譯工作

這種國(guó)際化的方式算是運(yùn)行時(shí)處理,不管是開發(fā)還是最終上線都只需要一份代碼。

當(dāng)然在使用mvvm framework的情況下也是可以不借助framework幫我們完成的view層的這部分的功能,而通過(guò)構(gòu)建工具去完成, 這部分的套路可以參見下午的示例3

未使用mvvm框架,使用了構(gòu)建工具(如webpack/gulp/browserify/fis) 使用了前端模板

國(guó)際化的方式和上面說(shuō)的使用mvvm框架的方式一致,因?yàn)橛心0逡鎺湍阃瓿闪?b>view層的渲染.所以對(duì)于樣式圖片,class屬性的處理可以和上述方式一致, 動(dòng)態(tài)文案的翻譯需引入翻譯函數(shù)。

這種國(guó)際化的方式也算是運(yùn)行時(shí)處理,開發(fā)和最終上線都只需要一份代碼。

沒有使用前端模板

因?yàn)闆]用使用前端模板,便少了對(duì)于view層的處理。這個(gè)時(shí)候你的DOM結(jié)構(gòu)可能是在html文件中一開始就定義好的了,也可能是借助于webpack這樣能允許你使用模塊化進(jìn)行開發(fā),通過(guò)js動(dòng)態(tài)插入DOM的方式。

接下來(lái)我們先說(shuō)說(shuō)沒有借助webpack這樣允許你進(jìn)行模塊化開發(fā)的構(gòu)建工具,DOM結(jié)構(gòu)直接是在html文件中寫死的項(xiàng)目。這種情況下你失去了對(duì)view層渲染能力。那么這種情況下有2種方式去處理這種情況。

第一種方式就是可以在你自己的代碼中添加運(yùn)行時(shí)的代碼。大致的思路就是在DOM層面添加屬性,這些屬性及你需要翻譯的map表所對(duì)應(yīng)的key值:

示例(2):

html文件:

  

運(yùn)行時(shí):

  
  

最后html會(huì)轉(zhuǎn)化為:

  

Hello

第二種方式就是借助于構(gòu)建工具在代碼編譯的環(huán)節(jié)就完成國(guó)際化的工作,以webpack為例:

示例(3):

html文件:

  

$t("你好")

這個(gè)時(shí)候使用了一個(gè)webpackpreloader: locale-path-loader,它的作用就是在編譯編譯前,就通過(guò)webpack完成語(yǔ)言環(huán)境的配置工作,在你的業(yè)務(wù)代碼中不會(huì)出現(xiàn)過(guò)多的關(guān)于語(yǔ)言環(huán)境變量以及很好的解決了運(yùn)行時(shí)作為cssbackground的圖片替換工作, 具體的locale-path-loader的文檔請(qǐng)戳我

使用方法:

  npm install locale-path-loader

webpack 1.x 配置:

  module.exports = {
    ....
    preLoaders: [
      {
        test: /.*$/,
        exclude: /node_modules/,
        loaders: [
          "eslint",
          "locale-path?outputDir=./src/common&locale=en&inline=true"
        ]
      } 
    ]
    ....
  }

webpack 2 配置:

  module.exports = {
    ....
    module: {
      rules: [{
        test: /.*$/,
        enforce: "pre",
        exclude: /node_modules/,
        use: [{
          loader: "locale-path-loader",
          options: {
            locale: "en",
            outputDir: "./src/common",
            inline: true
          }
        }]
      }]
    }
    ....
  }

經(jīng)過(guò)webpackpreloader處理后,被插入到頁(yè)面中的DOM最后成為:

  

Hello

但是使用這種方案需要在最后的打包環(huán)節(jié)做下處理,因?yàn)橥ㄟ^(guò)preloader的處理,頁(yè)面已經(jīng)被翻譯成相對(duì)應(yīng)的語(yǔ)言版本了,所以需要通過(guò)構(gòu)建工具以及改變preloader的參數(shù)去輸出不同的語(yǔ)言版本文件。當(dāng)然構(gòu)建工具不止webpack這一種,不過(guò)這種方式處理的思路是一致的。
這種方式屬于編譯時(shí)處理,開發(fā)時(shí)只需要維護(hù)一份代碼,但是最后輸出的時(shí)候會(huì)輸出不同語(yǔ)言包的代碼。當(dāng)然這個(gè)方案還需要服務(wù)端的支持,根據(jù)不同語(yǔ)言環(huán)境請(qǐng)求,返回相對(duì)應(yīng)的入口文件。關(guān)于這里使用webpack搭配locale-path-loader進(jìn)行分包的內(nèi)容可參見vue-demo:

|--deploy
  |   |
  |   |---en
  |   |    |--app.js
  |   |    |--vendor.js
  |   |    |--index.html
  |   |---zh
  |   |    |--app.js
  |   |    |--vendor.js
  |   |    |--index.html
  |   |---jp
  |   |    |--app.js
  |   |    |--vendor.js
  |   |    |--index.html
  |   |----lang.json

接下來(lái)繼續(xù)說(shuō)下借助構(gòu)建工具進(jìn)行模塊化開發(fā)的項(xiàng)目, 這些項(xiàng)目可能最后頁(yè)面上的DOM都是通過(guò)js去動(dòng)態(tài)插入到頁(yè)面當(dāng)中的。那么,很顯然,可以在DOM被插入到頁(yè)面前即可以完成靜態(tài)文案翻譯,樣式, 圖片替換, class屬性等替換的工作。

示例(4):
html文件:

  

$t("你好")

js文件:

  let tpl = require("html!./index.html")
  let wrapper = document.querySelector(".box-wrapper")
  
  // di18n.$html方法即對(duì)你所加載的html字符串進(jìn)行replace,最后相對(duì)應(yīng)的語(yǔ)言版本
  wrapper.innerHTML = di18n.$html(tpl)

最后插入到的頁(yè)面當(dāng)中的DOM為:

  

Hello

這個(gè)時(shí)候動(dòng)態(tài)翻譯再借助引入的di18n上的$t方法

  di18n.$t("你好")

這種開發(fā)方式也屬于運(yùn)行時(shí)處理,開發(fā)和上線后只需要維護(hù)一份代碼。

沒有使用任何framework構(gòu)建工具的純靜態(tài),偏展示性的網(wǎng)頁(yè)

這類網(wǎng)頁(yè)的國(guó)際化,可以用上面提到的通過(guò)在代碼中注入運(yùn)行時(shí)來(lái)完成基本的國(guó)際化的工作, 具體內(nèi)容可以參見示例(2)以及倉(cāng)庫(kù)中的html-demo文件夾。

語(yǔ)言包map表的維護(hù)

建議將語(yǔ)言包多帶帶新建文件維護(hù),通過(guò)異步加載的方式去獲取語(yǔ)言包.

項(xiàng)目地址(如果覺得文章不錯(cuò),請(qǐng)不要吝嗇你的star~~)

請(qǐng)戳我

最后需要感謝 @kenberkeley 同學(xué),之前和他有過(guò)幾次關(guān)于國(guó)際化的探討,同時(shí)關(guān)于編譯時(shí)這塊的內(nèi)容,他的有篇文章(請(qǐng)戳我)也給了我一些比較好的思路。

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

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

相關(guān)文章

  • 【整理】前端國(guó)際小結(jié)

    摘要:近期在做國(guó)際化的改造,做了相應(yīng)的調(diào)研,簡(jiǎn)單做下項(xiàng)目前端國(guó)際化的小結(jié)國(guó)際化可以分為前端國(guó)際化和后端國(guó)際化,也可以是前后端組合的國(guó)際化后端多為國(guó)際化,這里不做展開,百度一下到處都是常見型常見的前端國(guó)際化方法步驟如下原理定義國(guó)際化配置根據(jù)環(huán)境讀取 近期在做國(guó)際化的改造,做了相應(yīng)的調(diào)研,簡(jiǎn)單做下項(xiàng)目前端國(guó)際化的小結(jié) 國(guó)際化可以分為前端國(guó)際化和后端國(guó)際化,也可以是前后端組合的國(guó)際化后端多為spr...

    android_c 評(píng)論0 收藏0
  • 【整理】前端國(guó)際小結(jié)

    摘要:近期在做國(guó)際化的改造,做了相應(yīng)的調(diào)研,簡(jiǎn)單做下項(xiàng)目前端國(guó)際化的小結(jié)國(guó)際化可以分為前端國(guó)際化和后端國(guó)際化,也可以是前后端組合的國(guó)際化后端多為國(guó)際化,這里不做展開,百度一下到處都是常見型常見的前端國(guó)際化方法步驟如下原理定義國(guó)際化配置根據(jù)環(huán)境讀取 近期在做國(guó)際化的改造,做了相應(yīng)的調(diào)研,簡(jiǎn)單做下項(xiàng)目前端國(guó)際化的小結(jié) 國(guó)際化可以分為前端國(guó)際化和后端國(guó)際化,也可以是前后端組合的國(guó)際化后端多為spr...

    LoftySoul 評(píng)論0 收藏0
  • 阿里云前端周刊 - 第 20 期

    摘要:網(wǎng)頁(yè)可訪問(wèn)性似乎是一項(xiàng)艱巨的任務(wù),但它確實(shí)比聽起來(lái)要容易很多,這十條網(wǎng)頁(yè)可訪問(wèn)性準(zhǔn)則旨在確保所有網(wǎng)站都是通用的。 推薦 1. 阿里電商架構(gòu)演變之路 https://yq.aliyun.com/article... 首屆阿里巴巴中間件技術(shù)峰會(huì)上,阿里巴巴中間件技術(shù)部專家唐三帶來(lái)阿里電商架構(gòu)演變之路的演講,本文從阿里業(yè)務(wù)和技術(shù)架構(gòu)開始引入,分別分享了阿里電商從1.0到4.0架構(gòu)的演變之路,...

    Baaaan 評(píng)論0 收藏0
  • 精讀《前端未來(lái)展望》

    摘要:精讀前端可以從多個(gè)角度理解,比如規(guī)范框架語(yǔ)言社區(qū)場(chǎng)景以及整條研發(fā)鏈路。同是前端未來(lái)展望,不同的文章側(cè)重的格局不同,兩個(gè)標(biāo)題相同的文章內(nèi)容可能大相徑庭。作為使用者,現(xiàn)在和未來(lái)的主流可能都是微軟系,畢竟微軟在操作系統(tǒng)方面人才儲(chǔ)備和經(jīng)驗(yàn)積累很多。 1. 引言 前端展望的文章越來(lái)越不好寫了,隨著前端發(fā)展的深入,需要擁有非常寬廣的視野與格局才能看清前端的未來(lái)。 筆者根據(jù)自身經(jīng)驗(yàn),結(jié)合下面幾篇文章...

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

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

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<