ESModule

  • ESModule (esm) 是 ES6 的模块化方案,使用 import & export 进行导入导出
  • Node浏览器均支持 esm
    • 在 .html 文件中应用模块化,需要给 script 标签设置 type="module"
    • Node 默认支持 cjs 模块化规范。若想 Node 支持 esm,需要:
      ① 确保 Node 版本 >= 14.15.1
      ② 在 package.json 的根节点中配置 "type": "module"
  • 导入时 [路径]、[后缀] 都要写全!!!

默认导入导出

  • 一个模块只能有一个默认导出:export default XXX
  • 导入时接收的变量可自定义,符合标识符命名规范即可

demo1:

/* esm1.js */
let name = "superman";
export default name;
/* esm2.js */
import esm1 from "./esm1.js";
console.log("esm1", esm1); // esm1 superman

demo2:

/* esm1.js */
let name = "superman";
function showName() {console.log("name", name);
}
export default { name, showName };
/* esm2.js */
import esm1 from "./esm1.js";
console.log("esm1", esm1); // esm1 { name: 'superman', showName: [Function: showName] }

按需导入导出

  • 一个模块可以有多个导出
  • 导入时接收的变量需要与导出的标识符一样
  • 导入时可以使用 as 重命名
  • [按需导入导出] 可与 [默认导入导出] 一起使用
/* esm1.js */
export let name = "superman";
export function showName() {console.log("name", name);
}
export default { age: 21 }; // 默认导出
/* esm2.js */
import esm1, { name as myName, showName } from "./esm1.js";
console.log("esm1", esm1); // esm1 { age: 21 }
console.log("myName", myName); // myName superman
console.log("showName", showName); // showName [Function: showName]
  • 导入时可用 * 接收被导入文件的所有导出,需要配合 as 取别名使用:
/* esm2.js */
import * as esm1 from "./esm1.js";
console.log("esm1", esm1);
esm1 [Module: null prototype] {default: 21,name: 'superman',showName: [Function: showName]
}

直接执行模块

  • 导入文件时,会先执行被导入的文件,然后获取该文件导出的数据
  • 如果只想执行指定文件,而无需获取该文件导出的数据,可直接使用 import "./XXX.js"
/* esm1.js */
console.log("esm1");
/* esm2.js */
import "./esm1.js";

esm 模块化特点

① 每个模块都有自己作用域

<script>let name = "superman"
</script>
<script>console.log(name); // superman
</script>
<script type="module">let name = "superman"
</script>
<script type="module">console.log(name); // 输出空值
</script>

② 模块会被延迟解析

默认情况下,HTML 文件是从上往下解析的。如果把 script 标签放在 body 标签的前面,则无法获取 DOM 元素

<body><div>superman</div>
</body>
<script>console.log(document.querySelector("div"));
</script>

但是,如果我们给 script 标签添加属性 type="module",则会等页面加载完成后,才执行 script 标签里面的语句

<script type="module">console.log(document.querySelector("div"));
</script>
<body><div>superman</div>
</body>

③ 使用 esm 会将 JS 的运行模式变成 [严格模式](默认情况下,不是 [严格模式])

<script type="module">a = 10; // 会报错;严格模式下,变量必须被定义
</script>

④ 动态绑定

  • 使用 export 按需导出的是数据的引用,就是说 [源数据] 更新后,导入的数据也会更新
/* esm1.js */
export let age = 18;
setTimeout(() => (age = 21), 1000); // 一秒后改变 age 值
/* esm2.js */
import { age } from "./esm1.js";
console.log(age); // 18
setTimeout(() => {// 两秒后重新获取 age 值console.log(age); // 21
}, 2000);
  • 但是使用 export default 默认导出的数据不会动态绑定
/* esm1.js */
let age = 18;
export default age;
setTimeout(() => (age = 21), 1000); // 一秒后改变 age 值
/* esm2.js */
import age from "./esm1.js";
console.log(age); // 18
setTimeout(() => {// 两秒后重新获取 age 值console.log(age); // 18
}, 2000);

import 注意事项

① 即使重复写 import 语句,都只会导入一次

/* esm1.js */
console.log("esm1");
/* esm2.js */
import "./esm1.js";
import "./esm1.js";
import "./esm1.js";

看见,"esm1" 只输出了一次

import 语句提升

  • import 语句有提升效果,会提升到整个模块的最前面,首先执行

    这是因为 import 语句是编译阶段执行的,在代码运行之前

  • 因此,导入为静态加载,即不管用不用,都会先导入

foo();
import { foo } from 'my_module';

import 语句中不能使用 [表达式] / [变量]

  • 由于 import静态执行,所以不能使用 [表达式] / [变量] 这些只有在运行时才能得到结果的语法结构
// 报错
import { 'f' + 'oo' } from 'my_module'; // 不能使用 [表达式] 接收导入数据// 报错
let module = 'my_module';
import { foo } from module; // 不能使用 [变量] 作为被导入文件的路径// 报错:不能在语句内进行导入
if (true)import { foo } from 'module1';

动态导入import()

  • 因为是静态引入,所以默认的 import 语法不能写在 if 之类的语句里
  • 如果有这样的需求,我们可以使用 import() 动态导入:
if (true)import('./1.js');
  • 注意:动态引入,不会有 import 提升 (毕竟都不再是编译阶段执行了,变成运行时执行了)

  • import() 动态引入,返回一个 Promise 对象

    then() 的参数是导入的模块对象

import('./index2.js').then(res => {console.log(res); // Module {Symbol(Symbol.toStringTag): "Module"}
});

模块化 demo

思路:[ 数据 ]、[ 方法 ]、[ 逻辑处理 ] 分开放置

/* demo.js */
let a = 20;
let b = 30;
export { a, b };
/* demo2.js */
import { a, b } from "./demo.js";
const sum = () => a + b
export default sum;
<script type="module">import sum from '../js/demo2.js'console.log(sum()); // 50
</script>

CommonJs(cjs)

【JavaScript】ESModule(esm)相关推荐

  1. 【JavaScript】回流(reflow)与重绘(repaint)

    重绘与回流 首先要了解页面是如何呈现的: HTML文档加载后生成DOM树(包括display:none;元素): 在DOM树的基础上配合css样式结构体生成render树(不包含display:non ...

  2. 【BZOJ3028】食物(生成函数)

    [BZOJ3028]食物(生成函数) 题面 一个人要带\(n\)个物品,共有\(8\)种物品,每种的限制分别如下: 偶数个;0/1个;0/1/2个;奇数个; 4的倍数个;0/1/2/3个;0/1个;3 ...

  3. 【CF949D】Curfew(贪心)

    [CF949D]Curfew(贪心) 题面 CF 洛谷 破池姐姐翻译好强啊 题解 今天菊开讲这题,我大力猜想一波说肯定从中间有个分界线,他还说可能是假的 大力贪心就好了,从两边往中间考虑,只要这个房间 ...

  4. 【数据处理】奇异值分解(SVD) 数据降噪的python实现

    [数据处理]奇异值分解(SVD) 数据降噪的python实现 一.特征值分解 二.奇异值分解 三.python实现 参考资料 一.特征值分解 (参考资料[1])对称矩阵不同的特征值对应的特征向量两两正 ...

  5. 【Luogu3478】【POI2008】STA-Station(动态规划)

    [Luogu3478][POI2008]STA-Station(动态规划) 题面 题目描述 给出一个\(N(2<=N<=10^6)\)个点的树,找出一个点来,以这个点为根的树时,所有点的深 ...

  6. 【Centos】EFAK(kafka-eagle)对ZK、Kafka可视化管理工具容器化安装与配置

    [Centos]EFAK(kafka-eagle)对ZK.Kafka可视化管理工具容器化安装与配置 前言 构建 Dockerfile system-config.properties works re ...

  7. 【31】GPU(下):为什么深度学习需要使用GPU?

    [计算机组成原理]学习笔记--总目录 [31]GPU(下):为什么深度学习需要使用GPU? 引言 一.Shader 的诞生和可编程图形处理器[GPU发展历史] 1.可编程管线(Programable ...

  8. 【操作系统】文件管理(三)—— 文件的目录结构

    [操作系统]文件管理(三)-- 文件的目录结构 一.文件控制块(FCB) 二.索引结点(FCB的改进) 三.目录结构 1. 单级目录结构 2. 两级目录结构 3. 多级目录结构(树形目录结构) 4. ...

  9. 【30】GPU(上):为什么玩游戏需要使用GPU?

    [计算机组成原理]学习笔记--总目录 [30]GPU(上):为什么玩游戏需要使用GPU? 引言 一.GPU 的历史进程[略读] 二.图形渲染的流程[5个步骤] 1.顶点处理[三维空间中的点转换到二维空 ...

最新文章

  1. remote 移除_remote模块的使用(四)
  2. 支持比特币支付的商家中有90%接受了BCH
  3. 结对编程--基于android平台的黄金点游戏
  4. MATLAB数学计算与工程分析范例教程,MATLAB数学计算与工程分析范例教程
  5. python处理数据的包_在Python中利用Into包整洁地进行数据迁移的教程
  6. 在StackBlitz上setup SAP Spartacus
  7. spacy库的安装与使用_为 SpaCy 提供的中文数据模型
  8. scrapy常用工具备忘
  9. 借助office web apps实现在线预览和在线编辑
  10. restful接口开发实例_Restful接口开发与测试—接口测试
  11. 欠拟合和过拟合以及如何选择模型
  12. Sublime Text 3已卸载
  13. LSTM训练过程与参数解读
  14. linux查看标准错误码工具
  15. 第八篇: UpdateProgress 控件--显示正在处理中的信息
  16. 【算法】线性时间选择——第k大(小)元素问题
  17. 华为IPD你学不会(转)
  18. 电脑准考证登录不上去
  19. eclipse的启动失败提示发生了错误,请参阅日志文件
  20. html5绘制矩形动画,HTML5 Canvas中绘制矩形实例

热门文章

  1. python提取前几行数据_python读取文件的前几行
  2. Win7 XP 自动登录(取消每次登录Administration界面)
  3. FPG-超越FPN/NAS-FPN的表现 | Feature Pyramid Grids
  4. Android 锁屏后Service服务保活(支持9.0)
  5. ZK Studio 1.0 发布新功能
  6. [个人经验]我的百度测试开发实习始与末
  7. 为什么用企业微信做私域运营
  8. linux系统基础知识总结
  9. Windows server 2003怎么安装iis?Windows server 2003安装IIS教程
  10. 认养一头牛冲刺A股:拟募资18.5亿 徐晓波持股近40%