ES6 module: Modular solution for modern JavaScript
This article explores ES6 modules and shows how to use them with the help of a translator. Almost all languages have the concept of modules—a way to include declared functions in another file. Typically, developers create a packaged code base that handles related tasks. The library can be referenced by an application or other module. The advantages are:
Where are modules in JavaScript?
Anyone who started web development a few years ago would be surprised to find that there is no concept of modules in JavaScript. It is impossible to directly reference or include a JavaScript file into another file. Therefore, developers turn to other methods.
Various HTML
Functions may override other functions unless appropriate module mode is used. Early JavaScript libraries were notorious for using global function names or overwriting native methods.
Or inline:
<p>
</p>
<ul></ul>
Script merge
<🎜>
</pre>
<p>
<strong>
</strong>
HTML 可以使用多个 <script>
标签加载任意数量的 JavaScript 文件:
<script src="lib1.js"></script>Modules must be served using MIME type application/javascript. Most servers do this automatically, but be careful about dynamically generated scripts or .mjs files (see the Node.js section below). Regular <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>
标签中设置 type="module" 属性来加载。例如:
Module rollback<script>
标签可以获取其他域上的脚本,但模块是使用跨域资源共享 (CORS) 获取的。因此,不同域上的模块必须设置适当的 HTTP 标头,例如 Access-Control-Allow-Origin: *。最后,除非在
<script>
标签中添加 crossorigin="use-credentials" 属性并且响应包含标头 Access-Control-Allow-Credentials: true,否则模块不会发送 Cookie 或其他标头凭据。模块执行被延迟
<script>
标签的defer
属性会延迟脚本执行,直到文档加载并解析完毕。模块(包括内联脚本)默认情况下会延迟。示例:Browsers that do not support modules will not run the type="module" script. You can use the nomodule property to provide a fallback script that is ignored by the module-compatible browser. For example:
<🎜>Copy after loginShould you use modules in your browser?
Browser support is growing, but it may be too early to switch to the ES6 module. Currently, it is best to use a module packer to create a script that works anywhere.
Using ES6 module in Node.js
Node.js was released in 2009, it was unimaginable that no module was provided at any runtime. CommonJS is used, which means that the Node package manager npm can be developed. Since then, usage has increased exponentially. The CommonJS module is encoded in a similar way to the ES2015 module. Use module.exports instead of export:
<🎜> <🎜>Copy after loginUse require (rather than import) to import this module into another script or module:
// 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 };Copy after loginrequire can also import all projects:
const { sum, mult } = require('./lib.js'); console.log(sum(1, 2, 3, 4)); // 10 console.log(mult(1, 2, 3, 4)); // 24Copy after loginSo, it's easy to implement ES6 modules in Node.js, right? Not right. The ES6 module is located after the flags in Node.js 9.8.0 and will not be fully implemented until at least version 10. Although CommonJS and ES6 modules have similar syntax, they work in a fundamentally different way:
- ES6 modules are pre-parsed before executing the code to parse further imports.
- The CommonJS module loads dependencies on demand when executing code.
In the example above, this does not make any difference, but consider the following ES2015 module code:
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)); // 24Copy after loginOutput of 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';Copy after loginSimilar code written using CommonJS:
<code>running two.js running one.js Hello from two.js</code>Copy after loginOutput of 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';Copy after loginExecution order can be critical in some applications, what happens if you mix ES2015 and CommonJS modules in the same file? To solve this problem, Node.js only allows the use of ES6 modules in files with the extension .mjs. Files with the extension .js will default to CommonJS. This is a simple option that removes most of the complexity and should help with the code editor and code inspector.
Should you use the ES6 module in Node.js?
ES6 module is only useful in Node.js v10 and later (released in April 2018). Converting an existing project is unlikely to bring any benefits and will make the application incompatible with earlier versions of Node.js. For new projects, the ES6 module provides an alternative to CommonJS. The syntax is the same as client encoding and may provide an easier way to isomorphic JavaScript, which can run on a browser or server.
Module Melee
The standardized JavaScript module system took years to emerge and took longer to implement, but the problem has been corrected. Starting in mid-2018, all mainstream browsers and Node.js support the ES6 module, although a switching delay should be expected when everyone upgrades. Learn ES6 modules today to benefit from your JavaScript development tomorrow.
FAQs about ES6 modules (FAQ)
(The FAQ part in the original document is omitted here because the full text has been fully pseudo-originalized)
The above is the detailed content of Understanding ES6 Modules. For more information, please follow other related articles on the PHP Chinese website!