精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

項目復盤:通過動態腳本,實現按需加載語言包

開發 項目管理
我們項目的語言包是維護在在線表格上的,每次會通過腳本拉取數據,然后處理成 JSON 文件。我需要再寫一個腳本來處理這個 JSON 文件,將其分成多個語言包,并生成功 TS 類型文件。

大家好,我是前端西瓜哥,是一名前端開發。

最近做了一個將按需加載語言包的需求,有不少收獲,這里記錄一下。

改造前的項目

原來項目是將所有的語言包合并在一起,放到一個 JSON 文件里然后被引入。

打包后的腳本里,有完整的語言包的代碼,導致打包文件非常大。理論上用戶只會使用一種語言,其他的語言沒有加載的必要。

目前來說項目只支持兩種語言,每個語言有文案 4000 多條。如果還是使用全量加載的話,以后支持的語言每多一個,打包后的文件就要膨脹一圈。

做語言包的拆分還是很有必要的。它可以減少加載資源的大小,減少首次頁面加載時間,提高用戶體驗。

實現方案的選擇

實現按需加載語言包的方式很多,我了解到的有三種:

  1. 后端渲染:在請求時將單個語言包嵌入到 HTML 里。
  2. 動態 import:使用 ES6的 動態 import 語法。
  3. 動態腳本:在腳本里創建一個 script,添加到 DOM 樹上。

后端渲染的方案,其實是最快捷的

// 下面這一個 script 是后端渲染的
<script>window.i18n = { 'apple': '蘋果' /* ... */ }</script>
<script src="app.js"></script>

請求 HTML 時,后端做渲染工作,給 HTML 加上語言包的內容。

前端沒有什么改造的工作量,但問題是不能利用緩存。但這個問題其實也可以解決,就是后端生成好語言包 js 文件,將嵌入語言包內容的方式改為 cdn 引入的方式,可以利用好緩存。

但這讓模板引擎的邏輯變得很重,cdn 上傳到哪里,如何維護也是個問題。

動態 import 方案

import('lang/zh-CN.js').then(() => {
ReactDOM.render();
});

使用 React 等框架打包出來單頁面應用的文件通常很大,下載需要不少時間。

動態 import 必須在腳本整個下載完后,再執行,所以這是一個串行下載的邏輯。

如果可以的話,我們希望語言包可以和業務代碼同時下載。此外,更重要的一點是,在動態 import 前,我們不能調用獲取文案的方法 getText。

我在改造項目代碼時,發現在我動態 import 語言包并 ReactDOM.render() 之前,有些模塊文件調用了getText 方法,因為它們作為枚舉指直接暴露出來,沒有用函數封裝,被 import 時就直接執行了。

語言包都沒加載,你執行 getText 是拿不到文案的,這個方案我果斷放棄。

動態腳本方案

<script>
(function(){
// 語言包 js 文件內容為:window.i18n = { key1: value1 };
const i18nLangCDNs = {
"zh-CN": "/lang/zh-CN.1268ec6019c7a7bb7b27d1ecdadc3948.js",
"en-US": "/lang/en-US.e6c246ecf2b64be936a116706cdd6611.js",
};
let lang = getLang();
const script = document.createElement('script');
script.async = false;
script.src = i18nLangCDNs[lang];
document.querySelector('head').appendChild(script);
});
</script>

這種方案利用了腳本里創建腳本的方式。能在更前面的位置加載語言包腳本。

優點是我們可以不需要做后端渲染的工作,讓選擇語言包的邏輯交給前端。但涉及到前端工程化,需要寫插件改變原來的加載腳本形式。

我們的項目使用了 webpack,如果用這個方案,就需要寫一個 webpack 插件去改造 HtmlWebpackPlugin 的構建流程。

目前來說,方案 1 和 方案 3 都是不錯的。

但考慮到我們公司的前后端是分離的,后端的代碼實現對我來說其實是黑盒,我沒有權限也沒有能力去寫后端代碼。而項目是前端項目,最好還是讓前端來掌控維護。所以我最終選擇了方案 3。

方案1 和方案 2 的更具體介紹,可以看我的這篇文章:前端國際化,該如何實現按需加載語言包?

改造過程

原來項目打包后的 html 文件大致如下。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 業務代碼,語言包也在里面 -->
<script src="app.js"></script>
</body>
</html>

app.js 里有全量語言包的內容。

改造后的 html 文件如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
(function(){
// 語言包 js 文件內容為:window.i18n = { key1: value1 };
const i18nLangCDNs = {
"zh-CN": "/lang/zh-CN.1268ec6019c7a7bb7b27d1ecdadc3948.js",
"en-US": "/lang/en-US.e6c246ecf2b64be936a116706cdd6611.js",
};
let lang = getLang();
const script = document.createElement('script');
script.async = false;
script.src = i18nLangCDNs[lang];
document.querySelector('head').appendChild(script);
});
</script>
</head>
<body>
<!-- 為保持執行順序,業務代碼也需要改為動態加載形式 -->
<script>
<!-- app.js 文件已移除語言包 -->
['app.js'].forEach(function(src) {
const script = document.createElement('script');
script.async = false;
script.src = src;
document.body.appendChild(script);
});
</script>
</body>

我們語言包將 app.js 從中提取出來,并且分為多個語言包放到 js 文件,如 zh-CN.js、en-US.js,在 app.js 之前執行。

let lang = getLang();
const script = document.createElement('script');
script.async = false;
script.src = i18nLangCDNs[lang];
document.querySelector('head').appendChild(script);

我們先確認用戶使用的語言是什么。

如果我們不支持持久化設置,可以通過 navigator.language 或前端的其他地方獲取。

但通常用戶可以設置語言,這個語言標識就要后端給,再請求一次用戶信息可太離譜了,所以這里還是需要后端給我們往 html 里嵌入用戶選擇的語言。然后我們從語言 cdn 列表里選我們需要的語言。

script 元素默認會將 async 設置為 true,效果是腳本下載完立即執行。需要將其改為 false,保證多個動態腳本順序執行。

文件名使用了哈希,是為了解決瀏覽器緩存問題。

執行后,就會將語言包文案暴露在全局變量中。

業務代碼 app.js 也得改成動態加載形式,如果原來的非動態寫法,執行時機就會早于語言包腳本。

這里涉及到了 script 的執行時機,具體規則可以看我的這篇文章:script 的三種加載模式:默認加載、defer、async。

原來的寫法
<script src="app.js"></script>

改造后
<script>
<!-- app.js 文件已移除語言包 -->
['app.js'].forEach(function(src) {
const script = document.createElement('script');
script.async = false;
script.src = src;
document.body.appendChild(script);
});
</script>

這樣我們就能保證先執行語言包腳本,再執行 app.js。

app.js 中的業務代碼執行時,使用 getText 方法就能正常通過 key 獲取到對應的文案。

這里 app.js 改為動態的寫法后,需要腳本解析執行后才下載腳本,可以考慮加個 link preload 提前下載腳本。

link 的 preload 作用可以看我的這篇文章。

期間遇到的問題

思路并不復雜,但改造過程中做了很多工作,遇到了不少問題。這里簡單列舉一下,不展開講了,到時候會考慮另寫文章討論。

  • 我們項目的語言包是維護在在線表格上的,每次會通過腳本拉取數據,然后處理成 JSON 文件。我需要再寫一個腳本來處理這個 JSON 文件,將其分成多個語言包,并生成功 TS 類型文件。
  • 使用了 monorepo,我專門分了一個 i18n 的包。
  • 最難的是開發一個 Webpack 插件,需要做到拷貝特定文件夾下的語言包,加上內容哈希,放到構建目錄下。這些帶有哈希的名字要保存下來,通過 HtmlWebpack的鉤子轉換為內嵌 script 形式添加到 html 上。此外,還要將原來的打包文件 app.js 轉換為動態加載的形式。
  • 開發環境還是要全量加載語言包,方便測試。一個原因是 devServer 無法讀取到使用 copy 的文件,需要額外用 write-file-webpack-plugin,但項目用的 create-react-app 不太好改造。
  • 改造 getText 獲取文案的方法,需要考慮開發和生產環境的不同。
  • 我們還有個中間層的 nextjs 項目,我們的語言包要兼容該項目,所以里面還寫了判斷環境的邏輯,在 global 或 window 上掛載全局變量。
  • 測試用例和 CI 補上一行引入語言包的邏輯。
責任編輯:姜華 來源: 今日頭條
相關推薦

2013-08-20 18:39:34

JavaScript模requireJS

2021-09-21 09:59:05

Windows 11Windows微軟

2010-12-29 14:00:43

SharePoint 語言包

2009-08-21 18:46:30

下載Server 20

2010-03-25 16:31:55

Python代碼

2023-02-27 07:40:00

系統重構前端

2023-10-20 08:04:34

系統重構實踐

2010-02-04 17:13:23

Ubuntu安裝

2022-05-17 15:45:41

禮物驚喜送達線上送禮

2009-07-29 09:05:45

Windows 7 R語言包下載本地化包

2011-03-16 13:47:44

IE9

2012-05-28 09:08:23

Windows 8

2025-03-05 02:10:00

2018-08-16 11:18:34

Windows 10語言包刪除

2009-06-14 21:54:37

動態語言Java腳本API

2024-08-09 08:46:00

Springjar 包YAML

2012-08-07 10:05:57

Windows 8安裝指南

2020-06-19 12:59:33

動態腳本Java

2021-05-26 10:40:28

Vue3TypeScript前端

2009-05-28 09:40:06

微軟Windows 7操作系統
點贊
收藏

51CTO技術棧公眾號

欧美午夜黄色| 日本熟妇一区二区| 高清精品久久| 一区二区三区精品在线| 国产自产精品| 中国a一片一级一片| 91精品国产91久久综合| 精品国产免费一区二区三区四区 | 一区二区在线观看不卡| 国产日本一区二区三区| 免费在线不卡av| 欧美在线资源| 国产一区二区三区在线观看网站| 欧美体内she精高潮| 久久影院午夜精品| 亚洲欧美自拍偷拍色图| 欧美精品一区三区在线观看| 99热精品在线播放| 老司机精品视频网站| 日韩亚洲国产中文字幕| 久久久久久久无码| 先锋影音网一区二区| 精品毛片三在线观看| 综合色婷婷一区二区亚洲欧美国产| 好男人www在线视频| 麻豆91在线播放免费| 亚洲专区一区| 欧美日韩一区二区在线播放| 亚洲砖区区免费| 五月婷婷在线观看视频| 国产美女一区二区三区| 国产精品极品美女在线观看免费| 国产亚洲精品女人久久久久久| 欧美呦呦网站| 亚洲精品国产综合久久| 91人妻一区二区三区| 国产精品久久久久77777丨| 亚洲自拍偷拍麻豆| 青青草原国产免费| 在线观看麻豆| 久久精品视频在线看| 精品久久久久久综合日本| 精品久久久久久亚洲综合网站 | 国产又大又黄又粗又爽| 日韩激情电影免费看| 一区二区三区.www| 玖玖精品在线视频| 国产精品剧情| 国产精品国产三级国产普通话蜜臀 | 日日夜夜一区| 在线精品视频免费观看| 日韩欧美精品在线观看视频| 黄色aa久久| 亚洲成人激情av| 97碰在线视频| 欧美aaaaaaa| 一区二区在线观看视频| 成人短视频在线观看免费| 黄av在线播放| 亚洲精品乱码久久久久久日本蜜臀| 宅男一区二区三区| 日本中文字幕电影在线免费观看| 国产精品无码永久免费888| 水蜜桃亚洲一二三四在线| 91社区在线观看播放| 国产婷婷色一区二区三区四区| 日韩av在线电影观看| 91福利在线视频| 亚洲欧洲一区二区在线播放| 中文字幕在线亚洲精品 | 久久免费视频观看| 日韩久久久久久久久| 亚洲永久免费| 国产精品久久久精品| 在线视频1卡二卡三卡| 麻豆91精品视频| 91亚洲va在线va天堂va国| av免费观看在线| 国产精品小仙女| 国产精品亚洲综合| 欧美女优在线| 国产精品成人免费| 精品人妻人人做人人爽| 免费v片在线观看| 91福利在线免费观看| 青青在线视频免费| 国产乱码精品一区二区三区亚洲人 | 视频一区日韩| 亚洲国产欧美自拍| 一级特黄曰皮片视频| 亚洲欧洲中文字幕| 97高清免费视频| 中文有码在线播放| 国产成a人亚洲精品| 美女被啪啪一区二区| 日本免费在线观看| 亚洲综合av网| 欧美日韩在线观看不卡| 一区二区在线视频观看| 亚洲视频axxx| 欧美日韩免费做爰视频| 久久国产主播| 999热视频| 国产资源在线播放| 亚洲最快最全在线视频| 欧美伦理片在线看| caoporn成人免费视频在线| 在线观看日韩专区| 国产一级片免费观看| 视频一区二区中文字幕| αv一区二区三区| 成人18在线| 亚洲国产一区在线观看| 在线观看高清免费视频| 欧美精品中文字幕亚洲专区| 日韩中文字幕在线视频| 久久精品一二区| 国产成人综合在线播放| 无码免费一区二区三区免费播放| caoprom在线| 欧美一区午夜精品| 色欲AV无码精品一区二区久久 | 国语一区二区三区| 久久精品精品电影网| 97人妻一区二区精品视频| 成人免费视频一区| 中国老女人av| 视频欧美精品| 国产一区二区三区在线看| 精品91久久久| 国产91精品久久久久久久网曝门| 自拍偷拍视频在线| 成人涩涩视频| 亚洲天堂免费观看| 精品美女久久久久| 成人网男人的天堂| avove在线观看| 欧美成人xxxx| 中文字幕亚洲欧美一区二区三区| 亚洲免费在线视频观看| 99久久精品情趣| www.射射射| gogo久久日韩裸体艺术| 欧美黑人xxxx| а√中文在线资源库| 亚洲美女淫视频| 日韩av福利在线观看| 久久裸体网站| 成人黄色av播放免费| 日韩大片在线永久免费观看网站| 欧美色精品在线视频| 国产精品免费无码| 日韩黄色一级片| 日韩欧美精品一区二区| 精品免费av在线| 中文字幕日韩欧美在线| 中文字幕 亚洲视频| 国产精品欧美综合在线| www.日本一区| 91精品综合久久久久久久久久久 | 中文字幕日韩综合av| 国产美女www| 国产精品视频一二| 日韩欧美理论片| 国精品一区二区| 国产欧美日韩综合一区在线观看 | 亚洲永久免费av| 精品国产乱码久久久久夜深人妻| 极品裸体白嫩激情啪啪国产精品| 国产九色91| xxx欧美xxx| 在线成人激情黄色| 国产精品无码白浆高潮| 亚洲精品中文字幕乱码三区| zjzjzjzjzj亚洲女人| 日韩一区二区免费看| 日韩精品欧美专区| 自拍偷拍欧美日韩| 久久久久久尹人网香蕉| 国产系列在线观看| 在线播放中文一区| 国产网址在线观看| 国产喂奶挤奶一区二区三区| 夜夜夜夜夜夜操| jizz大全欧美jizzcom| 天天做综合网| 国产精品国色综合久久| 天堂av在线网| 精品国产一区久久久| 秋霞网一区二区| 色婷婷亚洲综合| 一区二区视频免费看| av成人老司机| www.超碰97.com| 亚洲高清不卡| 西游记1978| 国产乱人伦丫前精品视频| 国产999精品久久久| 97超碰在线公开在线看免费| 日韩激情在线视频| 91影院在线播放| 欧美日韩一区二区在线播放| 熟女av一区二区| 91首页免费视频| 国产探花在线观看视频| 久久av最新网址| 日韩精品手机在线观看| 精品免费一区二区| 国产精品国产精品国产专区蜜臀ah | 欧美电影在线观看完整版| 国产精品第二页| aa级大片免费在线观看| www.久久撸.com| 韩日在线视频| 91色在线看| 欧美mv日韩mv| 在线免费看av的网站| 午夜av一区二区三区| 顶臀精品视频www| 国产精品视频yy9299一区| 黄色录像a级片| 国产成人在线视频网站| 日韩精品视频一二三| 久久aⅴ国产紧身牛仔裤| 18禁裸男晨勃露j毛免费观看| 久久国产亚洲| 欧美一区二区视频17c| 久久中文字幕导航| 91手机在线观看| 午夜不卡一区| 国产精品久久久久久久久久久久久久| 182在线视频观看| 欧美第一页在线| 黄色网在线播放| 中文字幕免费精品一区高清| 天堂av网在线| 亚洲精品99久久久久| 亚洲福利在线观看视频| 91精品国产综合久久香蕉的特点| 日本三级一区二区三区| 色999日韩国产欧美一区二区| 国产a∨精品一区二区三区仙踪林| 亚洲激情图片qvod| √天堂中文官网8在线| 国产精品麻豆欧美日韩ww| 国产三级短视频| 国产精品色一区二区三区| 国产亚洲精品熟女国产成人| 国产亚洲成av人在线观看导航| 中文精品在线观看| 久久嫩草精品久久久精品一| av在线网站观看| 久久久久久电影| 极品人妻videosss人妻| 欧美激情一区三区| 农村老熟妇乱子伦视频| 亚洲欧洲国产日韩| 免费中文字幕日韩| 亚洲精品国产a久久久久久| 日本a级片视频| 亚洲丶国产丶欧美一区二区三区| 日本少妇裸体做爰| 日韩欧美国产中文字幕| 自拍偷拍精品视频| 欧美另类变人与禽xxxxx| 国产高清视频免费| 精品av久久707| 亚洲欧美日韩精品永久在线| 亚洲人a成www在线影院| 91精品国产综合久久久久久豆腐| 色偷偷av一区二区三区乱| 黄色网在线免费观看| 久久久久久久久久久久av| 国产精选在线| 国产精品爱久久久久久久| 成人精品视频在线观看| 成人av网站观看| 西野翔中文久久精品国产| 亚洲国产日韩美| 一区二区中文字| 国产精品333| 免费成人av资源网| 国模大尺度视频| 久久综合给合久久狠狠狠97色69| 在线观看免费黄色网址| 亚洲精品欧美专区| 九九精品免费视频| 欧美日韩日日骚| 日韩一级片免费| 亚洲一级片在线看| 天堂8中文在线| 欧美做受高潮电影o| 视频91a欧美| 久久香蕉综合色| 围产精品久久久久久久| 日韩激情免费视频| 精品综合久久久久久8888| 制服丝袜第一页在线观看| 中文字幕乱码久久午夜不卡| 一级黄色录像视频| 色噜噜狠狠成人中文综合| av免费观看网址| 亚洲视频在线观看网站| 欧美大片黄色| 国产精品一香蕉国产线看观看| 国产女人18毛片水真多18精品| 亚洲高清乱码| 99国产精品久久久久久久成人热| av中文字幕网址| 久久久青草青青国产亚洲免观| 欧美成人aaa片一区国产精品| 欧美在线色视频| 视频二区在线观看| 久久婷婷国产麻豆91天堂| 波多野结衣亚洲| 国产精品一区免费观看| 午夜久久免费观看| 国产欧美精品日韩| 亚洲专区在线播放| 日韩一区二区在线观看| 国产二区在线播放| 91精品国产高清自在线| 亚洲电影一区| 日本福利视频导航| 青青草精品视频| 色婷婷av777| 午夜av电影一区| 国产黄色免费大片| 久久久成人精品视频| 99蜜月精品久久91| 日产精品久久久一区二区| 亚洲精品婷婷| 国产精品嫩草69影院| 亚洲图片激情小说| 看黄色一级大片| 亚洲欧洲一区二区三区在线观看| 1区2区在线| 国产一区国产精品| 伊人精品成人久久综合软件| 久久精品亚洲天堂| 亚洲视频你懂的| 国产精品女同一区二区| 日韩中文理论片| 久久精品资源| 手机成人在线| 美女爽到高潮91| 999久久久国产| 欧美精品v国产精品v日韩精品 | 久久99成人| 最新国产精品久久| 激情综合网天天干| 国产午夜手机精彩视频| 日韩一区二区在线观看| 尤物视频在线看| 不卡一卡2卡3卡4卡精品在| 国产精品99免费看| 插我舔内射18免费视频| 精品久久久久久久久国产字幕| 天堂在线中文网| 热久久美女精品天天吊色| 视频国产一区| 日韩精品你懂的| 亚洲欧洲综合另类| 亚洲av无码国产精品永久一区| 欧美激情aaaa| 日本在线中文字幕一区| 波多野结衣作品集| 国产精品亲子伦对白| 国产精品一区二区黑人巨大 | 日本最新一区二区三区视频观看| 日本vs亚洲vs韩国一区三区二区| 亚洲色图日韩精品| 日韩天堂在线观看| 九色porny自拍视频在线播放| 欧美日韩精品免费观看| 老司机免费视频一区二区三区| 午夜爽爽爽男女免费观看| 精品粉嫩超白一线天av| 26uuu亚洲电影| 一区二区不卡在线| 粉嫩嫩av羞羞动漫久久久 | 国产精品一卡二卡三卡| 国产精品一区在线播放| 久久综合网络一区二区| 91免费公开视频| 亚洲精品电影在线| 精品久久福利| 日韩av高清在线看片| 国产精品天美传媒| 蜜桃av中文字幕| 国产精品美女久久久免费| 欧美在线不卡| 好吊视频在线观看| 欧美mv日韩mv| 欧美极品免费| 毛片av在线播放| 国产日韩精品一区二区浪潮av| 性猛交xxxx乱大交孕妇印度| 国产成人久久久精品一区| 女人香蕉久久**毛片精品|