Node.js 中的模块化机制——CommonJS

文章介绍了Node.js中的模块特性,包括模块作用域,确保未导出的变量对外不可见。模块在首次加载后会被缓存,避免重复执行。模块加载分为内置、自建和第三方,且有特定的查找顺序。模块导出主要通过`module.exports`或`exports`,允许覆盖或逐个设置导出内容。
摘要由CSDN通过智能技术生成

模块特性

具有模块作用域,模块中没有暴露导出的变量或对象无法被外部访问。模块内的代码被执行,产生实例,便会独立运行下去,直到模块代码运行结束,所有操作都在模块内部上下文运行。

// 调用者
const run = require('./running')
run.start()

setTimeout(() => {
  run.reset()
}, 6000)

// 被调用者
var cnt = 0
var clockId = null

function start() {
  clockId = setInterval(() => {
    console.log(++cnt);
  }, 1000)
}

function reset() {
  clearInterval(clockId)
}

module.exports = {
  start,
  reset
}

会一直执行计时器,直到被调用reset

模块加载

执行命令require时,就会加载一次模块内的所有代码,并返回模块对象。模块具有三种类型: 

// 系统内置模块
const http = require('http')

// 自建模块
const my_module = require('./my_module')

// 第三方模块
const monent = require('monent')

模块在第一次加载后会被缓存,多次调用require不会导致模块的代码被多次执行。无论那种模块,都会先从缓存中加载。

// 子模块 sub.js
var shared = { a: 1 }
module.exports = { shared }

// 调用者
let run1 = require('./sub')
let run2 = require('./sub')
run1.shared === run2.shared		// true

模块加载也有优先级,其中内置模块优先级最高,第三方模块优先级低。自定义模块不参与比较,因为自定义模块采用路径引用,不会发生冲突。
对于自定义模块模糊查询(省略后缀),查找文件顺序依次是 xxx - xxx.js - xxx.json -xxx.node
采用目录加载方式,先查找package.json中的main属性入口,如果没有找到,则加载目录价index.js文件,若仍然失败,打印错误。

|-module
	|-package.json
  	|-a.js
// package.json
{
  "main": "./a.js"
}

// 调用者
require('./module')

 模块导出

每个js模块都有一个module对象,该对象有个exports属性,即是暴露的模块内容。

Module {
  id: '.',
  path: 'R:\\Node\\module',
  exports: { start: [Function: start], reset: [Function: reset] },
  parent: null,
  filename: 'R:\\Node\\module\\running.js',
  loaded: false,
  children: [],
  paths: [
  'R:\\Node\\module\\node_modules',
  'R:\\Node\\node_modules',
  'R:\\node_modules'
  ]
}

而调用模块的变量其实就指向exports,因此我们有两种模块导出方式

// 方法一:全覆盖
module.exports = { 
  XXX: XXX,
	YYY: YYY
}
// 方法二:逐个设置
module.exports.XXX = XXX
module.exports.YYY = YYY

为了方便编码,node提供了一个新的对象exports,指向的也是module.exports,只要不采用全覆盖的方式导出变量(改变了指向),两者就指向相同对象。
无论如何改变,导出时的对象只锁定为module.exports,require只识别module.exports 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值