likes
comments
collection
share

浅析 ES Module 与 CommonJS 的解析过程

作者站长头像
站长
· 阅读数 18

浅析 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

浅析 ES Module 与 CommonJS 的解析过程

  • 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的加载过程

浅析 ES Module 与 CommonJS 的解析过程

  • 在加载过程中采用了模拟环境记录,对导出的变量进行实时绑定(也就意味着左侧变量改变后会主动进行重新赋值)
  • 针对于对象变量 绑定的是其堆内存的指针

两者加载过程对比

  • 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