Node.js(三)——模块化

一、什么是模块化

模块化是在解决复杂问题的时候,把系统自顶向下拆分成若干模块的过程,对于整个系统来说,模块是可组合、分解和更换的单元。

编程中的模块化就是遵守固定的规则,把一个大文件拆分成独立且互相依赖的多个小模块。

1.模块化的好处:

  • 提高了代码的可维护性
  • 提高了代码的复用性
  • 可以实现按需加载

2.模块化规范的规则:

使用统一的规则方便各大模块的互相调用(使用什么语法来引入或者向外暴露)

二.node.js中的模块化

1.node.js模块的分类

  • 内置模块(fs、path、http)
  • 自定义模块(用户创建的每个js文件都是自定义模块,js在node里跑就是自定义模块,在浏览器跑就是普通js文件。用module.exports、require这些都是遵循的node规则)
  • 第三方模块(第三方开发出来的模块,使用之前需要先下载,npm的那些,什么axios、jquery这些都是)

内置和自定义的都在自己电脑上,第三方的就需要先下载才能使用,这是他们的区别

2.模块的加载

使用强大的require(),可以引入内置、自定义、第三方的模块进行使用

复制代码
const fs=require('fs')
const clock=require('./clock.js')
const moment=require('moment')

只有自定义模块需要路径

使用require加载其他模块的时候,会执行被加载模块中的代码

使用require加载自定义模块的时候,js后缀可以省略

3.node.js的模块作用域

与函数作用域相似,模块作用域里定义的变量和方法只能在当前模块被访问,这种模块级别的访问限制叫模块作用域。(只能在自己文件访问自己的变量和方法)

模块作用域的好处:防止全局变量被污染

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

1.module对象

每个自定义模块都有一个module对象,他存储了当前模块有关的信息

比如我们随便创建一个js文件,然后打印一下它里面的module

复制代码
console.log(module)

2.module.exports对象

从上面的截图可以看到exports默认是一个空对象,在自定义模块中,module.exports可以将模块中的成员共享出去供外界使用。然后外界使用require引入这个模块之后就可以拿到这个模块exports指向的对象。

module.exports默认是空对象,当module2文件里什么都没有的时候,a输出的是{},也就是mudule2中的module.exports对象

复制代码
const a=require('./module2.js')

console.log(a)

如果我们想共享一些东西出去的话,就只需要给mudule2中的module.exports对象赋值即可,比如:

复制代码
module.exports={
  username:'hh',
  sayHi(){
    console.log('aa')
  }
}

这里面写什么,require输出得到的就是什么,引入的文件输出:

我这里犯了一个错误,这里输出结果是aa undefined,我最开始纳闷undefined是哪来的,再一看发现console.log一个函数的话会先调用这个函数,然后打印出它的返回值

复制代码
const a=require('./module2.js')

console.log(a.sayHi())

就等同于下面这样,运行完a.sayHi()(这个过程会输出aa),然后把结果赋值给了result(没有return就是undefined)然后输出

复制代码
const a=require('./module2.js')

const result=a.sayHi()

console.log(result)

或者用module.exports.username='aa'这种方式赋值也可以

3.exports对象

由于module.exports对象写起来比较复杂,node提供了exports对象,默认情况下,exports对象就等同于module.exports,不过还是以module.exports指向的对象为准。

注意:require()得到的永远都是module.exports指向的对象

复制代码
// Node.js 每个模块开始前,会悄悄执行这两行
var module = { exports: {} }
var exports = module.exports   // exports 是 module.exports 的引用

所以像下面这个require得到的就是name 'hh',而不是那一大坨

复制代码
module.exports.name='hh'

exports={
  username:'hh',
  sayHi(){
    console.log('aa')
    return '88'
  }
}

在第一句执行完之后module.exports.name='hh',exports和module.exports都指向name 'hh'这个对象,然后下面的赋值让exports指向了别的对象,所以别的模块去require的时候得到的东西就跟exports无关了,所以建议不要在一个模块中用两种写法。

其实就只要记住这俩最开始指向一个对象,最后require得到的是module.exports指向的对象就可以了。

四.Node.js中的模块化规范

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

CommonJS规定:

  • 每个模块内部,module变量代表当前模块
  • module变量是一个对象,他的exports属性(即module.exports)是对外的接口
  • 加载某个模块,其实是加载该模块的moudle.exports属性,require()方法用于加载该模块
相关推荐
米丘2 天前
vite8 vite preview 命令做了什么?
node.js·vite
blanks20203 天前
生成 公钥私钥 笔记
node.js
糖拌西瓜皮4 天前
Java开发者视角:深入理解Node.js异步编程模型
java·后端·node.js
智通5 天前
Node.js事件循环核心机制
node.js
初圣魔门首席弟子5 天前
Node.js 详细介绍(知识库版)
windows·qt·node.js·知识库
糖拌西瓜皮5 天前
Java 开发者如何快速上手 Node.js:一份从入门到进阶的学习路线
node.js
yspwf5 天前
NestJS 配置管理完整方案
后端·架构·node.js
网络点点滴5 天前
Node.js事件驱动架构
架构·node.js
weixin_471383035 天前
Node.js + Express 入门实战笔记-01-基础
node.js·lua·express
Rain5096 天前
2.2 数据基础:数据库集成与 ORM(TypeORM / Prisma)
数据库·人工智能·ai·数据分析·node.js·自动化·ai编程