CommonJS规范 和 ES6模块化总结

一、模块化解决了什么问题

1、全局污染问题

比如在a.js中写了一个名为getName的方法,在b.js文件中也定义了getName方法,但是方法内容不同,此时在index.html文件中分别引入a.js和b.js, 并调用getName方法,此时如果b.js晚于a.js引入,那么b.js中的逻辑就会覆盖掉a.js中的,也就是同名覆盖问题。

2、文件间的相互依赖

当我们在页面引入非常多的外部依赖,并且这些依赖间存在引入顺序先后的问题

3、数据安全问题

当我们定义了一个包含非常多属性的对象,并在方法中return出其中的部分属性,但是还是可以在外部访问到该对象的所有属性

二、common Js

1、是社区性质的规范,非官方, 在node Js服务器用得更多一些,当然也可以通过browserify工具将代码转换成浏览器可以识别的文件,后续在页面中引用转换后的文件就可以了

2、通过exports.name = value的形式给导出对象添加属性,或者通过Module.exports{name}以对象的形式导出,但是无论怎样修改导出的对象,最后都导出的都是Module.exports的值,exports是对Module.exports的初始引用,exports、Module.exports、this最开始都指向同一个空对象

 3、通过const {name:newName} = require('./a.js') or const a = require('./a.js')的形式导入

4、可能我们都会好奇,为什么Module.exports等可以直接拿过来使用,因为该模块的文件内容相当于函数体,外面被一个大的function包着,exports等都是这个function的参数,传进来我们可以直接在函数体中使用

三、ES6模块化

1、符合ECMA规范,官方提出的模块化规范,浏览器和服务器均可使用,使用时在script标签中或package.json中配置type为module就好

2、通过export const name = 'aaa'的方式分别导出,使用export{name}同一导出,注意此时{}不是对象,export defaulet{name}的方式导出默认对象,可以混合使用

3、通过import {name as newName] from '../a.s' 的方式引入,所以这里并不是es6中的结构赋值,可以import * from './a.js'方式引入所有内容

四、一个重要的点

commonjs引入的是变量的值,相当于深拷贝,后续该变量如果在导出文件中通过一些方法改变了值,此时导入文件中的值不会有任何变化; 即使多次执行一个模块的require命令,它都只会在第一次加载时运行一次,后面都会从缓存中读取,除非手动清除缓存

es6模块化,导出文件和导入文件的变量指向同一个内存地址,所以会互相影响,模块加载命令import,会生成一个只读引用,等到脚本真正执行的时候,再根据这个只读引用,到被加载的那个模块里去取值。

为了避免这种影响,我们更推荐使用const定义常量,而不是使用let

由于 ES6 模块的导入和导出在编译时就被确定,工具(如打包器、代码检查器和 IDE)可以在不执行代码的情况下分析模块之间的依赖关系、检查错误和优化代码

 CommonJS 模块是动态的,使用 require() 导入模块。由于 require() 是在运行时解析的,导致工具在编译时无法确定模块的接口。这使得静态分析的可能性大大降低。

一篇好的参考文章:https://juejin.cn/post/6844904067651600391

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WJIA7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值