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()方法用于加载该模块
相关推荐
陳陈陳1 天前
🚀 前端流式输出革命:SSE + BFF 架构从零到一实战指南
vue.js·架构·node.js
Revolution611 天前
第一次运行 Node.js:终端里的 JavaScript 怎样执行
后端·面试·node.js
半句唐诗1 天前
我是如何通过 Access Token 成功发布第一个 npm 包的
前端·npm·node.js
贩卖黄昏的熊1 天前
NestJS简明教程——异常处理和日志
javascript·node.js·nest.js
Revolution611 天前
Node.js 是什么:前端项目里哪些事情由它完成
前端·面试·node.js
Revolution611 天前
Nest.js 是什么:怎样用它写出第一个后端接口
后端·node.js·nestjs
柳林林1 天前
解决 nvm 切换 Node.js 版本时报“没有文件扩展 ‘.vbs’ 的脚本引擎”错误
node.js
To_OC2 天前
从 0 到 1:Milvus + 大模型打造私人记忆知识库
人工智能·node.js·llm
孟陬2 天前
介绍 Node.js v22 新增的 `toArray` 方法
node.js·deno·bun
卡兹墨2 天前
针对高并发、数据量大的场景,通常会考虑采用分库分表进行优化。在这篇文章,我们重点盘点一下Node.js主流ORM框架的动态分表方案 ...
node.js