赞
踩
在讲解CommonJS和ECMAScript Module(简称ESM)的区别之前,要先搞清楚他们所要解决的问题。
在CommonJS和ESM出现之前,一般直接通过script标签引入js文件,这带来了两个问题,一个是作用域污染,一个是循环依赖。
作用域污染: 假设html中引入了3个js,a和b,a中定义了name=1,b中定了了name=function(),c中再使用name时,如果先加载的a后加载的b,那么c中使用name就时就一直是function了。如果在较大的项目中,作用域污染的问题将会尤为严重,调用别的模块的方法,得到的却不是自己想要的东西。
循环依赖: script标签引入模块,模块是按照标签顺序加载的,这就导致,后加载的模块可以依赖先加载的模块,而先加载的模块不能引用后加载的模块,这给后期维护和在模块中新加内容带来了很大的麻烦。
当然这种方式还有很多弊端,这里就不一一列举,CommonJS和ESM都是为了解决这类问题而产生的。
说到CommonJS,就不得不提NodeJs,CommonJS是一种模块加载的规范,而NodeJs使用的便是这种规范,这种关系有点像ES6和Javascript。
CommonJS核心点就是通过require引入模块(js文件),通过exports和module.exports将模块暴露出去,需要注意的是,这种方式仅支持node环境下,浏览器是不支持的。
可以参考如下代码
// a.js
function hello() {
console.log('name')
}
module.exports = hello
// index.js
let hello = require('./a')
hello()
我们在a.js中暴露了hello方法,并在index.js中引用a.js并调用hello方法,由于CommonJS的模块加载规范并不能在浏览器运行,所以我们直接使用node指令运行idex.js
可以看到,console的内容成功打印了出来。
ESM是ES6中规定的模块加载规范,需要注意的是,node环境并不支持ESM的规范,所以我们在node环境下是不能用ESM的。浏览器是支持ESM的,ESM通过import导入模块,通过export和export default导出对象或方法。
因为ESM不能够在node环境下运行,所以我们在html中引入index.js文件,代码如下
// a.js
export function hello() {
console.log('name')
}
// index.js
import { hello } from './a.js'
hello()
// index.html
<body>
<script src="./src/index.js" type="module"></script>
</body>
这样,我们在浏览器运行index.html文件时,控制台同样会打出name字样,和CommonJS实现的是一样的。有两点需要注意,需要在server模式下运行,可以使用live server插件,还有script标签需要加上type=“module”,不然会报错Cannot use import statement outside a module
我们从几个方面来区分两者的区别
CommonJs需要node环境,ESM需要浏览器环境,但通常只有较新的浏览器才能完整的支持ESM,所以无论是CommonJs还是ESM,都可以交给Webpack在打包时做转义,输出成浏览器能够识别的语法。
CommonJs的require是在使用时加载的,即当代码运行到这里,该模块才会被加载。而ESM的import是在编译的时候加载的,即当你运行时,被import的模块就已经和其产生关系。
CommonJs使用require引用模块,使用exports或module.exports暴露模块。
ESM使用import加载模块,使用export或者export default暴露模块。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。