node.js

134 阅读12分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

node.js

node.js是基于Chrome V8引擎 javascript的运行环境

  1. 浏览器是Javascript的前端运行环境
  2. Node.js是Javascript的后端运行环境
  3. Node.js中无法调用DOM和BOM等浏览器内置API

node -v检查node版本

cd 切换目前所处的目录

node xx.js 运行javascript文件

使用↑键,可以执行终端中上次执行的命令

使用tab键,可以快速补全目录路径

使用esc键,可以快速清空当前已输入的命令

使用cls命令,可以清空终端

fs文件系统模块

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

例如:

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

如果要在Javascript代码中,使用fs模块来操作文件,则需要使用如下的方式先导入它:

const fs = require('fs')

1. fs.readFile()的语法格式

fs.readFile('./files/11.txt','utf8,function(err,dataStr){
    console.log(err)
    console.log(dataStr)
})

参数读解:

  • 参数1:必选参数,字符串,表示文件的路径。
  • 参数2:可选参数,表示以什么编码格式来读取文件。
  • 参数3:必选参数,文件读取完成后,通过回调函数拿到读取的结果

2. fs.writeFile()的语法格式

fs.writeFile('./files/2.txt','Hello Node.js!',function(err){
    console.log(err)
})

参数读解:

  • 参数1:必选参数,需要指定一个文件路径的字符串,表示文件的存放路径。
  • 参数2:必选参数,表示要写入的内容。
  • 参数3:可选参数,表示以什么格式写入文件内容,默认值时utf8。

___dirname 表示当前文件所处的目录

fs.writeFile(__dirname + '/files/2.txt','Hello Node.js!',function(err){
    console.log(err)
})

path路径模块

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

例如:

  • path.join()方法,用来将多个路径片段拼接成一个完整的路径字符串
  • path.basename()方法,用来从路径字符串中,讲文件名解析出来

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

const path = require('path')

1. path.join的语法格式

使用path.join()方法,可以把多个路径片段拼接为完整的路径字符串,语法格式如下:

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

参数解读:

...path路径片段的序列

返回值:

2. path.basename()的语法格式

使用path.basename()方法,可以获取路径中的最后一部分,经常通过这个方法获取路径中的文件名,语法格式如下:

const fpath = '/a/b/c/index'//文件的存放路径

var fullName = path.basename(fpath)
console.log(fullName)//输出 index.html

var nameWithoutExt = path.basename(fpath,'.html')
console.log(nameWithoutExt)//输出 index

参数解读:

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

ext可选参数,表示文件扩展名

返回:表示路径中的最后一部分

3. path.extname()的语法格式

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

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

const fext = path.extname(fpath)
console.log(fext) //输出 .html

参数解读:

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

返回:返回得到的扩展名字符串

http模块

在网路节点中,负责消费资源的电脑,叫做客户端;负责对外提供网络资源的电脑,叫做服务器

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

如果希望使用http模块创建Web服务器,则需要先导入它:

const http = require('http')

IP地址

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

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

注意:

  1. 互联网中每台Web服务器,都有自己的ip地址,例如:大家可以再windows的终端运行ping wwww.baidu.com命令,即可查看到百度服务器ip地址
  2. 在开发期间,自己的电脑既是一台服务器,也是一个客户端,为了方便测试,可以在自己的浏览器中输入127.0.0.1这个ip地址,就能把自己的电脑当做一台服务器进行访问了

域名和域名服务器

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

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

注意:

  1. 单纯使用IP地址,互联网中电脑也能正常工作。但是有了域名的加持,能让互联网的世界变得更加方便。
  2. 在开发测试期间,127.0.0.1对应的域名是localhost,他们都代表我们自己的这台电脑,在使用效果上没有任何区别

http模块

创建最基本的web服务器

//1.导入http模块
const http = require('http')
//2.创建web服务器实例
const server = http.createServer()
//3.为服务器实例绑定 request 事件,监听客户端的请求
server.on('request',function(req,res){
    console.log('Someone visit our web server.')
})
//4.启动服务器
server.listen(8080,function(){
    console.log('server running at http://127.0.0.1:8080')
})

模块化

模块化是指解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程,对于整个系统来说,模块是可组合、分解和更换的单元。

模块化就是遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块。

把代码进行模块化拆分的好处:

  1. 提高代码的复用性;
  2. 提高了代码的可维护性;
  3. 可以实现按需加载 模块化规范就是对代码进行模块化的拆分与组合时,需要遵守的那些规则。

例如:

  • 使用什么样的语法格式来引用模块
  • 在模块中使用什么样的语法格式向外暴露成员

模块化规范好处:大家都遵守同样的模块化规范写代码,降低了沟通的成本,极大方便了各个模块之间的相互调用,利人利己。

Node.js中模块的分类

Node.js中根据模块来源的不同,将模块分为了3个大类,分别是:

  • 内置模块(内置模块是由Node.js官方提供的,例如fs、path、http等)
  • 自定义模块(用户创建的每个.js文件,都是自定义模块)
  • 第三方模块(由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载)

加载模块

使用强大的require()方法,可以加载需要的内置模块、用户自定义模块、第三方模块进行使用,例如:

//1.加载内置的fs模块
const fs = require('fs')

//2.加载用户的自定义模块
const custom = require('./custom.js')

//3.加载第三方模块
const moment = require('moment')

注意:使用require()方法加载其他模块时,会执行被加载模块中的代码。

Node.js中的模块作用域

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

模块作用域防止变量污染的问题

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

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

module.exports对象

在自定义模块中,可以使用module.exports对象,将模块内的成员共享出去,供外界使用。

外界用require()方法导入自定义模块时,得到的就是module.exports所指向的对象。

exports对象

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

Node.js中的模块化规范

Node.js遵循了CommonJs模块化规范,CommonJs规定了模块的特性和各模块之间如何相互依赖。

CommonJs规定:

  1. 每个模块内部,module变量代表当前模块。
  2. module变量时一个对象,它的exports属性(即module.exports)是对外的接口。
  3. 加载某个模块,其实是加载该模块的module.exports属性,require()方法用于加载模块。

npm和包

npm下载包命令:npm install moment 简写:npm i moment

npm初次安装包后多了哪些文件

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

其中:

  • node_modules文件夹用来存放所有已安装到项目中的宝,require()导入第三方包时,就是从这个目录中查找并加载包。
  • package-lock.json配置文件用来记录node_modules目录下的每一个包的下载信息,例如包的名字、版本号、下载地址等。

安装指定版本的包

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

npm i moment@2.22.2

包管理配置文件

npm规定,在项目根目录中,必须提供一个叫做package.json的包管理配置文件,用来记录与项目有关的一些配置信息,例如:

  • 项目的名称、版本号、描述等
  • 项目中都用到了那些包
  • 哪些包只在开发期间会用到
  • 那些包在开发和部署时都需要用到

快速创建package.json

npm包管理工具提供了一个快捷命令,可以在执行命令时所处的目录中,快速创建package.json这个包管理配置文件:

//作用:在执行命令所处的目录中,快速创建package.json文件
npm init -y

注意:

  1. 上述命令只能在英文的目录下成功运行!所以,项目文件夹的名称一定要使用英文命名,不要使用中文,不能出现空格。
  2. 运行npm install命令安装包的时候,npm包管理工具会自动把包的名称和版本号,记录到package.json中。

dependencies节点

package.json文件中,有一个dependencies节点,专门用来记录使用npm install命令安装了那些包。

一次性安装所有的包

可以运行npm install命令(或npm i)一次性安装所有的依赖包:

//执行npm install 命令时,npm包管理工具会先读取package.json中的dependencies节点。
//读取到记录的所有依赖包名称和版本号之后,npm包管理工具会把这些包一次性下载到项目中
npm install

卸载包命令:npm uninstall xxx

devDependencies 节点

如果某些包只在项目开发阶段会用到,在项目上线之后不会用到,则建议把这些包记录到devDependencies节点中,与之对应的,如果某些包在开发和项目上线之后都需要用到,则建议把这些包记录到dependencies节点中。

//安装指定的包,并记录到devDependencies节点中
npm i 包名 -D
//注意:上述命令时简写形式,等价于下面完整的写法:
npm install 包名 --save-dev

包的分类

项目包

那些被安装到项目的node_modules目录中的包,都是项目包。

项目包又分为两类,分别是:

  • 开发依赖包(被记录到devDependencies节点中的包,只在开发期间会用到)
  • 核心依赖包(被记录到dependencies节点中的包,在开发期间和项目上线之后都会用到)

全局包

在执行npm install 命令时,如果提供了-g参数,则会把包安装为全局包。

npm i 包名 -g     # 全局安装指定的包
npm uninstall 包名 -g   #卸载全局安装的包

注意:

  1. 只有工具性质的包,才有全局安装的必要性,因为它们提供了好用的终端命令。
  2. 判断某个包是否需要全局安装后才能使用,可以参考官方提供的使用说明。

规范的包结构

  1. 包必须以单独的目录而存在
  2. 包的顶级牡蛎下要必须包含package.json这个包管理配置文件
  3. package.json中必须包含name,version,main这三个属性,分别代表包的名字、版本号、包的入口。