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

相关推荐
1024小神3 分钟前
Cocos游戏开发中,检测两个物体碰撞,并实现物理反弹逻辑
前端·javascript
拾光拾趣录5 分钟前
Vue Router 执行顺序
前端·vue.js·vue-router
前端权6 分钟前
Vue3 多行文本溢出隐藏与展开收起功能实现总结
前端·vue.js
用户3802258598246 分钟前
vue3源码解析:调度器
前端·vue.js
一一一87116 分钟前
javaScript数据存储, 对象和原型与原型链
javascript
Dolphin_海豚29 分钟前
electron windows 无边框窗口最大化时的隐藏边框问题
前端·electron·api
梦想CAD控件32 分钟前
WEB CAD与Mapbox结合实现在线地图和CAD编辑(CGCS2000)
前端·javascript·vue.js
WTSolutions1 小时前
Excel 转 JSON by WTSolutions API 文档
javascript
AverageJoe19911 小时前
一次vite热更新不生效问题排查
前端·debug·vite