CommonJS和ES6module的异同

开头总结
1 相同点
都是前端模块化的一种
2 不同点

  • 前者利用exports和module.exports导出数据,用require导入; 后者利用export和export default导出,利用import导入
  • 前者是动态化加载,可以放在块级作用域中使用; 后者是静态加载,在编译的时候就处理了。
  • 前者导出的数据如果是基本数据类型,导出的是拷贝,引用数据类型的话则是引用。后者导出的都是原数据的引用。
  • 前者可以解决循环引用的问题,后者不能解决
    不同点分析
    第一点
    // c.js exports.name = "mike"; module.exports = { name: "mike" } // d.js let c = require('./c'); console.log(c); // { name: 'mike' }

    对于ES6module要在package.json中增加"type": "module"或者采用.mjs扩展名,下面演示代码采用后者
    // b.mjs export let a = "hello world"; const b = "这是b" export default b; // a.mjs import b, {a} from './b.mjs' console.log(a); // hello world console.log(b); // 这是b // 对于export default的变量,引入的时候不需要加{},export的变量需要加{}

    第二点CommonJS如下
    只改变d的内容
    // d.js function say() { let c = require('./c'); console.log(c); } say(); // { name: 'mike' }

    ES6module如下
    只改变a.mjs
    function say() { import b, {a} from './b.mjs' console.log(a); console.log(b); } say(); // 报错

    第三点对于CommonJS
    // c.js module.exports = "hello world" // d.js let a = require('./c') a = "hi, world" console.log(a); let b = require('./c') console.log(b); //hi, world // hello world// 引用数据类型的情况 // c.js exports.name = "hello, world" // d.js let a = require('./c') a.name = "hi, world" console.log(a); let b = require('./c') console.log(b); // { name: 'hi, world' } { name: 'hi, world' }

    对于ES6module
    // a.mjs let a = "hello, world"; export {a}// b.mjs import {a} from './a.mjs' a = "hi, world" console.log(a); // 报错,Assignment to constant variable.

    因为ES6module导出的是引用,默认导出的是const变量,所以禁止更改其值,修改了则报错.
解决循环引用 1 CommonJS中采用了缓存,对于已经一个模块,require()函数先去缓存中寻找是否已经加载,如果加载了直接从缓存中取; 否则先缓存该模块,再去执行,(注意顺序) 有了缓存很好的解决了循环引用的问题。
如下例子存在main.js c.js d.js三个文件, c和d互相引用,main引用c和d
// c.js let d = require('./d'); console.log("这是c"); // d.js let c = require('./c') console.log("这是d"); // main.js let c = require('./c') let d = require('./d') console.log("这是main"); // 结果 // 这是d // 这是c // 这是main // 而且发现d仅执行了一次,验证了缓存的说法, 当执行到c的第一行的时候,c已经被缓存了,进入d执行第一行的时候,是从缓存中取的c,此时c只是被缓存了还未被执行。

【CommonJS和ES6module的异同】2 ES6module对于循环引用会报错。

    推荐阅读