NodeJS(二)——模块与包管理工具

N o d e J s 中 的 模 块 化 \color{blue}{NodeJs中的模块化} NodeJs

Node 应用由模块组成,采用 CommonJS 模块规范。
CommonJS 就是模块化的标准, nodejs 就是 CommonJS( 模块化) 的实现。
✌️✌️✌️

  • 模 块 的 分 类 : \color{navy}{模块的分类:} :
    • 核心模块
      • 核心模块指的是那些被编译进Node的二进制模块
      • 预置在Node中,提供Node的基本功能,如fs、http、https等
      • 核心模块使用C/C++实现,外部使用JS封装
    • 文件模块
      • 文件可放在任何位置
      • 加载模块文件时加上路径即可
    • 第三方模块
      • Node使用npm(Node Package Manager)安装第三方模块
      • npm会将模块安装(可以说是下载到)到应用根目录下的node_modules文件夹中
      • 模块加载时,node会先在核心模块文件夹中进行搜索,然后再到node_modules文件夹中进行搜索
    • 文件夹模块
      • Node首先会在该文件夹中搜索package.json文件
        • 存在,Node便尝试解析它,并加载main属性指定的模块文件
        • 不存在(或者package.json没有定义main属性),Node默认加载该文件夹下的index.js文件(main属性其实NodeJS的一个拓展,CommonJS标准定义中其实并不包括此字段)
      • 文件夹模块的例子
        • 在根目录下的/main.js中,我们需要使用一个自定义文件夹模块。

        • 将所有的自定义文件夹模块存放在根目录下的/module下,其中有一个/module/demo文件夹,是我们需要引入的文件夹模块;

        • 文件夹目录

          |——main.js
          |——module
          \qquad |—— demo
          \qquad\qquad |—— package.json
          \qquad\qquad |—— demo.js

        • package.json文件的信息如下:

          {
           	"name": "demo",
          	"version": "6.0.0",
          	"main": "./demo.js"
          }
          
        • main.js中:

          	let demo = require("./modules/demo");
          
        • Node将会根据package.json中指定的main属性,去加载./module/demo/demo.js

        • 这就是一个最简单的包,以一个文件夹作为一个模块。✌️✌️✌️

  • C o m m o n J S ( N o d e j s ) 中 自 定 义 模 块 的 规 定 : \color{navy}{CommonJS( Nodejs) 中自定义模块的规定:} CommonJSNodejs:
    • 我们可以把公共的功能抽离成为一个单独的 js 文件作为一个模块, 默认情况下面这个模块里面的方法或者属性, 外面是没法访问的。如果要让外部可以访问模块里面的方法或者属性, 就必须在模块里面通过 exports 或者 module.exports 暴露属性或者方法。
      在这里插入图片描述
    • 在需要使用这些模块的文件中, 通过 require 的方式引入这个模块,这个时候就可以使用模块里面暴露的属性和方法。 ✌️✌️✌️
  • C o m m o n J S 定 义 的 模 块 分 为 : \color{navy}{CommonJS定义的模块分为: } CommonJS:
    • 模块引用(require)
    • 模块定义(exports)
    • 模块标识(module)
  • 定 义 使 用 模 块 \color{navy}{定义使用模块} 使
    1.新建文件test.js,代码如下:
//模块定义
var tools = {
    sayHello: function() {
        return 'hello World!';
    },

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

// 模块接口的暴露
	//方法一
 	module.exports = tools;
 	//方法二
	//exports.sayHello = tools.sayHello;
	//exports.add = tools.add;

2.新建文件common.js,代码如下:

//模块的引用
const tools = require('./test');  //引用自定义的模块时, 在同一个目录下用 "./" 
const http = require('http');    //引入http模块
const hostname ='127.0.0.1';    //服务器地址
const port = 8888;             //服务器的端口号
const server = http.createServer((request,response)=>{   //使用http来创建服务器
    response.statusCode=200; 
    if(request.url!=='/favicon.ico'){
        response.setHeader('Content-Type','text/html;charset=utf-8');
        //模块的调用
        response.write("<br/>"+tools.sayHello()+"<br/>"); 
        //write()函数的参数必须是字符串类型
        response.write(tools.add(15,26).toString());
        response.end();
    } 
});
//监听 
server.listen(port,hostname,()=>{
    console.log(`Server running at http://${hostname}:${port}/`);
});

3.浏览器访问:localhost:8888
4.结果:hello World!
41
✌️✌️✌️

包 管 理 工 具 \color{blue}{包管理工具}

node.js是基于CommonJS的规范实现的,npm大家一定都很熟悉,它实践了CommonJS的包规范。

  • 包 规 范 \color{navy}{包规范}
    关于包规范,类比于git仓库,我们可以这么理解:
    • git init在当前文件夹中生成了隐藏文件.git,我们把它叫做git仓库。
    • npm init命令在当前文件夹中生成了配置文件package.json,它描述了当前这个包,我们管这个文件叫做包(概念不准确,可以这么理解)。
  • 包 结 构 \color{navy}{包结构}
    严格按照CommonJS规范来的话,包的目录应当包含以下文件或目录。
    • package.json:包描述文件,存在于包顶级目录下。是一个配置文件,它描述了包的相关信息。
    • bin:存放可执行二进制文件的目录
    • lib:存放js代码的目录
    • doc:存放文档的目录
  • m o d u l e 属 性 \color{navy}{module属性} module
    • m o d u l e . i d \color{aqua}{module.id} module.id 模块的识别符,通常是带有绝对路径的模块文件名。
    • m o d u l e . f i l e n a m e \color{aqua}{module.filename} module.filename 模块的文件名,带有绝对路径。
    • m o d u l e . l o a d e d \color{aqua}{module.loaded} module.loaded 返回一个布尔值,表示模块是否已经完成加载。
    • m o d u l e . p a r e n t \color{aqua}{module.parent } module.parent 返回一个对象,表示调用该模块的模块。
    • m o d u l e . c h i l d r e n \color{aqua}{module.children} module.children 返回一个数组,表示该模块要用到的其他模块。
    • m o d u l e . e x p o r t s \color{aqua}{module.exports} module.exports 表示模块对外输出的值。
      案例
      • 新建文件夹Node:mkdir Node

      • 终端进入文件夹:cd Node

      • 安装jquery来做测试:npm install jquery

      • 新建js文件:touch jquery.js

        |— —Node
        \qquad |— —node_module
        \qquad |— —package.json
        \qquad |— —jquery.js

      • jquery文件代码如下:

        	var jquery = require('jquery');
        	exports.$ = jquery;
        	console.log(module);        //module就是当前模块内部中的一个对象,代表当前对象
        
      • 终端执行:node jquery

      • 终端命令行输出的信息如下所示:

        	Module {
        		  id: '.',             //模块的识别符,通常是带有绝对路径的模块文件名
        		  exports: { '$': [Function] },     //表示模块对外输出的值
        		  parent: null,       //返回一个对象,表示调用该模块的模块
        		  filename: '/Users/anna/Node/jquery.js',   // 模块的文件名,带有绝对路径
        		  loaded: false,     // 返回一个布尔值,表示模块是否已经完成加载
        		  children:          //返回一个数组,表示该模块要用到的其他模块
        		   [ Module {
        		       id: '/Users/anna/Node/node_modules/jquery/dist/jquery.js',
        		       exports: [Function],
        		       parent: [Circular],
        		       filename: '/Users/anna/Node/node_modules/jquery/dist/jquery.js',
        		       loaded: true,
        		       children: [],
        		       paths: [Array] 
        		      }
        		   ],
        			  paths:
        			   [ '/Users/anna/Node/node_modules',
        			     '/Users/anna/node_modules',
        			     '/Users/node_modules',
        			     '/node_modules' 
        			    ] 
        	}
        

        可以看到,当前这个模块的parent属性为null,这证明当前这个模块是一个入口脚本,
        如果在jquery.js中引入别的文件模块,module会输出什么??? ???

      • 新建js文件:child.js

      • child.js里面的代码如下:

        	var str = "I'm NodeJs";
        	exports.str = str;
        	console.log(module);
        
      • 修改jquery.js中的代码:

        	var jquery = require('jquery');
        	var child=require('./child');   //在jquery中引入child模块
        	exports.$ = jquery;
        	console.log(module);  
        
      • 终端继续执行:node jquery

      • 终端命令行输出的信息如下:

        	Module {
        		  id: '/Users/anna/Node/child.js',
        		  exports: { str: 'I\'m NodeJs' },
        		  parent:
        		   Module {
        		     id: '.',
        		     exports: {},
        		     parent: null,
        		     filename: '/Users/anna/Node/jquery.js',
        		     loaded: false,
        		     children: [ [Module], [Circular] ],
        		     paths:
        		      [ '/Users/anna/Node/node_modules',
        		        '/Users/anna/node_modules',
        		        '/Users/node_modules',
        		        '/node_modules' ] },
        		  filename: '/Users/anna/Node/child.js',
        		  loaded: false,
        		  children: [],
        		  paths:
        		   [ '/Users/anna/Node/node_modules',
        		     '/Users/anna/node_modules',
        		     '/Users/node_modules',
        		     '/node_modules' ] }
        	Module {
        	  id: '.',
        	  exports: { '$': [Function] },
        	  parent: null,
        	  filename: '/Users/anna/Node/jquery.js',
        	  loaded: false,
        	  children:
        	   [ Module {
        	       id: '/Users/anna/Node/node_modules/jquery/dist/jquery.js',
        	       exports: [Function],
        	       parent: [Circular],
        	       filename: '/Users/anna/Node/node_modules/jquery/dist/jquery.js',
        	       loaded: true,
        	       children: [],
        	       paths: [Array] },
        	     Module {
        	       id: '/Users/anna/Node/child.js',
        	       exports: [Object],
        	       parent: [Circular],
        	       filename: '/Users/anna/Node/child.js',
        	       loaded: true,
        	       children: [],
        	       paths: [Array] } ],
        	  paths:
        	   [ '/Users/anna/Node/node_modules',
        	     '/Users/anna/node_modules',
        	     '/Users/node_modules',
        	     '/node_modules' ] }
        
      • 总结

        • child.js中的parent属性输出的是jqueryTest.js的module信息,
        • jqueryTest.js中的children属性,包括了jquery和child.js两个module信息
        • jqueryTest.js中的parent属性为null;
        • S o \color{red}{So} So,我们可以以module.parent来判断当前模块是否是入口脚本
          ✌️✌️✌️✌️✌️✌️
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值