偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

發(fā)布、傳輸和安裝現(xiàn)代 JavaScript 以實現(xiàn)更快的應用程序

開發(fā) 前端
當今的 Web 受到傳統(tǒng) JavaScript 限制,沒有任何單一優(yōu)化可以像使用 ES2017 語法編寫、發(fā)布和傳輸網(wǎng)頁或軟件包那樣提高性能。

超過 90% 的瀏覽器能夠運行現(xiàn)代 JavaScript,但傳統(tǒng) JavaScript 的流行仍然是當今 Web 性能問題的最大原因之一。

當今的 Web 受到傳統(tǒng) JavaScript 限制,沒有任何單一優(yōu)化可以像使用 ES2017 語法編寫、發(fā)布和傳輸網(wǎng)頁或軟件包那樣提高性能。

現(xiàn)代 JavaScript

現(xiàn)代 JavaScript 的特征不是使用特定的 ECMAScript 規(guī)范版本編寫代碼,而是使用所有現(xiàn)代瀏覽器都支持的語法。Chrome、Edge、Firefox 和 Safari 等現(xiàn)代網(wǎng)絡瀏覽器占據(jù)瀏覽器市場的 90% 以上,依賴相同底層渲染引擎的其他瀏覽器占另外 5%。這意味著全球 95% 的 Web 流量所來自的瀏覽器支持過去 10 年來最廣泛使用的 JavaScript 語言特性,包括:

  • 類 (ES2015)
  • 箭頭函數(shù) (ES2015)
  • 生成器 (ES2015)
  • 塊范圍 (ES2015)
  • 解構 (ES2015)
  • 剩余和展開參數(shù) (ES2015)
  • 對象速記 (ES2015)
  • 異步/等待 (ES2017)

較新版本的語言規(guī)范中的特性在現(xiàn)代瀏覽器中獲得的支持通常不太一致。例如,許多 ES2020 和 ES2021 特性僅在 70% 的瀏覽器市場獲得支持 — 仍然是大多數(shù)瀏覽器,但還不夠安全,不能直接依賴這些特性。這意味著盡管“現(xiàn)代”JavaScript 是一個活動目標,但 ES2017 擁有最廣泛的瀏覽器兼容性,同時包含大多數(shù)常用的現(xiàn)代語法特性。換句話說,ES2017 目前最接近現(xiàn)代語法。

傳統(tǒng) JavaScript

傳統(tǒng) JavaScript 是明確避免使用上述所有語言特性的代碼。大多數(shù)開發(fā)人員使用現(xiàn)代語法編寫源代碼,但將所有內(nèi)容編譯為傳統(tǒng)語法以增加瀏覽器支持。編譯為傳統(tǒng)語法確實會增加瀏覽器支持,但效果通常比我們想象的小。在許多情況下,支持度從 95% 左右增加到 98%,但同時產(chǎn)生了大量成本:

  • 傳統(tǒng) JavaScript 通常比等效的現(xiàn)代代碼大 20% 左右,而且速度更慢。工具缺陷和錯誤配置通常會進一步擴大這一差距。
  • 安裝的庫占典型生產(chǎn) JavaScript 代碼的 90%。庫代碼會由于polyfill 和 helper 重復而產(chǎn)生更高的傳統(tǒng) JavaScript 開銷,而發(fā)布現(xiàn)代代碼可以避免這個問題。

npm 上的現(xiàn)代 JavaScript

Node.js 標準化了一個 "exports" 字段來定義軟件包的入口點:

{
"exports": "./index.js"
}

"exports" 字段引用的模塊意味著 Node 版本至少為 12.8,它支持 ES2019。這意味著使用 "exports" 字段引用的任何模塊都可以使用現(xiàn)代 JavaScript 編寫。軟件包使用者必須假定具有 "exports" 字段的模塊包含現(xiàn)代代碼并在必要時進行轉(zhuǎn)換。

僅現(xiàn)代

如果要發(fā)布采用現(xiàn)代代碼的軟件包,并讓使用者在將其用作依賴項時處理轉(zhuǎn)換,則僅使用 ??"exports"?? 字段。

{
"name": "foo",
"exports": "./modern.js"
}

不推薦這種方法。在完美的世界中,每個開發(fā)人員都已經(jīng)將編譯系統(tǒng)配置為將所有依賴項 (node_modules) 轉(zhuǎn)換為所需語法。但是,目前情況并非如此,僅使用現(xiàn)代語法發(fā)布軟件包將使其無法在通過舊版瀏覽器訪問的應用程序中使用。

具有傳統(tǒng)回退的現(xiàn)代代碼

將 "exports" 字段與 "main" 一起使用,以便使用現(xiàn)代代碼發(fā)布軟件包,但還包括用于舊版瀏覽器的 ES5 + CommonJS 回退。

{
"name": "foo",
"exports": "./modern.js",
"main": "./legacy.cjs"
}

具有傳統(tǒng)回退的現(xiàn)代代碼和 ESM 捆綁程序優(yōu)化

除了定義回退 CommonJS 入口點,還可以使用 "module" 字段指向類似的傳統(tǒng)回退捆綁包,但該捆綁包使用 JavaScript 模塊語法 (import 和 export)。

{
"name": "foo",
"exports": "./modern.js",
"main": "./legacy.cjs",
"module": "./module.js"
}

許多捆綁程序(如 webpack 和 Rollup)依賴該字段來利用模塊特性和實現(xiàn)搖樹優(yōu)化。這仍然是一個傳統(tǒng)捆綁包,不包含除了 import/export 語法之外的任何現(xiàn)代代碼,所以使用這種方法來傳輸具有傳統(tǒng)回退、但仍然針對捆綁進行了優(yōu)化的現(xiàn)代代碼。

應用程序中的現(xiàn)代 JavaScript

第三方依賴項構成了 Web 應用程序中絕大多數(shù)的典型生產(chǎn) JavaScript 代碼。雖然 npm 依賴項在歷史上一直以 ES5 語法的形式發(fā)布,但這不再是一個安全假設,并且依賴項更新可能會破壞應用程序的瀏覽器支持。

隨著越來越多的 npm 包轉(zhuǎn)向現(xiàn)代 JavaScript,確保構建工具設置為能夠處理它們很重要。您所依賴的一些 npm 包很有可能已經(jīng)在使用現(xiàn)代語言特性。有許多選擇可使用 npm 中的現(xiàn)代代碼而不會破壞應用程序在舊版瀏覽器中的體驗,但總體思路是讓編譯系統(tǒng)將依賴項轉(zhuǎn)換為與源代碼相同的目標語法。

webpack

從 webpack 5 開始,現(xiàn)在可以配置 webpack 在生成捆綁包和模塊的代碼時將使用的語法。這不會轉(zhuǎn)換您的代碼或依賴項,只影響由 webpack 生成的“粘附”代碼。要指定瀏覽器支持目標,請在您的項目中添加一個 browserslist 配置,或者直接在 webpack 配置中添加:

module.exports = {
target: ['web', 'es2017'],
};

還可以將 webpack 配置為生成優(yōu)化的捆綁包,當以現(xiàn)代 ES 模塊環(huán)境為目標時,這些捆綁包會省略不必要的包裝函數(shù)。這也將 webpack 配置為使用 <script type="module"> 加載代碼拆分捆綁包。

module.exports = {
target: ['web', 'es2017'],
output: {
module: true,
},
experiments: {
outputModule: true,
},
};

有許多 webpack 插件可以編譯和傳輸現(xiàn)代 JavaScript,同時仍然支持舊版瀏覽器,例如 Optimize Plugin 和 BabelEsmPlugin。

Optimize Plugin

Optimize Plugin 是一個 webpack 插件,它可以將最終的捆綁代碼從現(xiàn)代 JavaScript 轉(zhuǎn)換為傳統(tǒng) JavaScript,而不是單獨的源文件。它是一個自包含設置,允許 webpack 配置假定所有內(nèi)容都是現(xiàn)代 JavaScript,沒有針對多個輸出或語法的特殊分支。

由于 Optimize Plugin 針對捆綁包而不是單個模塊進行操作,因此它會平等處理應用程序代碼和依賴項。這樣便可以安全地使用 npm 中的現(xiàn)代 JavaScript 依賴項,因為它們的代碼將被捆綁并轉(zhuǎn)換為正確的語法。它還可以比涉及兩個編譯步驟的傳統(tǒng)解決方案更快,同時仍然為現(xiàn)代和舊版瀏覽器生成單獨的捆綁包。這兩套捆綁包設計為使用模塊/無模塊模式加載。

// webpack.config.js
const OptimizePlugin = require('optimize-plugin');

module.exports = {
// ...
plugins: [new OptimizePlugin()],
};

Optimize Plugin 可以比自定義 webpack 配置更快、更高效,后者通常單獨捆綁現(xiàn)代和傳統(tǒng)代碼。它還可以處理運行中的 Babel,并使用 Terser 以單獨的針對現(xiàn)代和傳統(tǒng)輸出優(yōu)化的設置,使捆綁包最小化。最后,生成的傳統(tǒng)捆綁包所需的 polyfill 將提取到一個專用腳本中,這樣在較新的瀏覽器中不會復制或不必要地加載它們。

圖片

BabelEsmPlugin

BabelEsmPlugin 是一個 webpack 插件,它與 @babel/preset-env 一起工作來生成現(xiàn)有捆綁包的現(xiàn)代版本,以將更少的轉(zhuǎn)換代碼傳輸?shù)浆F(xiàn)代瀏覽器。它是 Next.js 和 Preact CLI 使用最多的模塊/無模塊現(xiàn)成解決方案。

// webpack.config.js
const BabelEsmPlugin = require('babel-esm-plugin');

module.exports = {
//...
module: {
rules: [
// your existing babel-loader configuration:
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
],
},
plugins: [new BabelEsmPlugin()],
};

BabelEsmPlugin 支持多種 webpack 配置,因為它運行應用程序的兩個基本獨立的版本。對于大型應用程序,編譯兩次可能需要一點額外的時間,但是這種技術允許 BabelEsmPlugin 無縫集成到現(xiàn)有 webpack 配置中,使其成為最方便的選擇之一。

將 babel-loader 配置為轉(zhuǎn)換 node_modules

如果使用 babel-loader 而沒有使用前兩個插件之一,則需要執(zhí)行一個重要的步驟才能使用現(xiàn)代 JavaScript npm 模塊。定義兩個單獨的 babel-loader 配置可以將 node_modules 中的現(xiàn)代語言特性自動編譯為 ES2017,同時仍然使用 Babel 插件和項目配置中定義的預設來轉(zhuǎn)換您自己的第一方代碼。這不會為模塊/無模塊設置生成現(xiàn)代和傳統(tǒng)捆綁包,但可以安裝和使用包含現(xiàn)代 JavaScript 的 npm 軟件包,而不會破壞舊版瀏覽器體驗。

webpack-plugin-modern-npm 使用這種技術來編譯在 package.json 中具有 "exports" 字段的 npm 依賴項,因為它們可能包含現(xiàn)代語法:

// webpack.config.js
const ModernNpmPlugin = require('webpack-plugin-modern-npm');

module.exports = {
plugins: [
// auto-transpile modern stuff found in node_modules
new ModernNpmPlugin(),
],
};

或者,可以通過在解析模塊時檢查 package.json 中是否存在 "exports" 字段,在 webpack 配置中手動實現(xiàn)該技術。為簡潔起見而省略緩存,自定義實現(xiàn)可能如下所示:

// webpack.config.js
module.exports = {
module: {
rules: [
// Transpile for your own first-party code:
{
test: /\.js$/i,
loader: 'babel-loader',
exclude: /node_modules/,
},
// Transpile modern dependencies:
{
test: /\.js$/i,
include(file) {
let dir = file.match(/^.*[/\\]node_modules[/\\](@.*?[/\\])?.*?[/\\]/);
try {
return dir && !!require(dir[0] + 'package.json').exports;
} catch (e) {}
},
use: {
loader: 'babel-loader',
options: {
babelrc: false,
configFile: false,
presets: ['@babel/preset-env'],
},
},
},
],
},
};

使用此方法時,您需要確保縮小器支持現(xiàn)代語法。Terser 和 uglify-es 都有指定 {ecma: 2017} 的選項,以便在壓縮和格式化期間保留 ES2017 語法并在某些情況下生成該語法。

Rollup

Rollup 內(nèi)部支持生成多組捆綁包作為單個版本的一部分,并默認生成現(xiàn)代代碼。因此,可以將 Rollup 配置為通過您可能已經(jīng)在使用的官方插件生成現(xiàn)代和傳統(tǒng)捆綁包。

@rollup/plugin-babel

如果使用 Rollup,getBabelOutputPlugin() 方法(由 Rollup 的官方 Babel 插件提供)會轉(zhuǎn)換生成的捆綁包中的代碼,而不是單個源模塊。Rollup 內(nèi)部支持生成多組捆綁包作為單個版本的一部分,每個捆綁包都有自己的插件。您可以通過不同的 Babel 輸出插件配置來傳遞各個捆綁包,從而生成不同的現(xiàn)代和傳統(tǒng)捆綁包:

// rollup.config.js
import {getBabelOutputPlugin} from '@rollup/plugin-babel';

export default {
input: 'src/index.js',
output: [
// modern bundles:
{
format: 'es',
plugins: [
getBabelOutputPlugin({
presets: [
[
'@babel/preset-env',
{
targets: {esmodules: true},
bugfixes: true,
loose: true,
},
],
],
}),
],
},
// legacy (ES5) bundles:
{
format: 'amd',
entryFileNames: '[name].legacy.js',
chunkFileNames: '[name]-[hash].legacy.js',
plugins: [
getBabelOutputPlugin({
presets: ['@babel/preset-env'],
}),
],
},
],
};

其他構建工具

Rollup 和 webpack 是高度可配置的,這通常意味著每個項目都必須更新其配置以在依賴項中啟用現(xiàn)代 JavaScript 語法。還有更高級的構建工具更傾向于慣例和默認值,而不是配置,例如 Parcel、Snowpack、Vite 和 WMR。這些工具中的大多數(shù)假定 npm 依賴項可能包含現(xiàn)代語法,并在生產(chǎn)編譯時將它們轉(zhuǎn)換為適當?shù)恼Z法級別。

除了 webpack 和 Rollup 的專用插件,還可以使用 devolution 將具有傳統(tǒng)回退的現(xiàn)代 JavaScript 捆綁包添加到任何項目中。Devolution 是一個獨立的工具,可轉(zhuǎn)換編譯系統(tǒng)的輸出以生成傳統(tǒng) JavaScript 變體,從而允許捆綁和轉(zhuǎn)換采用現(xiàn)代輸出目標。

責任編輯:華軒 來源: JavaScript 每日一練
相關推薦

2020-09-23 10:59:37

應用安全

2023-12-26 11:20:51

PyInstalleUPXPython

2015-03-13 16:19:17

JavaScript原生姿態(tài)應用程序

2009-01-03 14:25:10

ibmdwWeb

2010-08-12 15:52:34

Flex應用程序

2018-12-28 14:10:57

開發(fā)工具 移動應用

2020-04-24 08:00:51

多媒體手機移動設備

2021-08-03 10:19:32

應用程序現(xiàn)代化CIO

2022-05-14 23:51:31

云計算安全混合云

2012-12-25 09:52:22

Windows 8

2012-04-25 22:56:10

Android

2012-04-26 13:48:56

iPhone應用發(fā)布Ad Hoc

2023-10-25 10:46:56

Radius開源

2011-02-13 08:58:42

無線LANwlan整合

2023-05-24 23:34:11

2022-05-13 10:24:44

WineWindowsLinux

2022-10-21 14:21:46

JavaScript筆記技能

2021-03-14 18:26:43

云端云計算大型機應用程序

2011-02-22 10:23:43

2014-01-03 10:15:38

OpenShift應用程序部署
點贊
收藏

51CTO技術棧公眾號