Node.js的特性
(1) Nodejs语法完全是js语法,只要你懂js基础就可以学会Nodejs后端开发。
(2) Node.js超强的高并发能力,能够实现高性能服务器。
(3) 开发周期短、开发成本低、学习成本也低
2. 浏览器和Node.js环境对比
在Chrome浏览器环境中,V8引擎用于解析JS代码,而Blink引擎是浏览器的排版引擎,用于处理网页的html、css和DOM操作。
而Node环境中,只有V8引擎,用于处理JS代码,所以Node.js中,访问DOM和BOM是无法实现的。但Node.js因为有libuv中间层加持,能够实现浏览器所不能实现的一些功能。
Node.js 可以解析JS代码(没有浏览器安全级别的限制)提供很多系统级别的API
CommonJS规范
在node.js环境中,默认支持模块系统,该模块系统遵循CommonJs规范。
一个 JavaScript 文件就是一个模块,在模块文件中定义的变量和函数默认只能在模块文件内部使用,如果需要在其他文件中使用,必须显式声明将其进行导出。
CommonJS模块规范主要分为模块导出(也叫模块定义)、模块引用两个部分。
模块导出(module.exports或exports)
CommonJS中定义模块的规定: 我们把公共功能抽离成一个单独的js文件作为一个模块。默认情况下,里面的方法和属性是外面无法访问的。如果想要让外面能够访问到里面的属性和方法,就必须要通过 module.exports
或exports
暴露属性和方法。
在每一个模块文件中,都会存在一个 module 对象,即模块对象。在模块对象中保存了和当前模块相关信息。
在模块对象中有一个属性 exports,它的值是一个对象,模块内部需要被导出的成员都应该存储在到这个对象中。
可以用module.exports
给test.js模块系统添加属性:
或者用exports
给test.js模块系统添加属性:
或者用module.exports = { }
把属性组合成一个对象后导出:
模块导入(require) 在其他文件中通过 require
方法引入模块,require 方法的返回值就是对应模块的 module.exports
对象。在导入模块时,模块文件后缀 .js 可以省略,文件路径不可省略。
(1) require 方法属于同步导入模块,模块导入后可以立即使用。 (2) 导入其他模块时,建议使用 const 关键字声明,防止模块被重置。 我们创建一个require.js文件,里面导入上面的test.js:
会发现打印的第二个module的children属性会多一些信息:
2. npm包管理工具的用法详解
npm介绍:npm是世界上最大的开放源代码的生态系统,我们可以通过npm下载各种包。npm是随同Node.js一起安装的包管理工具,能解决Node.js代码部署上的很多问题。
常见的使用场景有以下几种 (1) 允许用户从NPM服务器下载别人编写的第三方包到本地使用。 (2) 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。 (3) 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。
npm常用命令 初始化项目:
npm init --yes
复制
使用 npm 命令安装模块:
npm install 包名@版本号
复制
全局安装与本地安装:
npm install 包名 # 本地安装
npm install 包名 -g # 全局安装
复制
查看所有全局安装的模块:
npm list -g
复制
卸载模块:
npm uninstall 包名
复制
更新模块:
npm update 包名
复制
package.json 和 package-lock.json 区别
(1) package.json 是在运行 “ npm init ”时生成的,主要记录项目依赖,主要有以下结构:
name:项目名,也就是在使用npm init 初始化时取的名字. main:入口文件,一般都是 index.js description:描述信息,有助于搜索。 version:版本号。 keywords:关键字,有助于在人们使用 npm search搜索时发现你的项目。 scripts:支持的脚本,默认是一个空的 test。 license :默认是 MIT。 dependencies:指定了项目运行时(生产环境)所依赖的模块。 devDependencies:指定项目开发时所需要的模块,也就是在项目开发时才用得上,一旦项目打包上线了,就将移除这里的第三方模块。
(2) package-lock.json 是在运行 “npm install” 时生成的一个文件,用于记录当前状态下项目中实际安装的各个 package 的版本号、模块下载地址、及这个模块又依赖了哪些依赖。
为什么有了package.json,还需要 package-lock.json 文件呢?
当项目中已有 package-lock.json 文件,在安装项目依赖时,将以该文件为主进行解析安装指定版本依赖包,而不是使用 package.json 来解析和安装模块。 因为 package 只是指定的版本不够具体,而package-lock 为每个模块及其每个依赖项指定了安装的版本,位置和完整性哈希,所以它每次创建的安装都是相同的。 无论你使用什么设备,或者将来安装它都无关紧要,每次都应该给你相同的结果。
npm install安装模块时的一些选项
使用npm install安装依赖时,可以使用--save
和--save-dev
。
使用--save
安装的依赖,安装的包会被写到package的dependencies属性里面去。dependencies 是运行时依赖(生产环境),可以简化为参数 -S
。
而使用--save-dev
则添加到 package.json 文件 devDependencies 键下,devDependencies 是开发时的依赖。即 devDependencies 下列出的模块,是开发时用的 ,生产环境会移除,可以简化为参数 -D
。
版本号的命名规则
在 Node.js 中所有的版本号都有3个数字:x.y.z。 第一个数字是主版本。第二个数字是次版本。第三个数字是补丁版本。
^
:只会执行不更改最左边非零数字的更新。 如果写入的是 ^0.13.0,则当运行 npm update 时,可以更新到 0.13.1、0.13.2 等,但不能更新到 0.14.0 或更高版本。 如果写入的是 ^1.13.0,则当运行 npm update 时,可以更新到 1.13.1、1.14.0 等,但不能更新到 2.0.0 或更高版本。 ~
:如果写入的是 〜0.13.0,则当运行 npm update 时,会更新到补丁版本:即 0.13.1 可以,但 0.14.0 不可以。 >
:接受高于指定版本的任何版本。 >=
:接受等于或高于指定版本的任何版本。 <=
:接受等于或低于指定版本的任何版本。 <
:接受低于指定版本的任何版本。 =
:接受确切的版本。 -
:接受一定范围的版本。例如:2.1.0 - 2.6.2。 ||
:组合集合。例如 < 2.1 || > 2.6。
三.Node.js的常用内置模块
下面开始总结Node.js的内置模块了,如果你是入门学习的话,推荐按照本文顺序来学,学习思路会更清晰。如果你只是要查阅相关模块的用法,可以从目录索引导航到那一个模块。
1. http模块
http模块是 Node.js 网络的关键模块。可以使用以下代码引入:
const http = require('http')
复制
该模块提供了一些属性、方法、以及类。我们要学习的就是一些常用的属性、方法、以及类的使用。
常用方法:
(1) http.createServer()
:用于返回 http.Server 类的新实例。 用法:
const server = http.createServer((req, res) => {
//使用此回调处理每个单独的请求。
})
复制
(2) http.request()
:用于发送 HTTP 请求到服务器,并创建 http.ClientRequest 类的实例。
(3) http.get()
:类似于 http.request()
,但会自动地设置 HTTP 方法为 GET,并自动地调用 req.end()
。
常用属性:
(1) http.METHODS
:此属性列出了所有支持的 HTTP 方法。像什么GET、POST、DELETE等等。
const http=require('http');
console.log(http.METHODS)
(2) http.STATUS_CODES
:此属性列出了所有的 HTTP请求的状态代码及其描述。
const http=require('http');
console.log(http.STATUS_CODES)
常用类: HTTP 模块提供了5 个很常用的类,分别如下: (1) http.Agent
:Node.js 会创建 http.Agent
类的全局实例,以管理 HTTP 客户端连接的持久性和复用,这是 Node.js HTTP 网络的关键组成部分。该对象会确保对服务器的每个请求进行排队并且单个 socket 被复用,它还维护一个 socket 池。
(2) http.ClientRequest
:当 http.request()
或 http.get()
被调用时,会创建 http.ClientRequest
对象。当响应被接收时,则会使用响应(http.IncomingMessage
实例作为参数)来调用 response 事件。返回的响应数据可以通过以下两种方式读取:
- 可以调用 response.read() 方法。
- 在 response 事件处理函数中,可以为 data 事件设置事件监听器,以便可以监听流入的数据。
(3) http.Server
: 当使用 http.createServer()
创建新的服务器时,通常会实例化并返回此类。拥有服务器对象后,就可以访问其方法:
close()
停止服务器不再接受新的连接。listen()
启动 HTTP 服务器并监听连接。
(4) http.ServerResponse
:由 http.Server 创建,并作为第二个参数传给它触发的 request 事件。通常在代码中用作 res:
const server = http.createServer((req, res) => {
//res 是一个 http.ServerResponse 对象。
})
复制
这个类的以下这些方法用于与 HTTP 消息头进行交互:
方法名 | 作用 |
---|---|
getHeaderNames() | 获取已设置的 HTTP 消息头名称的列表。 |
getHeaders() | 获取已设置的 HTTP 消息头的副本。 |
setHeader(‘headername’, value) | 设置 HTTP 消息头的值。 |
getHeader(‘headername’) | 获取已设置的 HTTP 消息头。 |
removeHeader(‘headername’) | 删除已设置的 HTTP 消息头。 |
hasHeader(‘headername’) | 如果响应已设置该消息头,则返回 true。 |
headersSent() | 如果消息头已被发送给客户端,则返回 true。 |
在处理消息头之后,可以通过调用 response.writeHead()
(该方法接受 statusCode
作为第一个参数,可选的状态消息和消息头对象)将它们发送给客户端。
若要在响应正文中发送数据给客户端,则使用 write()
。 它会发送缓冲的数据到 HTTP 响应流。
如果消息头还未被发送,则使用 response.writeHead()
会先发送消息头,其中包含在请求中已被设置的状态码和消息,可以通过设置 statusCode
和 statusMessage
属性的值进行编辑:
response.statusCode = 500
response.statusMessage = '内部服务器错误'
复制
(5) http.IncomingMessage
该类的对象可通过这两种方式创建:http.Server
,当监听 request 事件时。http.ClientRequest
,当监听 response 事件时。
它可以用来访问响应: 使用 statusCode
和 statusMessage
方法来访问状态。 使用 headers
方法或 rawHeaders
来访问消息头。 使用 method
方法来访问 HTTP 方法。 使用 httpVersion
方法来访问 HTTP 版本。 使用 url
方法来访问 URL。 使用 socket
方法来访问底层的 socket。
2. http模块简单案例实践
创建一个server.js,我们一点一点来用这个http模块:
const http=require('http')
// 创建服务器
http.createServer((req,res)=>{
//接收浏览器传的参数,返回渲染的内容,都在这个回调函数里面来做
//req是接收的浏览器的参数,res是返回给浏览器渲染的内容。
}).listen(3000,()=>{
console.log("server start")
})
/* listen()方法的第一个参数是端口号,第二个参数是一个回调函数,这个回调函数是服务器创建成功后执行的函数 */
复制
命令行运行node server.js
,会看到server start打印在控制台了,并且光标在闪动,这表示服务创建成功,并监听了这个服务。现在浏览器访问http://localhost:3000/,浏览器还访问不到任何东西,因为我们没有返回任何数据。
我们可以在createServer()
的回调里面调用res.write()
对浏览器进行输出,res.write()
可以调用多次,都会输出在浏览器上。但要注意,最后一定要掉用res.end()。不然浏览器会一直等,直到超时。