想法來源於工做需求,最後倒騰出一個國際化工做流,指望是這樣的: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的配置