搜尋

了解ES6模塊

Feb 15, 2025 am 10:57 AM

Understanding ES6 Modules

ES6 模塊:現代 JavaScript 的模塊化方案

本文探討 ES6 模塊,並展示如何在轉譯器的幫助下使用它們。幾乎所有語言都有模塊的概念——一種在另一個文件中包含已聲明功能的方法。通常,開發人員會創建一個封裝的代碼庫,負責處理相關的任務。該庫可以被應用程序或其他模塊引用。其優勢在於:

  1. 代碼可以拆分成更小的、自包含功能的文件。
  2. 相同的模塊可以在任意數量的應用程序之間共享。
  3. 理想情況下,模塊無需被其他開發人員檢查,因為它們已被證明有效。
  4. 引用模塊的代碼知道它是一個依賴項。如果模塊文件被更改或移動,問題會立即顯現。
  5. 模塊代碼(通常)有助於消除命名衝突。模塊 1 中的函數 x() 不會與模塊 2 中的函數 x() 衝突。可以使用命名空間等選項,使調用變為 module1.x() 和 module2.x()。

JavaScript 中的模塊在哪裡?

幾年前開始 Web 開發的任何人都會驚訝地發現 JavaScript 中沒有模塊的概念。無法直接引用或包含一個 JavaScript 文件到另一個文件中。因此,開發人員求助於其他方法。

多種 HTML <p> </p> <ul></ul>

  • 然而,這並非理想方案:
  • 每個腳本都會發起一個新的 HTTP 請求,這會影響頁面性能。 HTTP/2 在一定程度上緩解了這個問題,但它無助於引用其他域(如 CDN)上的腳本。
  • 每個腳本在其運行期間都會暫停進一步的處理。
  • 依賴項管理是一個手動過程。在上面的代碼中,如果 lib1.js 引用了 lib2.js 中的代碼,則代碼會失敗,因為它尚未加載。這可能會破壞進一步的 JavaScript 處理。

    除非使用適當的模塊模式,否則函數可能會覆蓋其他函數。早期的 JavaScript 庫因使用全局函數名或覆蓋原生方法而臭名昭著。

    腳本合併

    <🎜>
    解決多個

    或者內聯:

    模塊只解析一次,無論它們在頁面或其他模塊中被引用多少次。

    <p> <strong> </strong></p>

    服務器注意事項

    <script> 标签</script>

    HTML 可以使用多个 <script></script> 标签加载任意数量的 JavaScript 文件:

    <script src="lib1.js"></script>模塊必須使用 MIME 類型 application/javascript 提供服務。大多數服務器會自動執行此操作,但要注意動態生成的腳本或 .mjs 文件(請參閱下面的 Node.js 部分)。常規 <script src="lib2.js"></script><script src="core.js"></script>
    <script>console.log('inline code');</script><script></code> 标签问题的一种方法是将所有 JavaScript 文件合并成一个大型文件。这解决了一些性能和依赖项管理问题,但可能会导致手动构建和测试步骤。</p>
    <p><strong>模块加载器</strong></p>
    <p>RequireJS 和 SystemJS 等系统提供了一个库,用于在运行时加载和命名其他 JavaScript 库。模块在需要时使用 Ajax 方法加载。这些系统有所帮助,但对于大型代码库或添加标准 <code><script></code> 标签的网站来说,可能会变得复杂。</p>
    <p><strong>模块打包器、预处理器和转译器</strong></p>
    <p>打包器引入了编译步骤,以便在构建时生成 JavaScript 代码。代码经过处理以包含依赖项并生成单个 ES5 跨浏览器兼容的合并文件。流行的选项包括 Babel、Browserify、webpack 以及更通用的任务运行器,如 Grunt 和 Gulp。</p>
    <p>JavaScript 构建过程需要一些努力,但也有好处:</p>
    <ul>
    <li>处理是自动化的,因此人为错误的可能性较小。</li>
    <li>进一步的处理可以整理代码、删除调试命令、缩小结果文件等。</li>
    <li>转译允许您使用替代语法,如 TypeScript 或 CoffeeScript。</li>
    </ul>
    <p><strong>ES6 模块</strong></p>
    <p>上述选项引入了各种相互竞争的模块定义格式。广泛采用的语法包括:</p>
    <ul>
    <li>CommonJS——Node.js 中使用的 module.exports 和 require 语法</li>
    <li>异步模块定义 (AMD)</li>
    <li>通用模块定义 (UMD)</li>
    </ul>
    <p>因此,在 ES6 (ES2015) 中提出了单一的原生模块标准。</p>
    <p>ES6 模块内部的所有内容默认情况下都是私有的,并且在严格模式下运行(不需要“use strict”)。公共变量、函数和类使用 export 导出。例如:</p>
    <pre class="brush:php;toolbar:false"><code class="language-javascript">// lib.js
    export const PI = 3.1415926;
    export function sum(...args) {
      log('sum', args);
      return args.reduce((num, tot) => tot + num);
    }
    export function mult(...args) {
      log('mult', args);
      return args.reduce((num, tot) => tot * num);
    }
    // 私有函数
    function log(...msg) {
      console.log(...msg);
    }

    或者,可以使用单个 export 语句。例如:

    // lib.js
    const PI = 3.1415926;
    
    function sum(...args) {
      log('sum', args);
      return args.reduce((num, tot) => tot + num);
    }
    
    function mult(...args) {
      log('mult', args);
      return args.reduce((num, tot) => tot * num);
    }
    
    // 私有函数
    function log(...msg) {
      console.log(...msg);
    }
    
    export { PI, sum, mult };

    然后使用 import 将模块中的项目导入到另一个脚本或模块中:

    // main.js
    import { sum } from './lib.js';
    
    console.log(sum(1, 2, 3, 4)); // 10

    在这种情况下,lib.js 与 main.js 在同一个文件夹中。可以使用绝对文件引用(以 / 开头)、相对文件引用(以 ./ 或 ../ 开头)或完整 URL。可以一次导入多个项目:

    import { sum, mult } from './lib.js';
    
    console.log(sum(1, 2, 3, 4));  // 10
    console.log(mult(1, 2, 3, 4)); // 24

    并且可以为导入指定别名以解决命名冲突:

    import { sum as addAll, mult as multiplyAll } from './lib.js';
    
    console.log(addAll(1, 2, 3, 4));      // 10
    console.log(multiplyAll(1, 2, 3, 4)); // 24

    最后,可以通过提供命名空间来导入所有公共项目:

    import * as lib from './lib.js';
    
    console.log(lib.PI);            // 3.1415926
    console.log(lib.sum(1, 2, 3, 4));  // 10
    console.log(lib.mult(1, 2, 3, 4)); // 24

    在浏览器中使用 ES6 模块

    在撰写本文时,ES6 模块受 Chromium 系浏览器 (v63+)、Safari 11+ 和 Edge 16+ 支持。Firefox 支持将在版本 60 中到来(在 v58+ 中位于 about:config 标志之后)。使用模块的脚本必须通过在 <script></script> 标签中设置 type="module" 属性来加载。例如:

    模塊回退<script></script> 标签可以获取其他域上的脚本,但模块是使用跨域资源共享 (CORS) 获取的。因此,不同域上的模块必须设置适当的 HTTP 标头,例如 Access-Control-Allow-Origin: *。
    

    最后,除非在 <script></script> 标签中添加 crossorigin="use-credentials" 属性并且响应包含标头 Access-Control-Allow-Credentials: true,否则模块不会发送 Cookie 或其他标头凭据。

    模块执行被延迟

    <script></script> 标签的 defer 属性会延迟脚本执行,直到文档加载并解析完毕。模块(包括内联脚本)默认情况下会延迟。示例:

    <!-- 运行在第二位 -->
    <script type="module">
      // 执行某些操作...
    </script>
    <script defer src="c.js"></script>不支持模塊的瀏覽器不會運行 type="module" 腳本。可以使用 nomodule 屬性提供一個回退腳本,模塊兼容的瀏覽器會忽略該屬性。例如:<script src="a.js"></script><pre class='brush:php;toolbar:false;'>&lt;🎜&gt;</pre>
    <p><strong>您應該在瀏覽器中使用模塊嗎? </strong></p>
    <p>瀏覽器支持正在增長,但現在切換到 ES6 模塊可能還為時過早。目前,最好使用模塊打包器來創建一個在任何地方都能工作的腳本。 </p>
    <p><strong>在 Node.js 中使用 ES6 模塊</strong></p>
    <p>Node.js 在 2009 年發佈時,任何運行時不提供模塊都是不可想像的。採用了 CommonJS,這意味著可以開發 Node 包管理器 npm。從那時起,使用量呈指數級增長。 CommonJS 模塊的編碼方式與 ES2015 模塊類似。使用 module.exports 而不是 export:</p>
    <pre class='brush:php;toolbar:false;'>&lt;🎜&gt;
    &lt;🎜&gt;</pre>
    <p>使用 require(而不是 import)將此模塊導入到另一個腳本或模塊中:</p>
    <pre class='brush:php;toolbar:false;'>// lib.js
    const PI = 3.1415926;
    
    function sum(...args) {
      log('sum', args);
      return args.reduce((num, tot) =&gt; tot + num);
    }
    
    function mult(...args) {
      log('mult', args);
      return args.reduce((num, tot) =&gt; tot * num);
    }
    
    // 私有函数
    function log(...msg) {
      console.log(...msg);
    }
    
    module.exports = { PI, sum, mult };</pre>
    <p>require 也可以導入所有項目:</p>
    <pre class='brush:php;toolbar:false;'>const { sum, mult } = require('./lib.js');
    
    console.log(sum(1, 2, 3, 4));  // 10
    console.log(mult(1, 2, 3, 4)); // 24</pre>
    <p>那麼,在 Node.js 中實現 ES6 模塊很容易,對嗎? <em>不對</em>。 ES6 模塊在 Node.js 9.8.0  中位於標誌之後,並且至少要到版本 10 才會完全實現。雖然 CommonJS 和 ES6 模塊具有相似的語法,但它們的工作方式根本不同:</p>
    <ul>
    <li>ES6 模塊在執行代碼之前預先解析以解析進一步的導入。 </li>
    <li>CommonJS 模塊在執行代碼時按需加載依賴項。 </li>
    </ul>
    <p>在上面的示例中這沒有區別,但請考慮以下 ES2015 模塊代碼:</p>
    <pre class='brush:php;toolbar:false;'>const lib = require('./lib.js');
    
    console.log(lib.PI);            // 3.1415926
    console.log(lib.sum(1, 2, 3, 4));  // 10
    console.log(lib.mult(1, 2, 3, 4)); // 24</pre>
    <p>ES2015 的輸出:</p>
    <pre class='brush:php;toolbar:false;'>// ES2015 模块
    
    // ---------------------------------
    // one.js
    console.log('running one.js');
    import { hello } from './two.js';
    console.log(hello);
    
    // ---------------------------------
    // two.js
    console.log('running two.js');
    export const hello = 'Hello from two.js';</pre>
    <p>使用 CommonJS 編寫的類似代碼:</p>
    <pre class="brush:php;toolbar:false">&lt;code&gt;running two.js
    running one.js
    Hello from two.js&lt;/code&gt;</pre>
    <p>CommonJS 的輸出:</p>
    <pre class='brush:php;toolbar:false;'>// CommonJS 模块
    
    // ---------------------------------
    // one.js
    console.log('running one.js');
    const hello = require('./two.js');
    console.log(hello);
    
    // ---------------------------------
    // two.js
    console.log('running two.js');
    module.exports = 'Hello from two.js';</pre>
    <p>執行順序在某些應用程序中可能至關重要,如果在同一個文件中混合使用 ES2015 和 CommonJS 模塊會發生什麼?為了解決這個問題,Node.js 僅允許在擴展名為 .mjs 的文件中使用 ES6 模塊。擴展名為 .js 的文件將默認為 CommonJS。這是一個簡單的選項,它消除了大部分複雜性,並且應該有助於代碼編輯器和代碼檢查器。 </p>
    <p><strong>您應該在 Node.js 中使用 ES6 模塊嗎? </strong></p>
    <p>ES6 模塊僅在 Node.js v10 及更高版本(於 2018 年 4 月發布)中實用。轉換現有項目不太可能帶來任何好處,並且會使應用程序與早期版本的 Node.js 不兼容。對於新項目,ES6 模塊提供了一種 CommonJS 的替代方案。語法與客戶端編碼相同,並且可能為同構 JavaScript 提供更簡單的途徑,同構 JavaScript 可以在瀏覽器或服務器上運行。 </p>
    <p><strong>模塊混戰</strong></p>
    <p>標準化的 JavaScript 模塊系統花了多年時間才出現,並且花了更長時間才實現,但問題已經得到糾正。從 2018 年年中開始,所有主流瀏覽器和 Node.js 都支持 ES6 模塊,儘管在每個人都升級時應該預期會有一個切換延遲。今天學習 ES6 模塊,以便在明天從您的 JavaScript 開發中受益。 </p>
    <p><strong>關於 ES6 模塊的常見問題解答 (FAQ)</strong></p>
    <p><strong>(此處省略了原文檔中的FAQ部分,因為已經對全文進行了充分的偽原創)</strong></p>

    以上是了解ES6模塊的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

    JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

    使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

    我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

    如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

    本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

    JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

    JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

    JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

    JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

    神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

    JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

    Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

    Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

    如何安裝JavaScript?如何安裝JavaScript?Apr 05, 2025 am 12:16 AM

    JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

    See all articles

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    AI Hentai Generator

    AI Hentai Generator

    免費產生 AI 無盡。

    熱門文章

    R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
    3 週前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳圖形設置
    3 週前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您聽不到任何人,如何修復音頻
    3 週前By尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25:如何解鎖Myrise中的所有內容
    4 週前By尊渡假赌尊渡假赌尊渡假赌

    熱工具

    MinGW - Minimalist GNU for Windows

    MinGW - Minimalist GNU for Windows

    這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    將Eclipse與SAP NetWeaver應用伺服器整合。

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器

    Dreamweaver Mac版

    Dreamweaver Mac版

    視覺化網頁開發工具

    SublimeText3 Linux新版

    SublimeText3 Linux新版

    SublimeText3 Linux最新版