中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

js中ESM規范的示例分析

發布時間:2021-09-17 14:27:20 來源:億速云 閱讀:242 作者:柒染 欄目:web開發

js中ESM規范的示例分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

js中ESM規范的示例分析

前端發展到如今,社區生態已經非常豐富。

在無數開源大神的努力下,很多前端開發的痛點(比如「靜態類型檢查」、「瀏覽器兼容性」)早已有了事實上的標準解決方案(比如TS、babel)。

然而,在這繁榮之下,有一個日常開發不易感知的問題:

  • 模塊化規范的混亂

你可曾遇到過莫名其妙的bug,在多方搜資源,反復驗證,耗費數個小時終于發現:

原來是某個包導出的是CJS,而項目使用ESM導致。

比如這個例子:記一次打包壓縮報錯[1]

如果你覺得這是個很容易發現的問題,再考慮結合上node_modules的層層依賴呢?

這個問題,揭開了模塊化規范間斗爭與博弈的冰山一角。

作為現代前端工程化的基石,模塊化規范有太多值得深究的內容。

我會花幾篇文章來講解模塊化規范。本文是第一篇,會圍繞模塊化規范的演進展開。

正文

如果問十年前的前端最頭疼的是什么?一定是瀏覽器兼容性。

隨著babel等編譯工具出現,兼容性逐漸被工程化方案解決(ES6+編譯為ES5)。

不僅是「兼容性」問題,DSL(如JSX、VUE的模版語法)、代碼壓縮、代碼靜態檢查(TS)等日常開發的剛需都能在工程化方案中找到解決辦法。

如果將當今繁榮的前端工程化生態比喻為一座大廈,那大廈的地基一定是「模塊化規范」。

現代JS代碼都是基于「模塊化規范」組織起來,讓我們從下往上來看看這座大廈:

js中ESM規范的示例分析

規范的實現依賴于宿主環境,比如瀏覽器環境實現了EcmaScript Module(后文簡稱ESM)規范。

Node v12之前支持CommonJS(后文簡稱CJS)規范,12之后同時支持CJS與ESM。

在「宿主環境」之上,是基于模塊化規范實現的「工具集」,比如webpack、vite、VScode生態。

再往上,基于「工具集」提供的API,可以實現各種工程化工具。比如:

  • webpack loader

  • VScode plugin

  • babel plugin

再往上,就是開發者自己編寫的業務代碼。

開發者只需要在工具集中配置好工具,就能為業務代碼提供服務。比如:

在VScode(工具集)中配置eslint(工具),就能在開發時獲得相應提示

在webpack(工具集)中配置babel loader(工具),就能在開發時使用ES6+語法

可見,理想狀態下,在開發者視角是不需要關注底層的「模塊化規范」實現的。

規范之爭

然而,事物是動態發展的,模塊化規范也不是一蹴而就的,讓我們回到09年。

美國程序員「Ryan Dahl」創造了node.js項目,將JS用于服務端開發。

js中ESM規范的示例分析

node.js使用CJS[2]標準作為模塊化規范。

js中ESM規范的示例分析

有了服務端模塊規范(CJS),很自然的,JS開發者們想為客戶端(主要是瀏覽器)提供一種模塊化規范。

然而CJS是為服務端設計的。

在服務端,IO操作通常能迅速完成,所以CJS規范定義的:

  • 模塊加載 --> 模塊解析 --> 模塊執行

這個流程是作為一個整體同步執行的。

然而在瀏覽器環境,「模塊加載」(即數據請求)通常很耗時。有人曾作出一個形象的比喻:

如果一個CPU周期花費1秒完成,那么文件的網絡請求需要花費4年。

js中ESM規范的示例分析

顯然瀏覽器端需要一種「支持異步」的模塊化規范。

AMD(Asynchronous Module Definition 異步模塊定義)規范,就是這樣需求背景下的產物。

然而這些社區提出的規范終究只是為了解決一時的需求,隨著歷史的發展,新的模塊化規范不斷涌入、消亡。

直到ESM規范被提出。

ESM規范是ES標準的模塊化規范,他的早期討論可以追溯到2009年。

你可以在這里看到ESM規范的歷史es-module-history[3]

ESM將模塊規范分為三個階段:

  • 模塊加載 --> 模塊實例化 --> 模塊執行

其中「模塊加載」由宿主環境提供的loader完成(比如在瀏覽器環境,loader的行為由HTML規范[4]定義)。

「模塊實例化」與「模塊執行」由ESM規范定義執行流程。

區別于CJS規范的同步執行,ESM規范將流程拆解為3個獨立階段。

「模塊加載」同步、異步與否由宿主環境決定。

支持不同宿主環境,抹平多端差異、能力比其他規范都強大(后文會介紹)、再加上血統純正(ES官方提出),

使得ESM規范一統前端「看似」指日可待。

然而,此時社區已經有大量基于CJS規范產出的開源包、組件,他們無法立刻切換到ESM規范。

所以,JS生態的現狀是:會處于、并將長期處于CJS規范的庫與ESM規范的庫共存的狀態。

但是最終,ESM規范一定會成為主導,畢竟他的優點太多(同樣,后文會介紹)。

規范割裂帶來的機會

js中ESM規范的示例分析

當前模塊化規范的混亂,對開源大佬們來說,就是機會。

為了讓開發者將更多精力放在業務,而不是模塊規范的適配上。

很多開源「工具集」都試圖抹平模塊化差異,比如:

  • 在babel中使用babel-plugin-transform-commonjs可以將CJS規范的代碼轉換為ESM規范

  • 為了一刀切解決當前ESM、CJS、瀏覽器script標簽導入這3種規范互相不兼容的情況,提出了兼容三者格式的UMD(Universal Module  Definition)規范

一些「工具集」利用模塊化規范的不同與其他競品形成差異化競爭,比如:

  • browserify這款打包工具的賣點是:使用CJS規范打包,使一份代碼同時在Node環境與瀏覽器環境(打包后)執行。

js中ESM規范的示例分析

其中,在瀏覽器環境中,Node的一些核心庫(如events、stream、path...)會被打包成瀏覽器支持的版本。

  • Vite在DEV環境使用ESM規范構建模塊間的依賴關系。

依賴于大部分現代瀏覽器原生支持ESM規范,省去了打包的過程,使其編譯速度大大提升。

  • rollup原生對ESM提供更多支持。

嚴格支持ESM規范,并提供更好的靜態分析,使rollup一度提供性能更優異的treeShaking能力。

成為更多庫打包工具的首選。

與webpack這樣的的大而全方案形成差異競爭。

規范割裂帶來的痛

可以看到,由于底層宿主環境對模塊化規范支持的割裂,需要上層工具集來抹平模塊規范的差異。

設想一個同時使用了webpack、babel、TS的項目。

這3個工具集都對多種模塊規范有兼容處理。比如:

單獨使用babel時,對于如下代碼:

import a from 'lib'; console.log(a);

會被babel編譯為:

"use strict";  var _lib = _interopRequireDefault(require("lib"));  function _interopRequireDefault(obj) {   return obj && obj.__esModule ? obj : { default: obj }; }  console.log(_lib.default);

ESM的「默認導出」會被編譯為包含default屬性的對象。

你可以打開babel playground[5]試試

當多個「工具集」在同一個項目中,為了各自目的做著同一件事(抹平模塊化規范差異),

一旦工具鏈中某個插件配置有一絲絲不符合預期,或者引入了一個不符合預期的包,那么艱難的debug就此開始了......

js中ESM規范的示例分析

曙光即使當前有諸多不便,歷史的進程是無法阻止的,那些被歷史巨輪甩下并碾碎的模塊化規范,會逐漸消失在開發者的視野中。

看完上述內容,你們掌握js中ESM規范的示例分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

js
AI

信宜市| 赣榆县| 布拖县| 邵阳市| 荃湾区| 镇坪县| 安岳县| 淳化县| 林州市| 哈密市| 郑州市| 陆河县| 苏尼特左旗| 准格尔旗| 长武县| 靖宇县| 澄迈县| 翼城县| 淄博市| 岚皋县| 榆社县| 车险| 白山市| 扬州市| 老河口市| 铜川市| 库尔勒市| 连城县| 林州市| 铁力市| 连云港市| 锡林郭勒盟| 饶阳县| 连州市| 灌南县| 玉田县| 博白县| 南通市| 汉沽区| 溧阳市| 遂溪县|