<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          全面認識ECMAScript模塊

          共 4693字,需瀏覽 10分鐘

           ·

          2020-12-31 09:28

          關于ES模塊,本文將提供一些詳細的解讀,希望對你有所幫助!

          什么是ES模塊?

          ECMAScript模塊(簡稱ES模塊)是2015年推出的JavaScript中代碼重用的機制。在高度碎片化的JavaScript模塊場景中,它終于成為了標準。


          在2015年之前,JavaScript還沒有一個標準的代碼重用機制。這方面曾有過很多標準化的嘗試,導致這些年亂七八糟的碎片化。


          你可能聽說過AMD模塊、UMD或者CommonJS。沒有明顯的贏家。終于,隨著ECMAScript 2015,ES模塊登陸語言。


          我們現(xiàn)在有了一個 "官方 "的模塊系統(tǒng)。

          ECMAScript模塊無處不在?

          理論上,ECMAScript模塊應該普遍適用于所有JavaScript環(huán)境。實際上,瀏覽器仍然是ES模塊的主要目標。


          2020年5月,Node.js v12.17.0發(fā)貨時,支持ECMAScript模塊,沒有標志。這意味著我們現(xiàn)在可以在Node.js中使用導入和導出,而無需任何額外的命令行標志。


          在ECMAScript模塊在任何JavaScript環(huán)境中普遍工作之前,還有很長的路要走,但方向是正確的。

          ES模塊是怎樣的?

          一個ES模塊就是一個簡單的文件,我們可以聲明一個或多個出口。以這個虛構的utils.js為例。


          // utils.js
          export function funcA() {
          return "Hello named export!";
          }

          export default function funcB() {
          return "Hello default export!";
          }

          我們這里有兩個導出。


          第一個是一個命名的導出,后面是一個默認的導出,表示為導出默認。


          假設我們的項目文件夾中住著這個名為utils.js的文件,我們可以在另一個文件中導入這個模塊提供的對象。

          如何從ES模塊導入

          假設我們在項目文件夾中還有一個名為consumer.js的文件。要導入utils.js所暴露的函數(shù),我們可以這樣做。


          // consumer.js
          import { funcA } from "./util.js";

          這種語法是一種命名的導入方式,與命名的導出方式有異曲同工之妙。


          如果要導入定義為默認導出的funcB,我們可以這樣做:

          // consumer.js
          import funcB from "./util.js";

          如果我們想在一個文件中同時導入默認導出和命名導出,我們可以將其壓縮為:

          // consumer.js
          import funcB, { funcA } from "./util.js";

          funcB();
          funcA();

          我們也可以用star導入整個模塊。

          import * as myModule from "./util.js";

          myModule.funcA();
          myModule.default();

          要注意,在這種情況下,必須顯式調(diào)用默認導出。


          要從遠程模塊導入。

          import { createStore } from "https://unpkg.com/[email protected]/es/redux.mjs";

          const store = createStore(/* do stuff */)

          瀏覽器中的ECMAScript模塊

          現(xiàn)代瀏覽器支持ES模塊,盡管有一些注意事項。要加載一個模塊,請在腳本標簽的type屬性中添加模塊。


          <html lang="en">
          <head>
          <meta charset="UTF-8">
          <title>ECMAScript modules in the browsertitle>
          head>
          <body>
          <p id="el">The result is: p>
          body>
          <script type="module">
          import { appendResult } from "./myModule.js";

          const el = document.getElementById("el");
          appendResult(el);
          script>
          html>

          這里myModule.js是同一個項目文件夾下的一個簡單模塊。

          export function appendResult(element) {
          const result = Math.random();
          element.innerText += result;
          }

          雖然可以直接在瀏覽器中使用ES模塊,但現(xiàn)在捆綁JavaScript應用的任務仍然是webpack等工具的專屬,以獲得最大的靈活性、代碼拆分和對舊瀏覽器的兼容性。

          動態(tài)導入

          ES模塊是靜態(tài)的,這意味著我們無法在運行時更改導入。有了2020年登陸的動態(tài)導入,我們可以根據(jù)用戶的交互動態(tài)加載我們的代碼(webpack在ECMAScript 2020中提供動態(tài)導入功能之前就已經(jīng)提供了)。


          考慮一個簡單的HTML,它可以加載一個腳本。



          <html lang="en">
          <head>
          <meta charset="UTF-8">
          <title>Dynamic importstitle>
          head>
          <body>
          <button id="btn">Load!button>
          body>
          <script src="loader.js">script>
          html>

          也可以考慮用幾個導出的JavaScript模塊。

          // util.js
          export function funcA() {
          console.log("Hello named export!");
          }

          export default function funcB() {
          console.log("Hello default export!");
          }

          如果要動態(tài)加載這個模塊,也許點擊一下,我們可以這樣做。

          // loader.js
          const btn = document.getElementById("btn");

          btn.addEventListener("click", () => {
          // loads named export
          import("./util.js").then(({ funcA }) => {
          funcA();
          });
          });

          在這里,我們通過重構模塊的對象,只加載命名的導出。

          ({ funcA }) => {}

          ES模塊實際上就是JavaScript對象:我們可以重構它們的屬性,也可以調(diào)用它們的任何暴露的方法。


          要動態(tài)地導入一個默認的導出,我們可以這樣做。

          // loader.js
          const btn = document.getElementById("btn");

          btn.addEventListener("click", () => {
          // loads entire module
          // runs default export
          import("./util.js").then((module) => {
          module.default();
          });
          });

          當整體導入一個模塊時,我們可以使用它的所有輸出。

          // loader.js
          const btn = document.getElementById("btn");

          btn.addEventListener("click", () => {
          // loads entire module
          // uses everything
          import("./util.js").then((module) => {
          module.funcA();
          module.default();
          });
          });

          還有一種常見的動態(tài)導入方式,我們在文件的頂部提取邏輯。

          const loadUtil = () => import("./util.js");

          const btn = document.getElementById("btn");

          btn.addEventListener("click", () => {
          //
          });

          在這里,loadUtil將返回一個Promise,準備進行鏈鎖。

          const loadUtil = () => import("./util.js");

          const btn = document.getElementById("btn");

          btn.addEventListener("click", () => {
          loadUtil().then(module => {
          module.funcA();
          module.default();
          });
          });

          動態(tài)導入看起來很好,但是它們有什么用呢?


          通過動態(tài)導入,我們可以拆分我們的代碼,只在合適的時刻加載重要的內(nèi)容。在動態(tài)導入登陸JavaScript之前,這種模式是webpack這個模塊捆綁器的專屬。


          像React和Vue這樣的前端庫,就大量使用了通過動態(tài)導入進行代碼拆分的方式,在響應事件時加載分塊代碼,比如用戶交互或者路由變化。

          JSON文件的動態(tài)導入

          假設你在代碼庫的某個地方有一個JSON文件person.json。


          {
          "name": "Jules",
          "age": 43
          }

          現(xiàn)在,你想動態(tài)地導入這個文件,以響應一些用戶的交互。


          由于JSON文件導出的只是一個默認的導出,它不是一個函數(shù),所以你只能像這樣訪問默認的導出。

          const loadPerson = () => import("./person.json");

          const btn = document.getElementById("btn");

          btn.addEventListener("click", () => {
          loadPerson().then(module => {
          const { name, age } = module.default;
          console.log(name, age);
          });
          });

          這里,我們從默認的導出中重構name和age。

              const { name, age } = module.default;

          使用async/await動態(tài)導入

          import()語句返回的總是一個Promise,這意味著我們可以對它使用async/await。

          const loadUtil = () => import("./util.js");

          const btn = document.getElementById("btn");

          btn.addEventListener("click", async () => {
          const utilsModule = await loadUtil();
          utilsModule.funcA();
          utilsModule.default();
          });

          動態(tài)導入名稱

          當用import()導入一個模塊時,你可以隨心所欲地給它命名,只要保持一致即可。

            import("./util.js").then((module) => {
          module.funcA();
          module.default();
          });

          或者:

            import("./util.js").then((utilModule) => {
          utilModule.funcA();
          utilModule.default();
          });

          關注數(shù):10億+?文章數(shù):10億+
          粉絲量:10億+?點擊量:10億+

          ?


          懸賞博主專區(qū)請掃描這里


          喜愛數(shù):?1億+?發(fā)帖數(shù):?1億+
          回帖數(shù):?1億+?結貼率:?99.9%


          —————END—————



          喜歡本文的朋友,歡迎關注公眾號?程序員哆啦A夢,收看更多精彩內(nèi)容

          點個[在看],是對小達最大的支持!


          如果覺得這篇文章還不錯,來個【分享、點贊、在看】三連吧,讓更多的人也看到~

          瀏覽 98
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91久久免费视频 | 日韩久久高清视频在线播放 | 青青青视频在线 | 99热0| 天天躁日日躁AAAAXXXX |