浅析 ES Module 与 CommonJS 的解析过程
浅析 ES Module 与 CommonJS 的解析过程
commonJS (node使用的比较多,因为同步加载在浏览器中不好使)
-
ommonJS是一个规范
- Node是commonJs在服务器一个具有代表性的实现
- Browserify是CommonJS在浏览器中的一种实现
- webpack打包工具具备对commonJS的支持和转换。
-
Node 中对CommonJS 进行了支持和实现,
- node中每一个js都是一个单独的模块
- 这个模块中包含CommonJS规范的核心变量:exports、module.exports、require
- 我们可以使用这些变量来进行模块化开发
- 导入:require
- 导出:export 、 module.exports
Node中使用CommonJS模块化的原理
exports对象的引用赋值 联系引用数据类型 和 原始数据类型的 堆内存 栈内存的一个使用原理
浅层拷贝 === 引用赋值
CommonJS的加载 module.exports
- commonJS 其实是没有module.exports的概念的
- Node通过使用Module类,每一个模块(JS文件)都是一个modlule实例
- 所以module中真正导出的是module.exports
- Exports 对象其实是module.exports 的一个浅拷贝 也就是说 module.exports = exports = bar.js
require的细节
- require是同步加载资源的
- Require 对于对于资源只会加载一次,再次调用使用缓存 , process全局对象中的module实例中的isLoad 表示是否加载过
- 循环调用,采用了图的深度优先遍历的算法
ES Module
- 采用了 import export 两种关键字
- 编译器的静态分析(在函数中不能直接调用)
- 采用ES Module 将自动采用严格模式: use strict
ES Module的加载过程
- 在加载过程中采用了模拟环境记录,对导出的变量进行实时绑定(也就意味着左侧变量改变后会主动进行重新赋值)
- 针对于对象变量 绑定的是其堆内存的指针
两者加载过程对比
-
CommonJS 加载js文件的过程是运行时加载的,并且是同步的
- js引擎在执行js代码的过程中加载模块
const flag = true;
if(flag) {
const foo = require('./index');
}
-
CommonJS 通过module.exports 导出的是一个对象
- exports = module.exports = foo.js
- 引用赋值
-
ES Module 加载js文件的过程是编译时加载的 , 并且是异步的
-
编译时加载 意味着 import 不能和运行时相关的内容放在一起使用(静态解析)
-
const flag = true; if(flag) { import {max} form './index' XXXX }
-
-
异步的也就意味着 script type = 'module' 想到与 defer、async
-
转载自:https://juejin.cn/post/7156060104964440077