CommonJS模块化


一、Node.js模块化

1.node.js模块类型

  node.js模块类型常见的分为三块:

内置模块:如fs、http模块等。。
用户自定义模块:用户自己编写的js文件
第三方模块:如通过npm包管理工具导入的第三方由node.js内置模块封装出来的,用以提高开发效率的

2.加载模块

require()方法

  使用require()方法,用以加载各种模块进行使用

// 加载内置文件系统模块fs
const fs = require('fs');

// 加载用户自定义模块
const ownModule = require('./ownModule.js');

// 加载通过npm安装的第三方日期模块dayjs
const dayjs = require('dayjs');

3.向外共享模块作用域中的成员

module对象

  在每个用户自定义模块的.js文件中都有一个module对象,它里面存储了该模块有关的信息。
  通过在自己创建的文件customModule.js中打印module对象输出如下信息:

PS C:\Users\林木木\Desktop\node\模块化\自定义模块> node .\customModule.js
Module {
  id: '.',
  path: 'C:\\Users\\林木木\\Desktop\\node\\模块化\\自定义模块',
  exports: {},
  filename: 'C:\\Users\\林木木\\Desktop\\node\\模块化\\自定义模块\\customModule.js',
  loaded: false,
  children: [],
  paths: [
    'C:\\Users\\林木木\\Desktop\\node\\模块化\\自定义模块\\node_modules',
    'C:\\Users\\林木木\\Desktop\\node\\模块化\\node_modules',
    'C:\\Users\\林木木\\Desktop\\node\\node_modules',
    'C:\\Users\\林木木\\Desktop\\node_modules',
    'C:\\Users\\林木木\\node_modules',
    'C:\\Users\\node_modules',
    'C:\\node_modules'
  ]
}

  可见每个自定义模块的module对象中都包含id(模块标识符)、loaded(模块是否加载完成)、path(模块的搜索路径)等属性,我们将重点信息放在它的exports属性上

module.exports对象

  module的exports属性也是一个对象,我们可以通过module.exports对象,将自定义模块内的部分成员共享出去,供外界使用

在模块customModule.js中定义如下:

// 该成员和方法不打算共享出去,具有模块作用域,只能在该模块内访问,避免全局污染
let fruit = "Apple";
function sayName(f) {
  return f
}
sayName(fruit);

// 该成员和方法将在后面共享出去
let hobby = 'basketball';
function sayHobby(h) {
  return h;
}
sayHobby(hobby);

// 通过mudule.exports,向外共享成员hobby及方法sayHobby
module.exports = {
  hobby,
  sayHobby
}

在外部通过require()方法加载该模块:

const customModule = require('./customModule.js');
console.log(customModule);      // { hobby: 'basketball', sayHobby: [Function: sayHobby] }

exports对象

  Node提供了exports对象,在默认情况下,exports和module.exports指向同一个对象

console.log(exports === module.exports);    // true

  But:最终共享的结果,以module.exports指向的对象为准

在模块exportsObj.js中定义如下:

// exports和module.exports指向同一个对象,最终以module.exports暴露的对象为准
exports.address = 'zzuli';
exports.sayAddress = function () {
    return this.address;
}
module.exports = {
    name: 'lmm'
}

在外部通过require()方法加载该模块:

const exportObj = require('./exportsObj.js');
console.log(exportObj);     // { name: 'lmm' }

4.module.exports与exports的使用误区

  若执意要在同一模块中同时使用module.exports和exports两个对象,共享模块内成员时,将有一下几种情况:

情况一:

// 向外共享 { gender: '男', age: '21'};
exports.username = 'lmm';
module.exports = {
    gender: '男',
    age: 21
}

解释:重写了module.exports对象,也就是module.exports指向了另外一个对象,而exports仍旧指向原来的对象,此时两者不指向同一个对象,根据最终共享的结果,以module.exports指向的对象为准,向外共享 { gender: ‘男’, age: ‘21’}

情况二:

// 向外共享 { address: 'zzuli'};
module.exports.address = 'zzuli';
exports = {
    height: '172',
    weight: '130'
}

解释:重写了exports对象,也就是exports指向了另外一个对象,而module.exports仍旧指向原来的对象,此时两者不指向同一个对象,根据最终共享的结果,以module.exports指向的对象为准,向外共享 { address: ‘zzuli’}

情况三:

// 向外共享 { hobby: 'code', good: 'PingPong'};
exports.hobby = 'code';
module.exports.good = 'PingPong'

解释:此时两者都未重写,仍然指向同一个对象根据最终共享的结果,以module.exports指向的对象为准(此时也包括exports指向的对象),向外共享{ hobby: ‘code’, good: ‘PingPong’}

情况四:

// 向外共享 { sport: 'basketball', fruit: 'Apple', drink: 'Cola'};
exports = {
    sport: 'basketball',
    fruit: 'Apple'
}
module.exports = exports;
module.exports.drink = 'Cola';

解释:重写了exports对象后exports指向新的对象,但后续又修改了module.exports指向的对象为exports指向新的对象,因此二者仍然指向同一个对象,同理,根据最终共享的结果,以module.exports指向的对象为准(此时也包括exports指向的对象),向外共享{ sport: ‘basketball’, fruit: ‘Apple’, drink: ‘Cola’}

由此建议:不要再同一个模块中同时使用module.exports对象和exports对象

二、CommonJS模块化规范

  Node.js遵循了CommonJS模块化规范:规定了模块的特征和各模块之间如何相互依赖
CommonJS规定:

1.每个模块内部,module变量代表当前模块
2.module变量是一个对象,它的exports属性(module.exports)是对外的接口;
3.通过require()加载某个模块,其实是加载该模块的module.exports属性

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JV_32

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值