nodejs学习(一)概念和相关介绍

一.Node.js简介

- node是一款对ES标准实现的JS引擎
	- 通过node可以使js在服务器中运行
	- node就是一款使用js编写的web服务器
	- node底层是使用c++的编写的
	- node的中js引擎使用的chrome的v8引擎
	- node的特点:
		1.非阻塞、异步的I/O(当执行i/操作时,不会阻塞线程)
		2.事件和回调函数(当事件触发,执行传递过去的回调函数)
		3.单线程(主线程单线程,后台I/O线程池)
		4.跨平台

二.node目录结构

 

三.模块相关

  1.模块引用和分类

• 在规范中,定义了require()方法,这个方法接手模块标识,以此将一个模块引入到当前运行环境中。
• 模块引用的示例代码:   –
var math = require('math');

    分类:

核心模块

- http、fs、path、url、net、os、readline、......
- 核心模块在Node.js自身源码编译时,已经编译成二进制文件
- 部分核心模块在Node.js进程启动的时候已经默认加载到缓存里面了

文件模块

- 文件模块可以是:*.js 模块、*.node模块、*.json模块,这些都是文件模块
- 无论从npm上下载的第三方模块还是我们自己编写的模块都是文件模块

 

  2.模块定义和加载

• 在运行环境中,提供了exports对象用于导出当前模块的方法或者变量,并且它是唯一的导出的出口。

• 在模块中还存在一个module对象,它代表模块自身,而exports是module的属性。

• 在Node中一个文件就是一个模块。

• 从npm上下载的一个包(可能是由多个文件组成的一个实现特定功能的包)也是一个模块

• 任何文件或目录只要可以被Node.js通过`require()`函数加载的都是模块

• 每个模块就是一个独立的作用域,模块和模块之间不会互相"污染"

• 我们可以通过编程的方式,指定某个模块要对外暴露的内容(其实就是指定require的返回值,通过require的返回值对外暴露指定内容)。
这个对外暴露内容的过程也叫
"导出" `module.exports`

   加载

1.无论是核心模块还是文件模块加载都是采用`require('标识符')`来加载
2.核心模块的加载速度是最快的
3.无论是 核心模块 还是 文件模块,加载过一次后都会缓存起来,第二次加载(第二次require)的时候直接从缓存中读取即可。
所以模块中的代码只在第一次加载的时候执行一次,这点要注意。 3.核心模块只能通过
"模块名称" 来加载,例如:`require('模块名称')` 4.文件模块可以通过 require 指定路径的方式来加载(路径可以是文件路径 或 目录)   - `require('./a/b.js')` 通过指定相对路径来加载模块   - `require('/a/b.js')` 或 `require('c:\a\b.js')` 通过指定绝对路径来加载   - 注意:`require('')`加载模块的时候,相对路径永远相对于当前模块,不受node命令执行的路径影响。 5.通过路径的方式加载文件模块时,文件的后缀可有可无
  
- 省略后缀名后,Node.js默认会以:.js、.node、.json的顺序来加载(依次拼接不同的后缀,查找并尝试加载)。   - 建议:始终加上后缀。
6.模块的加载是同步的

  注意:

require 加载模块时做了2件事

1. 执行了模块中的代码
2. 返回了模块中对外暴露的内容(可能是对象、函数等等)

   3.模块使用

    使用方法:

方法一:
- 导出变量和函数 - 使用 exports - 例子:   exports.属性 = 属性值;   exports.方法 = 函数;
方法二: - 使用module.exports - 例子:   module.exports.属性 = 属性值;   module.exports.方法 = 函数;   module.exports = {};

     关于module.exports 和 exports

1.在每个模块中module表示当前模块对象, 里面保存了当前模块对象的各种信息

2.module.exports 其实就是 require()加载模块时的返回值

3. exports 就是module.exports的一个引用
    exports = module.exports;

特别注意:最终暴露给require的返回值的是:module.exports, 而不是exports

  源码:

 // To illustrate(说明) the behavior, imagine this hypothetical implementation of require(), which is quite similar to what is actually done by require():

  function require(...) {
  var module = { exports: {} };


  ((module, exports) => {
    // Your module code here. In this example, define a function.
    function some_func() {};
    exports = some_func;
    // At this point, exports is no longer a shortcut to module.exports, and
    // this module will still export an empty default object.
    module.exports = some_func;
    // At this point, the module will now export some_func, instead of the
    // default object.
  })(module, module.exports);

  
  return module.exports;
}

 

  示例:

  被导入的模块: 2.js

/*
	模块化
		- 在Node中,一个js文件就是一个模块
		- 在Node中,每一个js文件中的js代码都是独立运行在一个函数中
			而不是全局作用域,所以一个模块的中的变量和函数在其他模块中无法访问
 */

//这种打印的在导入的时候就会被运行 console.log("我是一个模块,我是02.module.js"); /* 我们可以通过 exports 来向外部暴露变量和方法 只需要将需要暴露给外部的变量或方法设置为exports的属性即可 * */ //向外部暴露属性或方法(只有这样,导入模块的代码才能访问当前(被导入)模块的方法和变量) exports.x = "我是模块2的x"; exports.y = "我是模块2的y"; exports.fn = function xx () { };

  导入模块的代码: 3.js

//引入其他的模块
/*
	在node中,通过require()函数来引入外部的模块
		require()可以传递一个文件的路径作为参数,node将会自动根据该路径来引入外部模块
		这里路径,如果使用相对路径,必须以.或..开头

	使用require()引入模块以后,该函数会返回一个对象,这个对象代表的是引入的模块

	我们使用require()引入外部模块时,使用的就是模块标识,我们可以通过模块标识来找到指定的模块
	- 模块分成两大类
		核心模块
			- 由node引擎提供的模块
			- 核心模块的标识就是,模块的名字
		文件模块
			- 由用户自己创建的模块
			- 文件模块的标识就是文件的路径(绝对路径,相对路径)
				相对路径使用.或..开头

 */
var md = require("./2");
var math = require("./math");
var fs = require("fs");

console.log(md);
console.log(math.add(123,456));
//console.log(fs);

  exports 和 module.exports的区别:

  helloModule.js

/*
module.exports.name = "孙悟空";
module.exports.age = 18;
module.exports.sayName = function () {
	console.log("我是孙悟空~~~");
};*/


module.exports  = {
	name:"猪八戒",
	age:28,
	sayName:function () {
		console.log("我是猪八戒");
	}
};

  test.js

var hello = require("./helloModule");

/*
	exports 和 module.exports
		- 通过exports只能使用.的方式来向外暴露内部变量
			exports.xxx = xxx

		- 而module.exports既可以通过.的形式,也可以直接赋值
			module.exports.xxx = xxxx
			module.exports = {}
 */

console.log(hello.name);
console.log(hello.age);
hello.sayName();

  

 

  4.模块标识

• 模块标识其实就是模块的名字,也就是传递给require()方法的参数,它必须是符合驼峰命名法的字符串,或者是以.、 ..开头的相对路径、或者绝对路径。

  5.模块的实现

• Node中虽然使用的是CommonJS规范,但是其自身也对规范做了一些
舍。

• 在Node中引入模块,需要经历如下3个步骤:
  – 路径分析
  – 文件定位
  – 编译执行

• 在Node中,模块分为三类:一类是底层由C++编写的内建模块,一类Node提供的核心模块;
还有一类是用户编写的模块,称为文件模块。

  说明:

var a = 10;

/*
	在node中有一个全局对象 global,它的作用和网页中window类似
		在全局中创建的变量都会作为global的属性保存
		在全局中创建的函数都会作为global的方法保存

	当node在执行模块中的代码时,它会首先在代码的最顶部,添加如下代码
 			function (exports, require, module, __filename, __dirname) {

 	在代码的最底部,添加如下代码
 			}

 	实际上模块中的代码都是包装在一个函数中执行的,并且在函数执行时,同时传递进了5个实参
		 exports
		 	- 该对象用来将变量或函数暴露到外部

		 require
		 	- 函数,用来引入外部的模块

		 module
		 	- module代表的是当前模块本身
		 	- exports就是module的属性
		 	- 既可以使用 exports 导出,也可以使用module.exports导出

		 __filename
 			- 当前模块的完整路径

	  	 __dirname
 			- 当前模块所在文件夹的完整路径

* */
//console.log(global.a);

/*
	arguments.callee
		- 这个属性保存的是当前执行的函数对象
* */
console.log(arguments.callee + "");
console.log(arguments.length);

console.log(exports);
console.log(module.exports == exports);

console.log(__dirname);

  

  6.包结构

• 包实际上就是一个压缩文件,解压以后还原为目录。符合规范的目录,应该包含如下文件:
– package.json 描述文件
– bin 可执行二进制文件
– lib js代码
– doc 文档
– test 单元测试

  7.包描述文件

• 包描述文件用于表达非代码相关的信息,它是一个JSON格式的文件 – package.json,位于包的根目录下,是包的重要组成部分。
• package.json中的字段 – name、 description、 version、 keywords、maintainers、 contributors、 bugs、licenses、 repositories、 dependencies、homepage、
os、 cpu、 engine、 builtin、directories、 implements、 scripts、 author、bin、 main、 devDependencies。

   8.NPM(Node Package Manager)

• CommonJS包规范是理论,NPM是其中一种实践。

• 对于Node而言,NPM帮助其完成了第三方模块的发布、安装和依赖等。借助NPM,Node与第三方模块之间形成了很好的一个生态系统。

  9.NPM命令

• npm –v
  – 查看版本
• npm
  – 帮助说明
• npm search 包名
  – 搜索模块包
• npm install 包名
  – 在当前目录安装包
• npm install 包名 –g
  – 全局模式安装包

 • npm remove 包名
  – 删除一个模块
 • npm install 文件路径
  – 从本地安装
 • npm install 包名 –registry=地址
  – 从镜像源安装
 • npm config set registry 地址
  – 设置镜像源

 

   读取控制台输入:

var readline = require('readline');

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});


rl.question('what is your name? \n', function (answer) {
  console.log('okay, you are ' + answer + '. thank you!');
  rl.close();
})

  

posted @ 2022-03-18 15:01  阿布_alone  阅读(73)  评论(0编辑  收藏  举报
TOP