Node学习-03

90 阅读3分钟

Node学习-03

Node中的模块系统

使用Node编写应用程序主要就是在使用:

  • ECMPScript
  • 核心模块 (fs, http, path, url ...)
  • 第三方模块 (art-template ...)
  • 自己写的模块

什么是模块化?

  • 文件作用域 (每个文件的变量具有单独的作用域,不会产生冲突)
  • 通信规则(导入、导出)

CommonJS模块规范

  • 模块作用域

  • 使用require方法来加载模块

  • 使用exports接口来导出模块

    • 导出多个成员:必须在对象中

      exports.a = 111;
      exports.b = 222;
      exports.c = 333;
      
    • 导出单个成员:拿到的就是函数、字符串。。。

      module.exports = 'hello';
      
      或者 
      // 通过导出一个对象的方式来导出多个成员
      module.exports = {
      	
      }
      

foo.js

var foo = 'bar';

function add(x, y) {
	return x + y;
}

exports.add = add;

或者

// 如果某个模块需要直接导出某个成员,而非通过挂载的方式,这个时候需要使用module.exports重新赋值
module.exports = add; // 这种方法可以直接拿到函数

Main.js

var fooExports = require('./foo');

console.log(fooExports);
console.log(fooExports.add(10, 20)); // 30

exports和module.exports的区别

在Node中,每个模块内部都有一个自己的module对象,该module对象内部,有一个成员:exports

var module = {
	exports: {
	
	}
}

module.exports.foo = 'bar';
module.exports.add = function (x, y) {
  return x + y;
} 
...
为了简化操作:
var exports = module.exports;
console.log(exports === module.exports); // true


// 默认在代码的最后有一句:
return module.exports;
  • exports是module.exports的一个简写,引用的是同一个对象

  • 但是为module.exports赋值的话,就会替换原对象

    exports.foo = 'aaa';
    
    module.exports = { foo: 'bbb' };
    

Q: 为什么导出单个对象时一定要module.exports='aaa'而不能exports='aaa'?

A: 是因为exports只是module.exports对象的一个引用,最后return出去的是module.exports,当exports赋值为另一个值时,只是将exports的引用指向了另外一个对象,而不会改变module.exports

优先从缓存加载

a.js

console.log('a被加载了');
require('./b.js');

b.js

console.log('b被加载了');

main.js

require('./a.js');
require('./b.js');

在这个过程中,b.js不会被重复加载,而是优先从缓存中进行加载,并且可以拿到接口对象

require标识符

require('模块标识符')
  • 核心模块的标识符:reuqire('fs') require('http')

    核心模块的本质也是文件,核心模块文件已经被编译到二进制文件中了,只需要按照名字加载即可

  • 路径形式的模块: ./xxx ../xxx /xxx 开头,并且不可以省略,但是.js后缀名可以省略

  • 第三方模块: 比如art-template, require('art-template'),第三方包的名字不能和核心模块的名字一样

    require('art-template')时:

    1. 先找当前文件所属目录中的node_modules目录

    2. 然后找到node_modules/art-template目录

    3. 再去找node_modules/art-template/package.json文件

    4. 再找到这个文件中的main.js(入口文件)属性,如果没有package.json或没有指定,则默认找index.js文件

    5. main.js指向了一个index.js

    6. 如果以上所有任何一个条件都不成立,则会进入上一级目录中的node_modules目录查找,。。。直到当前磁盘的根目录还找不到,则报错

NPM-Node Package Manager

包描述文件: package.json

初始化package.json: npm init

npm常用命令

// 查看版本
npm --version 

// 升级npm
npm install --global npm 

// 跳过向导,快速生成
npm init -y

// 安装
npm install
npm install 包名
// 在package.json文件中产生依赖项
npm install --save 包名

// 删除
npm uninstall 包名
// 同时删除依赖项
npm uninstall --save 包名

// 查看使用帮助
npm --help 

// 查看指定命令的帮助
npm uninstall --help

被墙问题-cnpm

// 安装
npm install --global cnpm

// npm替换成cnpm
cnpm install --save art-template

或者设置代理

npm config set registry https://registry.npm.taobao.org

// 验证,查看npm 配置信息
npm config list
npm install --save art-template