CommonJS模块化规范

CommonJS

  • 主要实践者: Node
  • 包含四个环境变量: module exports require global
  • CommonJS是同步加载模块
  • 适合场景:
    • 服务端读取本地磁盘非常快, 所以很适合该规范
    • 而浏览器端受限网络, 更适合异步加载

CommonJS模块导出

// app.js

// 一个一个导出
module.exports.name = "Tom";
module.exports.say = function(){
  console.log("say something")
}

// 整体导出
var name = "Tom";
function say(){
  console.log("say something")
}
module.exports = {
  name: name,
  say: say
}

CommonJS模块导入

// main.js

// 导入
const app = require('./app'); // 可以省略文件后缀
console.log(app.name)
console.log(app.say())

exports 和 module.exports的区别

  1. node执行一个文件时, 会生成一个exports和module对象
  2. 而module又有一个exports属性, 他们都指向一块内存区域 exports === module.exports
  3. 当添加exports.a=200, module.exports同时享有属性a
  4. 最终require()导入的是module.exports
  5. 可以看出exports是辅助module.exports操作内存中的数据用的;
  • 建议: 为了防止混乱, 不推荐使用exports, 建议只使用module.exports

require详解

当Node执行遇到require(x)

  1. 如果x是核心模块: 如require(‘fs’)

    • 返回该模块
  2. 如果x以”./“,”/“,”../“开头

    • 根据x所在父模块, 确定x的绝对路径

    • 将x当成文件, 依次查找下面文件

      x
      x.js
      x.json
      x.node
    • 如果没找到, 则把x当成目录, 依次查找下面的文件

      x/package.json(main字段)
      x/index.js
      x/index.json
      x/index.node
  3. 如果x不带路径, 并且也不是核心模块

    • 根据x所在父模块(也就是使用require(x)的模块), 确认x可能的安装目录
    • 依次在每个目录下, 将x当前文件名和目录名从node_modules目录下加载
// require常见用法
const fs = require('fs'); // 核心模块
const math = require('./math'); // 自定义模块, 当前目录下的math.js文件
const vue = require('vue'); // node_modules目录下的第三方包