Node.js教程-模块化

什么是模块化

模块化指为了解决一个复杂问题,自顶向下把系统逐层划分为若干个模块的过程。对于整个系统来说,模块是可以组合、分解和更换的单元。
代码进行模块化的好处:

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

模块化规范

模块化规范就是对代码进行模块化拆分组合时需遵从的规则。如:

  1. 引用模块的语法
  2. 在模块中向外暴露的语法格式
    模块化规范的好处: 开发人员遵从同样的模块化编写代码,降低了沟通的成本,极大的方便了各个模块间的相互调用。

Node.js 模块化

为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。模块是Node.js应用程序的基本组成部分,文件和模块是一一对应的,即一个Node.js对应一个模块。每个文件都有自己的作用域,在一个文件中定义的变量函数都是私有的,对其他文件不可见,这样可以防止全局变量被污染。
Node.js应用由模块组成,模块遵从CommonJS规范。CommonJS规范规定,每个模块内部,module变量代表当前模块,其为一个对象,它的exports属性(module.exports)向外暴露。加载某个模块,其实就是加载该模块的module.exports的值。

var x = 1
var add = function(a,b){
return a + b
}

// 暴露
module.exports.x = x
module.exports.add = add

// 引入模块
var xxx = require("xxx")
console.log(xxx.x)  // 1
console.log(xxx.add(1,2))  // 3

CommonJS模块特点:

  • 所有代码都运行在模块作用域,不会污染全局作用域
  • 模块可以多次加载,但只会在第一次加载时运行一次。第一次完成加载后即被缓存
  • 模块加载的顺序按照代码编写的顺序加载

分类

Node.js中根据模块来源不同,将模块分为三大类:

  1. 内置模块 内置模块由Node.js官方提供,如:fshttppath
  2. 自定义模块 开发人员编写的js文件
  3. 第三方模块 由第三方开发出来的模块,使用前需先下载

共享

每个模块内部都有一个module对象,其 存储了当前模块的有关信息


/**
{
  id: '.',
  path: 'D:\\studyspace\\code\\node\\node_001',
  exports: {},
  filename: 'D:\\studyspace\\code\\node\\node_001\\index.js',
  loaded: false,
  children: [],
  paths: [
    'D:\\studyspace\\code\\node\\node_001\\node_modules',    
    'D:\\studyspace\\code\\node\\node_modules',
    'D:\\studyspace\\code\\node_modules',
    'D:\\studyspace\\node_modules',
    'D:\\node_modules'
  ]
}
*/
console.log(module)

在自定义模块中,可以使用module.exportsexports将模块中的成员、方法对外暴露,供外界使用。(使用require()引入模块时,得到用于是module.exports 指向的对象)

console.log(module.exports)  // {}

const age = 10

// 向 module.exports 对象上挂载 age 属性
module.exports.age = age

// 向 module.exports 对象上挂载 name 属性
module.exports.name = '张三'

// 向 module.exports 对象上挂载 sayHi 方法
module.export.sayHi = function(){
	console.log('Hi, Node.js')
}

注意:exports不能直接指向一个值

加载

使用require()即可加载需要的模块。require命令的基本功能是,读入并执行一个JS文件,然后返回该模块的exports对象。

// 加载内置模块
const fs = require('fx')

// 加载自定义模块(可以省略 .js 的后缀名)
const xxx = require('./xxx.js')

// 加载第三方模块(使用前需下载该模块)
const moment = require('moment')

注意:模块第一次加载后会被缓存,即多次调用require()引入同一模块,不会导致该模块中的代码被执行多次,提高了模块加载效率。

模块的加载机制

Node.js 加载模块流程图
Node.js教程-模块化_第1张图片

内置模块的加载机制

内置模块是由Nolde.js官方提供的模块,内置模块的加载优先级最高

自定义模块的加载机制

加载自定义模块时,必须指定以.//开头的路径标识符,否则Node.js会将其当做内置模块第三方模块
若在引入模块时,省略了.js扩展名,则Node.js会按以下顺序加载文件(找到即返回,最终没有找到就报错):

  1. 按照确切的文件名进行加载
  2. 补全.js扩展名进行加载
  3. 补全.json扩展名进行加载
  4. 补全.node扩展名进行加载
第三方模块的加载机制

加载第三方模块,模块路径无须以.//开头。Node.js会从当前模块的父目录开始,尝试从其node_modules文件夹中加载其模块;若没有找到则移动到再上一层的node_modules文件夹中加载,其次类推,直到找到为止。

目录作为模块

当把目录作为模块标识符,传递给**require()**进行加载时,有三种加载方式:

  1. 在被加载的目录下找到一个 package.json的文件,并寻找main属性,其值作为require()加载的入口
  2. 若目录下没有package.json文件,或main入口不存在或无法解析,则Node.js尝试加载目录下的index.js文件
  3. 若以上两步都失败了,则抛出Error: Cannot find module 'xxx'

你可能感兴趣的:(node.js)