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

相关推荐
yume_sibai3 分钟前
HTML HTML基础(4)
前端·html
给月亮点灯|22 分钟前
Vue基础知识-Vue集成 Element UI全量引入与按需引入
前端·javascript·vue.js
三思而后行,慎承诺40 分钟前
Reactnative实现远程热更新的原理是什么
javascript·react native·react.js
知识分享小能手43 分钟前
React学习教程,从入门到精通,React 组件生命周期详解(适用于 React 16.3+,推荐函数组件 + Hooks)(17)
前端·javascript·vue.js·学习·react.js·前端框架·vue3
面向星辰1 小时前
html音视频和超链接标签,颜色标签
前端·html·音视频
lxh01131 小时前
LRU 缓存
开发语言·前端·javascript
yangzhi_emo1 小时前
ES6笔记5
前端·笔记·es6
wow_DG2 小时前
【Vue2 ✨】Vue2 入门之旅 · 进阶篇(二):虚拟 DOM 与 Diff 算法
开发语言·javascript·vue.js·算法·前端框架
Hexene...2 小时前
【前端Vue】el-dialog关闭后黑色遮罩依然存在如何解决?
前端·javascript·vue.js·elementui·前端框架