CommonJS与ESM

CommonJS的产生

CommonJS 由 Mozilla 工程师 Kevin Dangoor 于 2009 年 1 月创立,最初命名为ServerJS。2009 年 8 月,该项目更名为CommonJS。旨在解决 Javascript 中缺少模块化标准的问题。

Node.js 后来也采用了 CommonJS 的模块规范。

module与require

在CommonJS中,module与require并非js关键字,而是一个对象与函数,这可以去打印看看

js 复制代码
console.log(module)

{
  id: '.',
  path: '/Users/xx/code/test-code',
  exports: {},
  filename: '/Users/xx/code/test-code/s.cjs',
  loaded: false,
  children: [],
  paths: [
    '/Users/xx/code/test-code/node_modules',
    '/Users/xx/code/node_modules',
    '/Users/xx/node_modules',
    '/Users/node_modules',
    '/node_modules'
  ]
}

console.log(require)
[Function: require] {
  resolve: [Function: resolve] { paths: [Function: paths] },
  main: {
    id: '.',
    path: '/Users/xx/code/test-code',
    exports: {},
    filename: '/Users/xx/code/test-code/s.cjs',
    loaded: false,
    children: [],
    paths: [
      '/Users/zhutao/code/test-code/node_modules',
      '/Users/zhutao/code/node_modules',
      '/Users/zhutao/node_modules',
      '/Users/node_modules',
      '/node_modules'
    ]
  },
  extensions: [Object: null prototype] {
    '.js': [Function (anonymous)],
    '.json': [Function (anonymous)],
    '.node': [Function (anonymous)]
  },
  cache: [Object: null prototype] {
    '/Users/xx/code/test-code/s.cjs': {
      id: '.',
      path: '/Users/xx/code/test-code',
      exports: {},
      filename: '/Users/xx/code/test-code/s.cjs',
      loaded: false,
      children: [],
      paths: [Array]
    }
  }
}

我们可以看到两个对象,其中的module.exports是module下面的一个对象 exports只是module.exports下面的引用

所以当module.exports与exports同时存在时,只会导出module.exports

js 复制代码
//s.cjs
module.exports = {
  name: 1,
};
exports = {
  age: 1,
};
//或者
exports = {
  age: 1,
};

module.exports = {
  name: 1,
};

//a.cjs
const modu = require("./s.cjs");
console.log(modu); //{ name: 1 }

同样,exports改变指针指向也会导致导出失效,

所以exports只能以exports.xx = xx;的方式导出

js 复制代码
// s.cjs
exports = {
  age: 1,
};
//a.cjs
const modu = require("./s.cjs");
console.log(modu); //{}



// s.cjs
exports.name = {
  age: 1,
};
//a.cjs
const modu = require("./s.cjs");
console.log(modu); //{ name: { age: 1 } }

但使用exports.xx =xx;后上下文都有module.exports = {} 讲改变指针指向,原本的exports将失去导出效果

language 复制代码
//只有module.exports生效 既然导出对象只有name没有age
module.exports = {
  name: 1,
};
exports.age = 12;

ESM

在ESM中import与export 与export default 是一对关键字

并且ESM模块解析是发生在编译阶段,而CommonJS是发生在运行阶段,这个很好理解,CommonJS本身就是函数,既然是函数就要运行时进行解析。

区别

  1. 二者最外层this指向不一样,Common.js指向exports ESM指向undefined。

最外层this也能导出,但遇到使用module.exports改变指向时会失去效果 2. ESM没有__dirname与__filename

相关推荐
岁岁种桃花儿29 分钟前
Vue核心语法第十一篇:绑定样式
前端·javascript·vue.js
程序员黑豆8 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
To_OC9 小时前
踩了个 TS 的坑之后,我终于把 type 和 interface 掰明白了
前端·react.js·typescript
GreenTea9 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
浮生望9 小时前
前端API工程化:用 Mock 数据与 Axios 配置实现独立于后端的并行开发
前端
万少10 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
波波00710 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
Brown.alexis11 小时前
es6知识点1-自备使用
前端·ecmascript·es6
小爬的老粉丝12 小时前
JavaScript 纯前端预览 WPS:先识别容器,再路由解析器
前端·javascript·wps