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命令时所处的目录,动态拼接出被操作文件的完整路径。
解决方案:
-
在使用fs模块操作文件时,直接提供完整的路径,不要提供./或../开头的相对路径,从而防止路径动态拼接的问题。但是移植性非常的差,不利于维护
-
采用__dirname(表示当前文件所处的目录)+'路径' 进行拼接。
什么是path路径模块
path 模块是Node.js官方提供的、用来处理路径的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理需求。
例如:
path.join()方法,用来将多个路径片段拼接成一个完整的路径字符串。
path.basename()方法,用来从路径字符串中,将文件名解析出来。
//如果在JavaScript代码中,使用path模块来处理路径,则需要使用如下的方式先导入它
const path =require('path');
path.join()的语法格式
使用path.join([...paths])
参数解读:
-
...paths路径片段的序列
-
返回值 < 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对象,它里面存储了和当前模块有关的信息,打印如下
共享成员时的注意点
使用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
-
如何记录项目中安装了哪些包
在项目根目录中,创建一个叫做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