ES模块

当我们提到 ES模块(ECMAScript Modules,简称ESM)时,指的是 JavaScript 模块化 的一种标准化方式,允许开发者在浏览器和 Node.js 环境中以更加结构化和可维护的方式来组织和共享代码。谷歌浏览器(Google Chrome)从版本61开始,就支持了JavaScript的ES模块(ECMAScript Modules,简称ESM)。这意味着从2018年5月开始

ES模块的背景

在 JavaScript 中,早期的脚本是全局作用域的,这使得在大型项目中管理和共享代码变得困难。为了改进这一点,JavaScript 引入了模块化的概念,使得每个文件可以成为一个模块,包含独立的代码逻辑,并通过 导入(import) 和 导出(export) 语句与其他模块交互。

ES模块的主要特点

1导入和导出:

通过 export 导出模块中的功能或数据。 通过 import 导入其他模块导出的功能或数据。 例如:

  1. // module.js
  2. export const greet = () => console.log("Hello, World!");
  3. // main.js
  4. import { greet } from './module.js';
  5. greet(); // 输出 "Hello, World!"

2静态分析:

与 CommonJS(Node.js 中的模块化标准)不同,ESM 是静态的。这意味着模块的导入和导出在编译时就能确定,能够进行更好的优化,比如提前加载、减少冗余代码等。 这也让浏览器能够进行更高效的解析和执行。

3按需加载:

ES模块支持按需加载,这意味着只会加载被需要的模块,从而提高性能。例如,浏览器只会加载实际导入的部分,而不会一次性加载整个文件。

4默认导出和命名导出:

默认导出:模块中可以有一个默认导出的实体,其他模块可以随意命名这个导出的内容。

  1. // math.js
  2. export default function add(a, b) {
  3. return a + b;
  4. }
  5. // main.js
  6. import add from './math.js';

命名导出:模块可以导出多个命名的实体,每个导出的内容都需要使用对应的名称导入。

  1. // utils.js
  2. export function sum(a, b) {
  3. return a + b;
  4. }
  5. export const PI = 3.14159;
  6. // main.js
  7. import { sum, PI } from './utils.js';

5异步加载:

ES模块的加载是异步的,这意味着在浏览器中使用 <script> 标签时,浏览器不会阻塞页面的渲染,能够提高加载性能。

浏览器对 ES模块的支持

随着 JavaScript 语言的发展,浏览器开始 原生支持 ES模块。在浏览器中引入 ES模块,使用<script type="module">标签来指定,和传统的<script>标签相比有以下几个不同点:

1异步加载:

<script type="module">中的脚本会被异步加载,这意味着它不会阻塞页面渲染。

2模块化:

使用 import 和 export 语句可以直接在浏览器中使用模块化的功能。例如,你可以直接在 HTML 页面中引入模块:

  1. <script type="module">
  2. import { greet } from './module.js';
  3. greet();
  4. </script>

3跨域限制:

默认情况下,模块导入遵循 同源策略,也就是说,模块文件需要和主页面在同一源(即相同的协议、域名和端口)下才能被加载。如果你想跨域加载模块,需要配置 CORS(跨源资源共享)。

4严格模式:

ES模块默认在严格模式下执行,这意味着在该模式下,某些不允许的操作(例如定义重复的变量、使用未声明的变量等)会抛出错误。

与传统<script>标签的区别

传统的<script>标签会按顺序同步执行脚本,但这种方式不适用于大型应用,因为多个脚本的加载可能会导致页面渲染延迟。而 ES模块通过以下方式改进了这一点:

异步加载:

<script type="module">默认会异步加载,不会阻塞页面的渲染。

按需加载:

模块化的特性意味着只会加载实际需要的模块,节省了带宽和性能开销。

作用域:

每个模块都有自己的作用域,不会污染全局作用域,减少了命名冲突的风险。

ES模块的未来

随着浏览器对 ES模块的广泛支持,开发者可以利用模块化的特性进行更高效、更可维护的开发。特别是在构建大型前端应用时,ES模块提供了一种原生的、标准化的方式来组织代码,而不再依赖于第三方工具或复杂的打包机制。