了解ES6模块
ES6 模块:现代 JavaScript 的模块化方案
本文探讨 ES6 模块,并展示如何在转译器的帮助下使用它们。几乎所有语言都有模块的概念——一种在另一个文件中包含已声明功能的方法。通常,开发人员会创建一个封装的代码库,负责处理相关的任务。该库可以被应用程序或其他模块引用。其优势在于:
- 代码可以拆分成更小的、自包含功能的文件。
- 相同的模块可以在任意数量的应用程序之间共享。
- 理想情况下,模块无需被其他开发人员检查,因为它们已被证明有效。
- 引用模块的代码知道它是一个依赖项。如果模块文件被更改或移动,问题会立即显现。
- 模块代码(通常)有助于消除命名冲突。模块 1 中的函数 x() 不会与模块 2 中的函数 x() 冲突。可以使用命名空间等选项,使调用变为 module1.x() 和 module2.x()。
JavaScript 中的模块在哪里?
几年前开始 Web 开发的任何人都会惊讶地发现 JavaScript 中没有模块的概念。无法直接引用或包含一个 JavaScript 文件到另一个文件中。因此,开发人员求助于其他方法。
多种 HTML
除非使用适当的模块模式,否则函数可能会覆盖其他函数。早期的 JavaScript 库因使用全局函数名或覆盖原生方法而臭名昭著。
或者内联:
<p>
</p>
<ul></ul>
脚本合并
<🎜>
</pre>
<p>
<strong>
</strong>
HTML 可以使用多个 <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="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>
标签中设置 type="module" 属性来加载。例如:
模块回退<script>
标签可以获取其他域上的脚本,但模块是使用跨域资源共享 (CORS) 获取的。因此,不同域上的模块必须设置适当的 HTTP 标头,例如 Access-Control-Allow-Origin: *。最后,除非在
<script>
标签中添加 crossorigin="use-credentials" 属性并且响应包含标头 Access-Control-Allow-Credentials: true,否则模块不会发送 Cookie 或其他标头凭据。模块执行被延迟
<script>
标签的defer
属性会延迟脚本执行,直到文档加载并解析完毕。模块(包括内联脚本)默认情况下会延迟。示例:不支持模块的浏览器不会运行 type="module" 脚本。可以使用 nomodule 属性提供一个回退脚本,模块兼容的浏览器会忽略该属性。例如:
<🎜>登录后复制您应该在浏览器中使用模块吗?
浏览器支持正在增长,但现在切换到 ES6 模块可能还为时过早。目前,最好使用模块打包器来创建一个在任何地方都能工作的脚本。
在 Node.js 中使用 ES6 模块
Node.js 在 2009 年发布时,任何运行时不提供模块都是不可想象的。采用了 CommonJS,这意味着可以开发 Node 包管理器 npm。从那时起,使用量呈指数级增长。CommonJS 模块的编码方式与 ES2015 模块类似。使用 module.exports 而不是 export:
<🎜> <🎜>登录后复制使用 require(而不是 import)将此模块导入到另一个脚本或模块中:
// 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); } module.exports = { PI, sum, mult };登录后复制require 也可以导入所有项目:
const { sum, mult } = require('./lib.js'); console.log(sum(1, 2, 3, 4)); // 10 console.log(mult(1, 2, 3, 4)); // 24登录后复制那么,在 Node.js 中实现 ES6 模块很容易,对吗?不对。ES6 模块在 Node.js 9.8.0 中位于标志之后,并且至少要到版本 10 才会完全实现。虽然 CommonJS 和 ES6 模块具有相似的语法,但它们的工作方式根本不同:
- ES6 模块在执行代码之前预先解析以解析进一步的导入。
- CommonJS 模块在执行代码时按需加载依赖项。
在上面的示例中这没有区别,但请考虑以下 ES2015 模块代码:
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登录后复制ES2015 的输出:
// 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';登录后复制使用 CommonJS 编写的类似代码:
<code>running two.js running one.js Hello from two.js</code>登录后复制CommonJS 的输出:
// 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';登录后复制执行顺序在某些应用程序中可能至关重要,如果在同一个文件中混合使用 ES2015 和 CommonJS 模块会发生什么?为了解决这个问题,Node.js 仅允许在扩展名为 .mjs 的文件中使用 ES6 模块。扩展名为 .js 的文件将默认为 CommonJS。这是一个简单的选项,它消除了大部分复杂性,并且应该有助于代码编辑器和代码检查器。
您应该在 Node.js 中使用 ES6 模块吗?
ES6 模块仅在 Node.js v10 及更高版本(于 2018 年 4 月发布)中实用。转换现有项目不太可能带来任何好处,并且会使应用程序与早期版本的 Node.js 不兼容。对于新项目,ES6 模块提供了一种 CommonJS 的替代方案。语法与客户端编码相同,并且可能为同构 JavaScript 提供更简单的途径,同构 JavaScript 可以在浏览器或服务器上运行。
模块混战
标准化的 JavaScript 模块系统花了多年时间才出现,并且花了更长时间才实现,但问题已经得到纠正。从 2018 年年中开始,所有主流浏览器和 Node.js 都支持 ES6 模块,尽管在每个人都升级时应该预期会有一个切换延迟。今天学习 ES6 模块,以便在明天从您的 JavaScript 开发中受益。
关于 ES6 模块的常见问题解答 (FAQ)
(此处省略了原文档中的FAQ部分,因为已经对全文进行了充分的伪原创)
以上是了解ES6模块的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

JavaScript在网站、移动应用、桌面应用和服务器端编程中均有广泛应用。1)在网站开发中,JavaScript与HTML、CSS一起操作DOM,实现动态效果,并支持如jQuery、React等框架。2)通过ReactNative和Ionic,JavaScript用于开发跨平台移动应用。3)Electron框架使JavaScript能构建桌面应用。4)Node.js让JavaScript在服务器端运行,支持高并发请求。
