Node.js模块化系统基础

模块概念

  • 一个js文件就是一个模块
  • Node 中没有全局作用域,一个模块就是一个独立的环境
  • Node 中的模块默认是不能相互访问的

核心模块

  • 由Node提供的封装了API的具名模块
    • fs : 文件处理模块
    • http : 网络服务构建模块
    • os : 系统服务模块
    • . . . . . .

导入导出模块(让模块之间可以相互访问)

导入

通过 require()来加载并执行指定的模块,返回对应模块中的exports对象

const customModuleName = require('module');

require()加载规则

  • 优先从缓存加载: 加载过的模块再次请求加载时不会重复加载,会从缓存中找到之前加载的模块,将模块的导出的结果返回
  • 判断模块的标识(require()的参数):
    • 核心模块: 模块标识就是核心模块的的名称。
    • 用户自定义模块: 路径形式+模块名称,Node会根据模块是否包含路径形式的字符来判断加载的是否是用户自定义的模块。当前路径也要 加 ./
    • 第三方模块: 模块标识是此模块报名。Node在判断当前此模块非核心模块后会在当前目录下查找 node_modules目录,再在其中找到对应包名的目录,然后找到该目录中的package.json文件,找到main属性所指定的入口文件,然后加载这个入口文件。(如果该属性没有值,则会将index.js文件作为默认备选项)。如果当前目录下没有node_modules或者其之下没有对应包名的目录,就会到上一层去找,直到磁盘根目录,如果还找不到就报错。一般将一个node_modules放在项目根目录下,并且不会再有其他node_modules目录了

导出

在Node中,每个模块默认都有一个module的对象,这个对象中有一个exports对象

let module = {
	exports:{
		...
	}
}

这个exports对象用于我们将模块中需要导出的东西进行导出

let foo = 'bar';
let fn = function(){...};
module.exports.foo = foo;
module.exports.fn = fn;

默认在每一个模块最后都有一个retutn module.exports的语句来将我们设置的东西导出
不过Node还提供了一个exports对象,可以让我们不用点得太深

let foo = 'bar';
let fn = function(){...};
exports.foo = foo;
exports.fn = fn;

效果和module.exports相同,实际上这两个东西是一样的

module.exports === exports;//true
//in fact
let exports = module.exports;

因此二者指向的是同一个空间
有时我们希望直接导出某个数据对象,如直接导出一个函数,对象…,而不是导出一个exports。先来看一下错误的做法

let fn = function(){...};
exports = fn;

由于直接赋值改变了exports的指向,指向了fn但是模块最终返回的是module.exports,所以对exports的操作不会影响到最终返回的结果。

正确的做法

let fn = function(){...};
module.exports = fn;

PS:如果分不清楚的话,可以选择忘记exports而使用module.exports

注意: Node内部采用的是UTF-编码,不会发生中文乱码的情况,但是返回数据到前端时则需要设置Content-Type

你可能感兴趣的:(Node)