ES6 模块 与 CommonJS模块

动态:模块的依赖关系建立在代码运行阶段
静态:模块的依赖关系建立在代码编译阶段

ES6模块

  • 每个文件作为一个模块,每个模块拥有独立的作用域。
  • 通过exports导出
     //命名导出:
    exports { a, b };
    export const  a = 1024;
    
    //默认导出:
    exports default a; (只能导出一个对象)

  • 通过import导入,默认导出的变量,导入时可以随意命名,命名导出方式,导入时名称必须一致,可以使用as 重命名。

 

CommonJS模块

  • 最初为服务端设计,node.js版本。
  • 每个文件即使一个模块,用于独立的作用域。
  • 导出是一个模块向外暴露自己的唯一方式。CommonJS中通过module.exports导出模块中的内容。
  • 使用 module.exports 导出一个具体的值或对象(默认导出):
  • // 导出一个值 
    module.exports = 'Hello'; 
    // 导出一个对象 
    module.exports = { name: 'John', age: 25 };
  • 使用 exports 对象导出多个成员:
  • // 导出多个成员 
    exports.name = 'John'; 
    exports.age = 25;

  • CommonJS中使用require进行模块的导入。
    如果导入的模块是第一次被加载,这时会首先执行该模块,然后导出执行后的内容。 如果模块曾经被加载过,则直接导出第一次加载时执行后的内容。(相当于是一个静态值了)

 

两种模块的差异

    ES6 模块和 CommonJS 模块有很大的差异。

语法上面:CommonJS 模块使用require()加载和module.exports输出,ES6 模块使用importexport

用法上面:require()是同步加载,后面的代码必须等待这个命令执行完,才会执行。import命令则是异步加载,或者更准确地说,ES6 模块有一个独立的静态解析阶段,依赖关系的分析是在那个阶段完成的,最底层的模块第一个执行。

 模块导入时:CommonJS是值拷贝,而ES6则是只读的动态映射。

(在 CommonJS 中,模块导入是值拷贝的,也就是说,导入的模块会被完整地 拷贝到一个新的变量中。这意味着对导入的模块进行修改不会影响原始模块的内容。)

  • ES6模块相比CommonJS的优势
    • 死代码检测和排除:通过静态分析工具检测出哪些模块没有被调用过。从而在打包时去掉未使用的模块,以减少资源包的体积。
    • 模块变量类型检查:JS是动态类型语言,不会在代码执行前检查类型错误,ES6模块属于静态类型模块,有助于确保模块之间的传递的值或者接口类型是正确的。
    • 编译器优化:CommonJS无论采用哪种方式,导入的都是一个对象,而ES6模块直接导入变量,减少应用层级,程序效率更高。

CommonJS 模块加载 ES6 模块 

CommonJS 的require()命令不能加载 ES6 模块,会报错,只能使用import()这个方法加载。


(async () => {
  await import('./my-app.mjs');
})();

上面代码可以在 CommonJS 模块中运行。

require()不支持 ES6 模块的一个原因是,它是同步加载,而 ES6 模块内部可以使用顶层await命令,导致无法被同步加载。

ES6 模块加载 CommonJS 模块

ES6 模块的import命令可以加载 CommonJS 模块,但是只能整体加载,不能只加载单一的输出项。


// 正确
import packageMain from 'commonjs-package';

// 报错
import { method } from 'commonjs-package';

这是因为 ES6 模块需要支持静态代码分析,而 CommonJS 模块的输出接口是module.exports,是一个对象(CommonJS 导出的对象是通过赋值给 module.exportsexports 来实现的,而这种赋值操作是在运行时进行的,并不能在编译时进行静态分析。),无法被静态分析,所以只能整体加载。

静态代码分析:静态代码分析是指在不执行代码的情况下(代码编译阶段),对代码进行解析、分析和处理。静态代码分析能够帮助我们理解代码的结构、依赖关系和执行流程,从而实现诸如语法检查、模块解析、依赖管理等功能。在不执行代码的情况下对其进行检查、优化和转换,从而提高代码的可靠性、可维护性和性能。

加载单一的输出项,可以写成下面这样。


import packageMain from 'commonjs-package';
const { method } = packageMain;

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值