详细讲一下CommonJS 和 ES6 Module 的区别

我们闲言少叙,直接开始来了解一下他们的多种区别,希望能帮到大家!

1. 语法差异

​
// CommonJS
// 导出
module.exports = {
    hello: function() {},
    name: 'value'
};
// 或
exports.hello = function() {};
exports.name = 'value';

// 导入
const { hello, name } = require('./module');
// 或
const module = require('./module');


// ES6 Module
// 导出
export function hello() {}
export const name = 'value';
// 或
export default {
    hello: function() {},
    name: 'value'
};

// 导入
import { hello, name } from './module';
// 或
import * as module from './module';
import module from './module';  // 默认导入

​

2. 加载时机

// CommonJS - 运行时加载
const data = require('./data.js');
if (condition) {
    const dynamicModule = require('./dynamic.js');
}

// ES6 Module - 静态加载(编译时)
import data from './data.js';  // 必须在顶层
// if (condition) {
//     import module from './module.js';  // ❌ 错误
// }

// ES6 动态导入
if (condition) {
    import('./dynamic.js').then(module => {
        // 使用 module
    });
}

3. 值的拷贝 vs 引用

// CommonJS - 值的拷贝
// module.js
let counter = 0;
module.exports = {
    counter: counter,
    increment: function() {
        counter++;
    }
};

// main.js
const module = require('./module');
console.log(module.counter);  // 0
module.increment();
console.log(module.counter);  // 0(不会改变,因为是拷贝)


// ES6 Module - 值的引用
// module.js
export let counter = 0;
export function increment() {
    counter++;
}

// main.js
import { counter, increment } from './module';
console.log(counter);  // 0
increment();
console.log(counter);  // 1(会改变,因为是引用)

4. 循环依赖处理

// CommonJS
// a.js
console.log('a starting');
exports.done = false;
const b = require('./b.js');
console.log('in a, b.done =', b.done);
exports.done = true;
console.log('a done');

// b.js
console.log('b starting');
exports.done = false;
const a = require('./a.js');
console.log('in b, a.done =', a.done);
exports.done = true;
console.log('b done');

// 输出:
// a starting
// b starting
// in b, a.done = false
// b done
// in a, b.done = true
// a done


// ES6 Module
// a.mjs
console.log('a starting');
export let done = false;
import { done as bDone } from './b.mjs';
console.log('in a, b.done =', bDone);
done = true;
console.log('a done');

// b.mjs
console.log('b starting');
export let done = false;
import { done as aDone } from './a.mjs';
console.log('in b, a.done =', aDone);
done = true;
console.log('b done');

5. 异步加载

// CommonJS
// 同步加载
const fs = require('fs');
const data = fs.readFileSync('file.txt');

// ES6 Module
// 支持异步加载
const loadModule = async () => {
    const module = await import('./dynamic-module.js');
    module.doSomething();
};

6. 主要区别总结: 

1.语法差异

 // CommonJS
   const module = require('./module');
   module.exports = { /* ... */ };

   // ES6 Module
   import module from './module';
   export default { /* ... */ };

2.加载机制

   // CommonJS - 运行时加载
   const dynamic = condition ? require('./a') : require('./b');

   // ES6 Module - 静态加载
   import module from './module';  // 必须在顶层

3.值的处理

   // CommonJS - 值的拷贝
   exports.counter = 0;
   exports.increment = () => exports.counter++;

   // ES6 Module - 值的引用
   export let counter = 0;
   export const increment = () => counter++;

4.模块对象

   // CommonJS
   module.exports = {
       // 导出对象
   };

   // ES6 Module
   export {
       // 导出绑定
   };

5.this 指向 

  // CommonJS
   console.log(this);  // {} (模块对象)

   // ES6 Module
   console.log(this);  // undefined

6.文件扩展名

   // CommonJS
   require('./module');  // 可以省略 .js

   // ES6 Module
   import './module.js';  // 必须带扩展名

现代项目通常推荐使用 ES6 Module,因为它提供了更好的静态分析能力和树摇(tree-shaking)支持。希望大家看完这篇文章之后会对CommonJS和ES6 Module有一个新的理解,建议大家收藏且反复观看!

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值