一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

在生產(chǎn)環(huán)境配置ES2015+代碼 | Fundebug博客

 Fundebug 2018-08-03

摘要 :支持瀏覽器兼容ES2015+,提高用戶體驗

為了保證可讀性,本文采用意譯而非直譯。另外,本文版權(quán)歸原作者所有,翻譯僅用于學(xué)習。

大多數(shù)web開發(fā)者使用JavaScript時喜歡使用最新的語言特性,比如:async、await、classes、箭頭函數(shù)等。可是,盡管實際上現(xiàn)在所有最新版瀏覽器都能運行ES2015+代碼并且支持我提到的這些特性,但開發(fā)者仍然使用polyfills將代碼編譯成ES5語法并打包,以便那些還在使用低版本瀏覽器的用戶能夠正常使用。

這點是很糟糕的。在理想情況下,我們無需傳送不必要的代碼。

用最新的JavaScript和DOM APIs,我們可以根據(jù)需求加載ployfills,因為我們可以在運行時使用特性檢測它們的支持是否支持這些語法。但是隨著一些新的JavaScript語法出現(xiàn),,因為任何未知的語法都會導(dǎo)致解析錯誤,然后導(dǎo)致代碼停止執(zhí)行,所以單憑特性檢測語法支持程度很棘手。

雖然我們目前針對新語法檢測沒有一個好的的解決方案,但現(xiàn)在有一種方式可以檢測基本的ES2015語法支持。

解決方案是使用<script type="module">。

大多數(shù)開發(fā)者認為<script type="module">也是加載ES模型的一種方式(當然這是正確的),但是<script type="module">也有更直接的功能,加載瀏覽器可處理的、使用ES2015+語法的JavaScript文件。

換句話說,每個支持<script type="module">的瀏覽器也支持ES2015+特性。例如:

  • 支持<script type="module">的瀏覽器也支持async、await
  • 支持<script type="module">的瀏覽器也支持Class類
  • 支持<script type="module">的瀏覽器也支持箭頭函數(shù)
  • 支持<script type="module">的瀏覽器也支持fetch、Promise、Map、Set等

現(xiàn)在唯一需要做的是對于不支持<script type="module">的瀏覽器做一個降級方案。如果你當前是ES5版本的代碼,那么很幸運,你已經(jīng)完成了這個工作?,F(xiàn)在需要做的是生成ES2015+版本的代碼。

接下來闡釋如何實現(xiàn)這項技術(shù),并討論我們應(yīng)該如何編寫ES2015+代碼。

實現(xiàn)方式

如果你已經(jīng)在使用像webpack、rollup等打包JavaScript,你應(yīng)該繼續(xù)保持。

接下來,除了你當前的包,你將生成第二個包,和第一個方式一樣。唯一不同的是你不需要轉(zhuǎn)譯為ES5并且你也不需要引入polyfills插件。

如果你已經(jīng)在用babel-preset-env(你應(yīng)該使用該插件),第二步是非常簡單的。您所要做的就是使用支持<script type="module">的瀏覽器,這樣Babel將忽略不必要的轉(zhuǎn)化的語法。

換句話說,它將輸出ES2015+代碼而不是ES5。

例如,如果你用webpack并且你的主腳本入口點是./path/to/main.js,根據(jù)當前的配置,ES5版本應(yīng)該是這樣(注意:因為使用的是ES5語法,所有我命名為main-legacy

module.exports = {
entry: {
'main-legacy': './path/to/main.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'public'),
},
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
modules: false,
useBuiltIns: true,
targets: {
browsers: [
'> 1%',
'last 2 versions',
'Firefox ESR',
],
},
}],
],
},
},
}],
},
};

如果使用ES2015+版本,你需要按照第二種配置,該配置的使用環(huán)境是支持<script type="module">的瀏覽器。配置如下:

module.exports = {
entry: {
'main': './path/to/main.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'public'),
},
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
modules: false,
useBuiltIns: true,
targets: {
browsers: [
'Chrome >= 60',
'Safari >= 10.1',
'iOS >= 10.3',
'Firefox >= 54',
'Edge >= 15',
],
},
}],
],
},
},
}],
},
};

運行后,這兩種配置會有兩個為生產(chǎn)環(huán)境準備好的JavaScript文件:

  • main.js(支持ES2015+語法)
  • main-legacy.js(支持ES5語法)

下一步是修改你的HTML,使瀏覽器有條件的支持ES2015+模塊。你能用<script type="module"><script nomodule>的混合方式:

<!-- Browsers with ES module support load this file. -->
<script type="module" src="main.js"></script>

<!-- Older browsers load this file (and module-supporting -->
<!-- browsers know *not* to load this file). -->
<script nomodule src="main-legacy.js"></script>

警告:Safari 10 不支持 nomodule屬性, 但是為了解決這一問題,你可以在使用<script nomodule>前,使用內(nèi)聯(lián)JavaScript代碼片段(注意:這個插件已經(jīng)安裝在Safari11版本中了)。

注意
大部分情況下,這個方法“僅僅是能夠?qū)崿F(xiàn)”,在實現(xiàn)方法之前需要注意一些關(guān)于如何加載模塊的細節(jié):

        1. 像模塊加載一樣<script defer>,這意味著在文檔解析之后才能執(zhí)行。如果有些代碼需要在它之前運行,最好的方式是把代碼分開并獨立加載。

        2. 模塊運行總是用strict mode,如果出于某些原因你的代碼不需要使用strict mode,最好分開加載。

        3. 模塊以不同的方式處理全局的varfunction聲明。例如:
在腳本中var foo = 'bar'function foo() {…}等同于讀取window.foo。但是在模塊中就不是這種情況,請確保在你的代碼中不會依賴這種行為。

示例

我創(chuàng)建了webpack-esnext-boilerplate,開發(fā)者也能來切身體驗。

在這個模板中我有意的添加了webpack的最新特性,為了展示這個技術(shù)在實際場景中如何使用。下面包含了打包的最佳實踐:

我從不推薦一些我沒用的技術(shù),更新的這篇博客也是用的這項技術(shù)。如果你想了解更多,可以檢查我的源代碼。

如果你用了除webpack之外的其它打包工具,這個過程或多或少都是一樣。我選擇webpack作為示例,因為它是當前最受歡迎的打包工具,它也是最復(fù)雜的。我想既然該技術(shù)可以與webpack一起使用,那么它也可以用于其它場景。

這樣做真的值得嗎?

在我看來,確實值得!這樣做節(jié)省是很可觀的。例如,以下是博客中實際生成的代碼的兩個版本的總文件大小的比較:

版本 大?。▔嚎s) 大?。▔嚎s+ gzipped)
ES2015 +(main.js) 80K 21k
ES5(main-legacy.js 175K 43K

傳統(tǒng)的ES5版本是ES2015+版本的兩倍多大小。

我們知道文件越大下載時間越長,而且解析和評估的時間也會更長。從我站點的兩個版本比較,舊版本的代碼解析和執(zhí)行的時間花費了將近一倍(這些測試是使用wepagetest.org在MoTo G4上運行的):

版本 解析/評估 時間 (單獨運行) 解析/評估 時間 (平均值)
ES2015+ (main.js) 184ms, 164ms, 166ms 172ms
ES5 (main-legacy.js) 389ms, 351ms, 360ms 367ms

雖然這些絕對文件的大小在解析、評估的時間不是很長,但要知道這只是一個博客,我不會在上面加載很多腳本。但是這個案例放在其他網(wǎng)站,有更多的腳本加載,你將看到使用ES2015+帶來的巨大收益。

如果你還有質(zhì)疑,并認為文件大小和執(zhí)行時間不同主要是由于需要更多的polyfills來支持傳統(tǒng)環(huán)境,這樣的的想法不完全沒有道理。但是,無論好壞,這是當今的網(wǎng)站上普遍方式。

對HTTPArchive數(shù)據(jù)集的快速查詢顯示,Alexa排名網(wǎng)站中有85181個在其生產(chǎn)中包含babel-polyfillcore-jsregenerator-runtime。六個月前,這個數(shù)字是34588!

實際上,轉(zhuǎn)換和引用polyfills正在迅速成為新的常態(tài)。不幸的是,這意味著數(shù)十億用戶通過網(wǎng)絡(luò)將數(shù)萬億不必要的字節(jié)發(fā)送到本來可以不需要代碼傳輸?shù)臑g覽器上。

現(xiàn)在我們開始發(fā)布我們的ES2015

目前這種技術(shù)的主要問題是大多數(shù)模塊作者不發(fā)布ES2015+版本的源碼,他們發(fā)布了轉(zhuǎn)換后的ES5版本。

既然可以部署ES2015+版本,我們就應(yīng)該改變。

我完全明白,這對眼前來說提出了很多挑戰(zhàn)。大多數(shù)生成工具發(fā)布文檔,建議配置所有的模塊都是ES5。這意味著如果模塊作者開始向npm發(fā)布ES2015+源代碼,他們可能會破壞一些用戶的構(gòu)建,并且通常會引起混淆。

問題是大多數(shù)開發(fā)人員使用Babel將其配置在node_modules中,不進行任何轉(zhuǎn)換,但如果使用ES2015+源代碼發(fā)布模塊,則這是一個問題。幸運的是,修復(fù)很容易。只需要在構(gòu)建配置中刪除node_modules。

rules: [
{
test: /\.js$/,
exclude: /node_modules/, // Remove this line
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
}
]

缺點是,如果node_modules除了本地依賴項之外,像Babel這樣的工具必須開始轉(zhuǎn)換依賴關(guān)系,那么構(gòu)建將會變慢。幸運的是,這是一個可以在工具級別上使用持久的本地緩存解決的問題。

無論在ES2015+作為新模塊發(fā)布標準的道路上我們可能面臨什么困境,我們值得為此而奮斗。如果我們作為模塊者,只將代碼的ES5版本發(fā)布到npm,那么我們會強制用戶使用臃腫且緩慢的代碼。

通過發(fā)布ES2015,我們?yōu)殚_發(fā)人員提供了一個選擇,并最終使每個人受益。

結(jié)論

雖然<script type="module">的初衷是在瀏覽器中加載ES模塊(及其依賴項)的機制,但它的目的不應(yīng)該局限于此。

<script type="module">將很容易加載一個JavaScript文件,這為開發(fā)人員提供了一種必要的方法,可以在支持它的瀏覽器中有條件的加載新功能。

這與nomodule屬性一起,為我們提供了一種在生產(chǎn)中使用ES2015+代碼的方法,我們終于可以停止向不需要它的瀏覽器發(fā)送這么多的冗余代碼。

編寫ES2015代碼對開發(fā)人員來說是一個勝利,部署ES2015代碼對用戶來說是一個勝利。

延伸閱讀:


版權(quán)聲明:
轉(zhuǎn)載時請注明作者Fundebug以及本文地址:
https://blog./2018/07/31/deploying_es2015+/

您的用戶遇到BUG了嗎?

體驗Demo 免費使用

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    欧美激情视频一区二区三区| 正在播放玩弄漂亮少妇高潮| 91人人妻人人爽人人狠狠| 国产一区二区久久综合| 98精品永久免费视频| 大香蕉精品视频一区二区| 国产午夜精品亚洲精品国产| 国产肥妇一区二区熟女精品 | 亚洲一区二区三区日韩91| 伊人色综合久久伊人婷婷| 国产欧美日本在线播放| 亚洲熟女国产熟女二区三区| 视频一区中文字幕日韩| 欧美日韩国产欧美日韩| 人妻亚洲一区二区三区| 国产精品一区二区传媒蜜臀| 国产内射一级二级三级| 亚洲一区二区精品免费视频| 欧美日韩亚洲国产av| 97人妻精品一区二区三区男同| 国产在线小视频你懂的| 国产精品视频一区二区秋霞| 亚洲欧美中文字幕精品| 99久免费精品视频在线观| 国产成人在线一区二区三区| 国产视频在线一区二区| 翘臀少妇成人一区二区| 色一欲一性一乱—区二区三区| 日韩精品一区二区三区含羞含羞草 | 国产精品二区三区免费播放心| 欧美日韩一区二区午夜| 日本加勒比不卡二三四区| 玩弄人妻少妇一区二区桃花| 日韩18一区二区三区| 美日韩一区二区精品系列| 亚洲av成人一区二区三区在线| 亚洲天堂精品在线视频| 日韩人妻免费视频一专区| 欧洲亚洲精品自拍偷拍| 久久大香蕉精品在线观看 | 日本免费一区二区三女|