【JavaScript】ESModule(esm)
ESModule
- ESModule (esm) 是 ES6 的模块化方案,使用
import
&export
进行导入导出 - Node 及浏览器均支持 esm
- 在 .html 文件中应用模块化,需要给 script 标签设置
type="module"
- Node 默认支持 cjs 模块化规范。若想 Node 支持 esm,需要:
① 确保 Node 版本 >= 14.15.1
② 在 package.json 的根节点中配置"type": "module"
- 在 .html 文件中应用模块化,需要给 script 标签设置
- 导入时 [路径]、[后缀] 都要写全!!!
默认导入导出
- 一个模块只能有一个默认导出:
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)相关推荐
- 【JavaScript】回流(reflow)与重绘(repaint)
重绘与回流 首先要了解页面是如何呈现的: HTML文档加载后生成DOM树(包括display:none;元素): 在DOM树的基础上配合css样式结构体生成render树(不包含display:non ...
- 【BZOJ3028】食物(生成函数)
[BZOJ3028]食物(生成函数) 题面 一个人要带\(n\)个物品,共有\(8\)种物品,每种的限制分别如下: 偶数个;0/1个;0/1/2个;奇数个; 4的倍数个;0/1/2/3个;0/1个;3 ...
- 【CF949D】Curfew(贪心)
[CF949D]Curfew(贪心) 题面 CF 洛谷 破池姐姐翻译好强啊 题解 今天菊开讲这题,我大力猜想一波说肯定从中间有个分界线,他还说可能是假的 大力贪心就好了,从两边往中间考虑,只要这个房间 ...
- 【数据处理】奇异值分解(SVD) 数据降噪的python实现
[数据处理]奇异值分解(SVD) 数据降噪的python实现 一.特征值分解 二.奇异值分解 三.python实现 参考资料 一.特征值分解 (参考资料[1])对称矩阵不同的特征值对应的特征向量两两正 ...
- 【Luogu3478】【POI2008】STA-Station(动态规划)
[Luogu3478][POI2008]STA-Station(动态规划) 题面 题目描述 给出一个\(N(2<=N<=10^6)\)个点的树,找出一个点来,以这个点为根的树时,所有点的深 ...
- 【Centos】EFAK(kafka-eagle)对ZK、Kafka可视化管理工具容器化安装与配置
[Centos]EFAK(kafka-eagle)对ZK.Kafka可视化管理工具容器化安装与配置 前言 构建 Dockerfile system-config.properties works re ...
- 【31】GPU(下):为什么深度学习需要使用GPU?
[计算机组成原理]学习笔记--总目录 [31]GPU(下):为什么深度学习需要使用GPU? 引言 一.Shader 的诞生和可编程图形处理器[GPU发展历史] 1.可编程管线(Programable ...
- 【操作系统】文件管理(三)—— 文件的目录结构
[操作系统]文件管理(三)-- 文件的目录结构 一.文件控制块(FCB) 二.索引结点(FCB的改进) 三.目录结构 1. 单级目录结构 2. 两级目录结构 3. 多级目录结构(树形目录结构) 4. ...
- 【30】GPU(上):为什么玩游戏需要使用GPU?
[计算机组成原理]学习笔记--总目录 [30]GPU(上):为什么玩游戏需要使用GPU? 引言 一.GPU 的历史进程[略读] 二.图形渲染的流程[5个步骤] 1.顶点处理[三维空间中的点转换到二维空 ...
最新文章
- remote 移除_remote模块的使用(四)
- 支持比特币支付的商家中有90%接受了BCH
- 结对编程--基于android平台的黄金点游戏
- MATLAB数学计算与工程分析范例教程,MATLAB数学计算与工程分析范例教程
- python处理数据的包_在Python中利用Into包整洁地进行数据迁移的教程
- 在StackBlitz上setup SAP Spartacus
- spacy库的安装与使用_为 SpaCy 提供的中文数据模型
- scrapy常用工具备忘
- 借助office web apps实现在线预览和在线编辑
- restful接口开发实例_Restful接口开发与测试—接口测试
- 欠拟合和过拟合以及如何选择模型
- Sublime Text 3已卸载
- LSTM训练过程与参数解读
- linux查看标准错误码工具
- 第八篇: UpdateProgress 控件--显示正在处理中的信息
- 【算法】线性时间选择——第k大(小)元素问题
- 华为IPD你学不会(转)
- 电脑准考证登录不上去
- eclipse的启动失败提示发生了错误,请参阅日志文件
- html5绘制矩形动画,HTML5 Canvas中绘制矩形实例
热门文章
- python提取前几行数据_python读取文件的前几行
- Win7 XP 自动登录(取消每次登录Administration界面)
- FPG-超越FPN/NAS-FPN的表现 | Feature Pyramid Grids
- Android 锁屏后Service服务保活(支持9.0)
- ZK Studio 1.0 发布新功能
- [个人经验]我的百度测试开发实习始与末
- 为什么用企业微信做私域运营
- linux系统基础知识总结
- Windows server 2003怎么安装iis?Windows server 2003安装IIS教程
- 认养一头牛冲刺A股:拟募资18.5亿 徐晓波持股近40%