結合webpack 一步一步實現懶加載的國際化簡易版方案

 想法來源於工做需求,最後倒騰出一個國際化工做流,指望是這樣的:vue

1. 自動化處理國際化文案(表現爲轉義翻譯人員給到的文件處理成技術人員所識別的文件)node

2. 轉化後的國際化文件可以按需加載,實現懶加載的功能webpack

綜上,實現以上需求所涉及知識點:nodejs, webpackweb

本文只記錄文件實現懶加載功能,至於國家化文案轉換若是須要的告知。那麼,就開始啦。
先上實際效果圖:框架



以上即是最終效果,有興趣的能夠繼續往下看this

Q: 首先有這樣一個HTML文本,思考如何講要替換的文字進行國際化?spa

<section>
  <div class="icon-bg"></div>
  <div id="create" class="lx-button lx-button-black">Create wallet</div>
  <div id="import" class="lx-button">Import wallet</div>
  <button id="cn">zh-cn</button>
  <button id="hant">zh-hant</button>
  <br>
</section>

...: 經過觀察了vue 和angular的國際化方案,最後決定在元素上增長一個標識,用來識別該元素須要作國際化,思路就是經過document.querySelectorAll()選擇全部具備i18n類的元素翻譯

A: 效果以下
3d

 

 有了標識符後,怎麼才能替換文字?思路是這樣的:code

如何替換文字? -> 替換什麼語言的文字 ? -> 替換的內容具體是什麼?

一路逆推過去: 
1. 替換的內容具體是什麼?

替換的內容考慮到懶加載,因此通常對於相同的字段的文案都會按照不一樣國家分開來(此處,參考平時用的angular 和vue框架)
因此,中文文案和繁體文案分紅了兩個文件夾存放,存放以下:


(PS: 我的習慣會把文案相關文件放入叫作i18n的文件夾中)

此時,便解決了替換的內容具體是什麼 。

2. 替換什麼語言的文字?

語言確定是在頁面加載的時候獲取的,並且是不固定的,因此在初始化國際化的時候確定是須要明確指定的,而且,爲了方便檢索,一般國際化文件夾裏面會根據不一樣語言的標識碼進行劃分,可是有些國家比較特別公用一種文字,好比新加坡的和香港的和臺灣的就都是繁體,因此咱們確定不會sasa的去創建三個繁體的國際化文案的,因此,這裏須要統一入口作這種需求處理;
3. 如何替換文字?
反推到最後一步,很顯然,獲取了須要國際化的元素以後,根據指定的替換的語言去獲取相應的資源文件,而後並把資源文件中的字段替換掉頁面上的文案
具體代碼以下:

export class TinaI18n {
  constructor (obj){
    this.currentLang = obj['currentLang'];
    this.useFileName = obj['useFileName'];
  }

  // 設置當前國際化語言
  setLang(){
    if(/^zh/i.test(this.currentLang)){
      if(/^zh[-—](cn|SG)/gi.test(this.currentLang)){
        this.currentLang = 'zh-cn';
      }else {
        this.currentLang = 'zh-hant';
      }
    }else {
      this.currentLang = this.currentLang.slice(0,2).toLowerCase();
    }
  }

  // 獲取當前國際化語言翻譯文案
  static getI18nFile(fileUrl){
    return import(/* webpackIgnore: true */ fileUrl).then(({default: ctx}) => {
      return ctx;
    })
  }

  // 變換國際化
  setInnerHtml(lang){
    lang && (this.currentLang = lang);
    let ele = document.querySelectorAll('.i18n');
    if (!(ele.length > 0)) {
      return new Error('請檢查class是否有添加i18n');
    }
    this.setLang();
 
    TinaI18n.getI18nFile(`${window.location.href}i18n/${this.currentLang}/${this.useFileName}.js`).then(ctx => {for (let i = 0; i < ele.length; i++) {
        if (this.currentLang && ctx) {
          if (!ele[i].getAttribute('placeholder')) {
            ele[i].innerText = ctx[ele[i].getAttribute('data-i18n')];
          }
        } else {
          if (!(ctx)) {
            console.error('獲取文案失敗: 路徑指定錯誤? 文件不存在?');
            return
          }
        }
      }
    }).catch(err => {
      console.log('err', err);
    });
  }

}

如何使用?

import {TinaI18n} from "./i18n/TinaI18n";

window.onload = function () {
  // 實例化國際化
  const tinaI18n = initI18N('zh-hant', 'add');

  // 簡體中文
  document.querySelector('#cn').addEventListener('click', ()=>{
    tinaI18n.setInnerHtml('zh-cn');
  });

  // 繁體中文
  document.querySelector('#hant').addEventListener('click', ()=>{
    tinaI18n.setInnerHtml('zh-hant');
  })
};

// 初始化國際化
function initI18N(currentlang, currentFile) {
  const tinaI18n =  new TinaI18n({
    currentLang: currentlang,
    useFileName: currentFile
  });
  tinaI18n.setInnerHtml();
  return tinaI18n;
}

 

這裏建立了一個專門作國際化的類,經過實例化這個類,傳入語言代碼(一種語言標識)和文件名稱,調用setInnerHtml(),對頁面上的元素進行替換,注意,這個功能只能替換標籤裏的文案,像placehoder要新寫一個方法,像變量也是要寫一個方法

下一篇更新勇於動態加載webpack的配置

相關文章
相關標籤/搜索