初学Node.js(1)

142 阅读13分钟

Node.js简介

1.浏览器是JavaScript的前端运行环境。

2.Node.js是javascript的后端运行环境。

3.Node.js中无法调用DOM和BOM等浏览器内置API

Node.js可以做什么

Node.js作为一个JavaScript的运行环境,仅仅提供了基础的功能和API。然而,基于Node.js提供的这些基础能,很多强大的工具和框架如雨后春笋,层出不穷,所以学会了Node.js,可以让前端程序员胜任更多的工作和岗位。

1.基于Express框架,可以快速构建web应用。

2.基于electron框架,可以构建跨平台的桌面应用。

3.基于restify框架,可以快速构建API接口项目。

4.读写和操作数据库、创建实用的命令行工具辅助前端开发、etc

怎么学

JavaScript基础语法 +Node.js内置API模块(fs、path、http等)+第三方API(express、mysql)

准备工作

如何安装

安装包可以从Node.js的官网首页直接下载,进入到Node.js的官方首页(nodejs.org/en/) ,点击绿色的按钮,下载所需的版本后,双击直接安装即可。

如何执行

在Node.js环境中执行javascript代码

1.打开终端

2.输入node要执行的js文件的路径

3.node +文件名执行

ps:终端命令cd +path 或者 在当前文件shift +鼠标右键打开power shell终端

实际开发用到的语句

fs文件系统模块

fs模块是Node.js官方提供的、用来操作文件的模块,它提供了一系列的方法和属性。用来满足用户对文件的操作需求。

fs.readFile()方法,用来读取指定文件中的内容。

fs.writeFile()方法,用来向指定的文件中写入内容

如果要在JavaScript代码中,使用fs模块来操作文件,则需要使用如下的方式先导入它:const fs = require('fs')

fs.readFile(path,[option],callback)

参数解读:

参数1:必选参数,字符串,表示文件的路径。

参数2:可选参数,表示以什么编码格式来读取文件。

参数3:必选参数,文件读取完成后,通过回调函数拿到读取的结果。

callback回调函数中有两个参数(err,win)

如果成功,err为null ,为成功对象

如果失败,win为undifinded,err为错误对象

fs.writeFile(file,data,[option],callback)

参数解读

1.参数1:必选参数,需要指定一个文件路径的字符串,表示文件的存放路径。

参数2:必选参数,表示要写入的内容。

参数3:可选参数,表示以什么格式写入文件内容,默认值是utf8

参数4:必选参数,文件写入完成后的回调函数。

callback回调函数中的err

1.如果文件写入成功,则err的值等于null

2.如果文件写入失败,则err的值等于一个错误对象

fs模块-路径动态拼接的问题

在使用fs模块操作文件时,如果提供的操作路径是以./或../开头的相对路径时,很容易出现路径动态拼接错误的问题.

原因:代码在运行的时候,会以执行node命令时所处的目录,动态拼接出被操作文件的完整路径。

解决方案:

  1. 在使用fs模块操作文件时,直接提供完整的路径,不要提供./或../开头的相对路径,从而防止路径动态拼接的问题。但是移植性非常的差,不利于维护

  2. 采用__dirname(表示当前文件所处的目录)+'路径' 进行拼接。

什么是path路径模块

path 模块是Node.js官方提供的、用来处理路径的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理需求。

例如:

path.join()方法,用来将多个路径片段拼接成一个完整的路径字符串。

path.basename()方法,用来从路径字符串中,将文件名解析出来。

//如果在JavaScript代码中,使用path模块来处理路径,则需要使用如下的方式先导入它

const path =require('path');

path.join()的语法格式

使用path.join([...paths])

参数解读:

  1. ...paths路径片段的序列

  2. 返回值 < string >

//要先引入join的方法
const path = require('path')
const pathStr =path.join('/a','/b/c','../','./d','e')

console.log(pathStr) //输出\a\b\d\e

const pathStr2 = path.join(__dirname,'./files/1.txt')

console.log(pathStr2) //输出 当前目录\files\1.txt

tip:涉及到路径拼接的操作,都要使用path.join()方法进行处理。不要直接使用

+进行字符串的拼接。

获取路径中的文件名

path.basename()的语法格式

使用path.basename()方法,可以获取路径中的最后一部分,经常通过这个方法获取

路径中的文件名,语法格式如下:

const path = require('path')

//定义文件路径
const fpath = '/a/b/c/index.html'

const fullName =path.basename(fpath)

console.log(fullName)

//index.html

const namewithout = path.basename(fpath,'.html')

console.log(namewithout)

获取路径中的文件扩展名

path.extname()的语法格式

使用path.extname()方法,可以获取路径中的扩展名部分,语法格式如下:


path.extname(path)

参数解读:

1.path必选参数,表示一个路径的字符串

2.返回:< string> 返回得到的扩展名字符串

const fpath = '/a/b/c/index.html'  //路径字符串

const fext = path.extname(fpath)

console.log(fext) //输出 .html

什么是http模块

http模块是Node.js官方提供的,用来创建web服务器的模块,通过http模块提供的http.createServer()方法,就能方便的把一台普通的电脑,变成一台web服务器,从而对外提供web资源服务

const http = require('http')

进一步理解http模块的作用

服务器和普通电脑的区别在于,服务器安装了web服务器软件,例如IIS、apache等。通过安装这些服务器软件,就能把一台普通的电脑变成一台web服务器。

在Node.js中,我们不需要使用IIS、Apache等这些第三方web服务器软件,因为我们可以基于Node.js提供的http模块,通过几行简单的代码,就能轻轻松松的手写一个服务器软件,从而对外提供web服务。

服务器相关的概念

IP地址

IP地址就是互联网上每台计算机的唯一地址,因此IP地址具有唯一性,如果把个人电脑比作一台电话,那么IP地址就相当于电话号码,只有知道对方IP地址的前提下,才能与对应的电脑之间进行数据通信。

IP地址的格式:通常用"点分十进制"表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。例如:用点分十进制表示IP地址

域名和域名服务器

尽管IP地址能够唯一标记网络上的计算机,但IP地址是一长串数字,不直观,而且不便于记忆,于是人们又发明了另一套字符型的地址方案,即所谓的域名地址

IP地址和域名是一一对应的关系,这份对应关系存放在一种叫做域名服务器的电脑中,使用者只需通过好记的域名访问对应的服务器即可,对应的转换工作由域名服务器实现,因此,域名服务器就是IP地址和域名之间的转换服务的服务器。

注意: 在开发测试期间,127.0.0.1对应的域名是localhost,它们都代表我们自己的这台电脑,在使用效果上没有任何区别。

端口号

计算机中的端口号,就好像是现实生活中的门牌号一样。通过门牌号,外卖小哥可以在整栋大楼众多房间中,准确把外卖送到你的手中。

同样的道理,在一台电脑中,可以运行成百上千个web服务,每个web服务都对应一个唯一的端口,客户端发送过来的网络请求,通过端口号,可以被准确交给对应的web服务进行处理。

注意: 1.每个端口号不能同时被多个web服务占用 2.在实际应用中,URL中的80端口可以被省略。

创建最基本的web服务器

1.导入http模块

如果希望在自己电脑上创建一个web服务器,从而对外提供web服务,则需要导入http模块

 const http =require('http')

2.创建web服务器实例

调用http.createServer()方法,即可快速创建一个web服务器实例。

 const server =http.createServer()

3.为服务器实例绑定request事件,监听客户端的请求

  //使用服务器实例的 .on()方法,为服务器绑定一个request事件
  
  server.on('request',(req,res)=>{
  console.log('some visit our web server')
  }
  )
  

req请求对象

只要服务器接收到了客户端的请求,就会调用通过server.on()为服务器绑定的request事件处理函数。如果想在事件处理函数中,访问与客户端相关的数据或属性,可以使用如下的方式。

4.启动服务器

//调用server.listen(端口号,cb回调)方法,即可启动web服务器
server.listen(80,()=>{
console.log('http server running at http://127.0.0.1')
}
)

模块化

编程领域中的模块化

编程领域中的模块化,就是遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块。 把代码进行模块拆分的好处:

1.提高了代码的复用性。

2.提高了代码的可维护性。

3.可以实现按需加载。

Node.js中的模块作用域

什么是模块作用域

和函数作用域类似,在自定义模块中定义的变量方法等成员,只能在当前模块内被访问 ,这种模块级别的访问限制,叫做模块作用域

模块作用域的好处 防止了全局变量污染的问题。(一个js不能使用另一个js中的变量)

向外共享模块作用域中的成员

1.module对象

在每个.js自定义模块中都有一个modue对象,它里面存储了和当前模块有关的信息,打印如下

image.png

共享成员时的注意点

使用require() 方法导入模块时,导入的结果,永远以module.exports指向的对象为准。(指向最后用的那个对象)

2.exports 对象 由于module.exports 单词写起来比较复杂,为了简化向外共享成员的代码,Node提供了exports对象,默认情况下,exports和module.exports 指向同一个对象。最终共享的结果,还是以module.exports指向的对象为准。

npm与包

1.什么是包

Node.js 中的第三方模块又叫做包。

2.包的来源 不同于Node中的内置模块与自定义模块,包是由第三方个人或团队开发出来的,免费供所有人使用。

注意:Node.js中的包都是免费且开源的,不需要付费即可免费下载使用。

3.初次装包后多了哪些文件 初次装包完成后,在项目文件夹下多了一个叫做node_modules的文件夹和package-lock.json的配置文件。

其中:

node_modules 文件夹用来存放所有已安装到项目中的包。require()导入第三方包时,就是从这个目录中查找并加载包。

package-lock.json 配置文件用来记录node_modules目录下的每一个包的下载信息,例如包的名字、版本号、下载地址等。

注意:npm包管理工具会自动维护它们

4.安装指定版本的包

默认情况下,使用npm install命令安装包的时候,会自动安装最新的包,如果需要安装指定版本的包,可以在包名之后,通过@符号指定具体的版本,例如

npm i moment@2.22.2

  1. 如何记录项目中安装了哪些包

    在项目根目录中,创建一个叫做package.json的配置文件,即可用来记录项目中安装了那些包,从而方便剔除node_modules目录之后,在队成员之间共享项目的源代码。

注意:今后在项目开发中,一定要把node_modules文件夹,添加到.gitgnore忽略文件中。

开发属于自己的包

1.初始化包的基本结构

新建文件夹

新建如下三个文件

1.package.json (包管理配置文件)

2.index.js (包的入口文件)

3.readme.md(包的说明文档)

2.发布包

1.注册npm账号

1.访问www.npmjs.com/网站,点击sign up按钮,进入注册用户页面。

2.填写账户相关信息:Full Name、Public Email、Username、Password

3.点击Create an Account按钮,注册账号。

4.登录邮箱,点击验证连接,进行账号验证。

2.打开自己的终端

在登录前要检查自己登录的是不是npm的服务器,如果不是要先切换到npm的服务器

通过nrm ls检查自己现在连接的是哪一个服务器

nrm ls

通过

nrm use npm

切换到npm服务器,然后再进行登录

npm login

依次输入用户名,密码,邮箱

3.把包发布到npm上

将终端切换到包的根目录之后,运行npm publish命令,即 可将包发布到npm上(注意:我们要发布的包不能和别人已经发布的包名称重复)

4.删除已发布的包

运行npm unpublish 包名 --force命令,即可从npm删除已发布的包

注意点:

1.npm unpublish命令只能删除72小时以内发布的包。

2.npm unpublish删除的包,在24小时内不允许重复发布。

3.发布包的时候要慎重,尽量不要往npm上发布没有意义的包。

模块的加载机制

优先从缓存中加载

模块在第一次加载后会被缓存。这也以为着多次调用require()不会导致模块的代码被执行多次。

注意:不论是内置模块、用户自定义模块、还是第三方模块、 它们都会优先从缓存中加载,从而提高模块的加载效率。

内置模块的加载机制

内置模块是由Node.js官方提供的模块,内置模块的加载优先级最高。 (例如fs,path,http,node内置的模块)

例如,require('fs')始终返回内置fs模块,即使在node_modules目录下有名字相同的包也叫做fs

自定义模块的加载机制

使用require()加载自定义模块时,必须指定以./或../开头的路径标识符。在加载自定义模块时,如果没有指定./或../这样的路径,则node会把它当作内置模块或第三方模块进行加载。

同时,在使用require()导入自定义模块时,如果省略了文件的扩展名,则Node.js会按顺序分别尝试加载以下的文件

1.按照确切的文件名进行加载

2.补全.js扩展名进行加载

3.如果还是失败,会补全.json扩展名进行加载。

4.如果还是失败,会补全.node扩展名进行加载 (是win 32的一个应用程序)

5.加载失败,终端报错

第三方模块的加载机制

如果传递require()的模块标识符不是一个内置模块,也没有以./或者../开头,则Node.js会从当前模块的父目录开始,尝试从/node_modules 文件夹中加载第三方模块。

如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录。

目录作为模块

当把目录作为模块标识符,传递给require()进行加载的时候,有三种加载方式:

1.在被加载的目录下查找一个叫做package.json的文件,并寻找require()加载的入口

2.如果目录没有package.json文件,或者main入口不存在或无法解析,则Node.js将会试图加载目录下的index.js文件。

3.如果以上两步都失败了,则Node.js会在终端打印错误消息,报告模块的缺失,ERROR:can not find modules xxx