请说说commonJS模块与ES模块的差异有哪些?

CommonJS 模块和 ES 模块是 JavaScript 中两种不同的模块系统,它们在语法、执行时机、动态导入等方面存在显著差异。

1. 语法:

  • CommonJS: 使用 require() 同步加载模块,使用 module.exportsexports 导出模块成员。

    // 模块A
    const add = (a, b) => a + b;
    module.exports = { add };
    
    // 模块B
    const { add } = require('./moduleA'); 
    
  • ES 模块: 使用 import 语句导入模块,使用 export 语句导出模块成员。

    // 模块A
    export const add = (a, b) => a + b;
    
    // 模块B
    import { add } from './moduleA';
    

2. 执行时机:

  • CommonJS: 模块加载和执行是同步的。require() 会阻塞代码执行,直到模块加载完成。这意味着 CommonJS 模块的执行顺序与它们在代码中出现的顺序一致。

  • ES 模块: 模块加载和执行是异步的。import 语句不会阻塞代码执行,浏览器会在后台加载模块。ES 模块的执行顺序取决于模块之间的依赖关系和浏览器的加载策略。 所有导入的模块都会在当前模块的顶层作用域之前执行。

3. 动态导入:

  • CommonJS: 支持动态导入,但需要使用 require(),并且是同步的。

    const modulePath = './module' + someVariable;
    const myModule = require(modulePath);
    
  • ES 模块: 支持动态导入,使用 import() 函数,并且是异步的,返回一个 Promise。

    const modulePath = './module' + someVariable;
    import(modulePath).then(module => {
        // 使用 module
    });
    

4. 顶层作用域:

  • CommonJS: 每个模块都有自己的顶层作用域。在一个模块中定义的变量、函数等不会污染全局作用域,也不会被其他模块直接访问,除非显式导出。

  • ES 模块: ES 模块的顶层作用域是共享的。这意味着在 ES 模块顶层声明的变量、函数等,在其他导入该模块的地方是可见的,类似于全局变量。 但是,ES 模块的设计理念仍然鼓励尽可能地使用 exportimport 来管理模块之间的依赖关系,而不是依赖共享的顶层作用域。

5. 兼容性:

  • CommonJS: 主要用于 Node.js 环境,浏览器端需要使用构建工具(如 Webpack、Browserify)进行转换。

  • ES 模块: 是 JavaScript 的标准模块系统,现代浏览器都原生支持 ES 模块。

总结:

特性 CommonJS ES 模块
语法 require(), module.exports, exports import, export
执行时机 同步 异步
动态导入 require() (同步) import() (异步)
顶层作用域 模块私有 模块共享 (但建议使用 export/import)
兼容性 Node.js 现代浏览器

选择哪种模块系统取决于你的项目环境和需求。 对于新的前端项目,推荐使用 ES 模块,因为它更现代化,性能更好,并且是 JavaScript 的标准。 对于 Node.js 项目,CommonJS 仍然是主流,但 ES 模块的支持也越来越好。 许多项目会混合使用两种模块系统,尤其是在过渡阶段。

posted @   王铁柱6  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示