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 小时前
从0到1实现 Balatro 游戏后端(1):项目规划与牌型判断实现
后端·websocket·typescript·node.js·游戏开发·项目实战·nestjs
@PHARAOH2 小时前
WHAT - npm和corepack
前端·npm·node.js
MPGWJPMTJT2 小时前
从 Volta 迁移到 mise:Windows 下 Node 版本管理切换记录
前端·node.js
zhangfeng11332 小时前
Remotion 渲染视频脚本 ,自动化编辑视频 Node.js 层面是“单线程 JS”,但在实际渲染时是“高度并行”的。
node.js·自动化·音视频
羽师3 小时前
Node.js和npx关系
node.js
灵魂学者3 小时前
使用 Electron 打包项目构建 .EXE 桌面应用程序(简)
electron·node.js·vue·build·桌面应用程序
右耳朵猫AI3 小时前
Node.js技术周刊 2026年第14周
node.js
gogoing17 小时前
Node.js 模块查找策略(require 完整流程)
javascript·node.js
zhangfeng113318 小时前
小龙虾 wordbuddy 安装浏览器控制器 agent-browser npm install -g agent-browse
前端·人工智能·npm·node.js