Node.js

概念

js是一门客户端语言,且是一门脚本语言,也就是说只能在浏览器上运行,且只能依赖HTML才能运行。

为了提高js的格调,让js脱离浏览器也能运行,一代大神Ryan Dahl在2009年,通过分析将谷歌中V8引擎(即谷歌浏览器中的js解析器),分离出来,进行二次封装,做出了一款软件,叫node.js。

这款软件中可以运行js代码,且不需要依赖浏览器和HTML。

所以说,node.js本质上是一个js除了浏览器之外的运行环境,使得js除了是一门客户端语言外,还是一门和Java、PHP、Ruby平起平坐的客户端语言。

使用node.js注意

1.node.js实现了js代码在浏览器外执行,所以在node.js中无法运行DOM和BOM代码

2.node,js除了EcmaSrcipt外,还内置了很多其他Api

3.node.js让js在写前端代码的基础上,可以写后端代码,因为node.js可以构建服务器

中文文档

下载安装

node.js初体验

nodejs是执行js代码的环境,执行方式有两种:

1.在node.js直接执行代码(类似于在浏览器控制台写js代码并执行)

 在命令行中输入node,敲回车,就进入了nodejs的控制台,操作跟浏览器的控制台一样

node
console.log(111)

Node.js_第1张图片

 退出这个控制台,通过两次ctrl+c或者.exit命令。

这种方式无法用来开发代码,因为我们也从不在浏览器的控制台开发代码

2.使用nodejs执行js文件

新建js文件,书写规范的js代码,通过命令行的node命令执行这个文件。

执行的文件有两种方式

①当前命令行不在文件所在的文件夹下,此时需要文件的绝对路径 - 不常用

②当前命令行在文件所在的文件夹下,此时使用文件的相对路径即可 - 常用

CommonJS模块化开发规范

因为node命令执行js文件的时候,只能指定一个js文件,所以我们在开发的时候只能将项目所有代码写在一个文件中,可是这样不利于我们进行分工合作,也不利于后期项目的维护,所以需要对js代码进行模块化管理。

所有前端的模块化,都是将一个js 当做是一个模块,多个模块之间可以互相导入使用

CommonJS是nodejs中自带的模块化规范,只能在nodejs中使用,导出使用module.exports关键字 ,导出使用require关键字。

// 导入
require(被导入的模块)

// 导出
module.exports = {数据}
module.exports.键 = 值
exports.键 = 值

一个文件就是一个独立的模块,可以理解为是一个独立的作用域,别的模块需要用到这个作用域中的数据,就需要将这个作用域中的数据导出,可以理解为函数返回数据的意思。

a.js导出:

let a = 10
module.exports = a // 数据a就被导出了 - 这种导出方式只能导出一个数据
module.exports = {a} // 对象被导出了 - 通常要导出多个数据就使用这种导出方式
module.exports.a = a // 导出了一个对象 - 这种导出方式可以在多个地方导出数据

为了让导出变得更简单,commonjs规范中,在每个模块中定义了一个变量exports,并将module.exports赋值给了exports,导出时可以使用exports:

exports = {a}
exports.a = a

注意:使用exports导出的时候,千万不能直接给exports赋值,因为导出功能是由module.exports提供的,如果直接给exports赋值,就将exports的内存空间换成另外一个数据空间了,将失去导出功能。

b.js导入:

let data = require('./a.js')

导入的就是导出的数据,导出数据就接受到数据,导出对象就接收到对象。

注意:导入的文件是自定义的,那路径中的./是不能省略的。导入文件的后缀可以省略,因为nodejs中能被导入的只能是js文件。

在nodejs中被导入的模块分三种:

1.自定义模块 - 路径中的./不能省略

2.内置模块 - 只需要导入模块名称,不需要路径,因为默认会在系统中找这个文件

3.第三方模块 - 别人写好的js文件,我们需要导入使用,所以必须提前下载好才能导入使用

内置模块

fs

fs(file system)模块提供了用于文件进行交互的相关方法。

const fs = require('fs')

// 写入数据(覆盖)
fs.writeFile(文件路径,待写入的数据,err => {}) // 异步写入文件
fs.writeFileSync(文件路径,待写入的数据) // 同步写入文件

// 读取文件中数据
fs.readFile(文件路径, 'utf-8’,(err,data) => {}) // 异步读取文件
fs.readFileSync(文件路径, 'utf-8’) // 同步读取文件
// 第二个参数是可选项,如果不加的话,默认读取出来的buffer(用16进制来描述2进制数据流的格式)数据,需要通过buffer.toString()才能转成字符串

// 判断文件是否存在
let ret = fs.existsSync(path)

// 获取文件信息(异步)
fs.stat(文件,(err,stats) => {
	stats.isDirectory() // 是否是目录
	stats.isFile()       // 是否为文件
	stats.size            // 文件大小(以字节为单位)
})

// 给文件中追加内容
fs.appendFile(文件路径,待写入的数据,err => {}) // 异步追加
fs.appendFileSync(文件路径,待写入的数据) // 同步追加

// 删除文件(异步)
fs.unlink(文件路径,err => {})

// 文件重命名
fs.renameSync(旧的文件路径, 新的文件路径)

os

os(operation system)模块提供了与操作系统相关的实用方法和属性。

const os = require('os')
// 换行符
os.EOL  //根据操作系统生成对应的换行符 window \r\n,linux下面 \n

// cpu相关信息
os.cpus()
// 总内存大小 (单位 字节)
os.totalmem()
// 空余内存大小 (单位 字节)
os.freemem()

path

path模块用于处理文件和目录(文件夹)的路径。

const path = require('path')

// 获取路径最后一部内容,一般用它来获取文件名称
path.basename('c:/a/b/c/d.html')  // d.html

// 获取目录名,路径最后分隔符部分被忽略
path.dirname('c:/a/b/c/d.html') // c:/a/b/c

// 获取路径中文件扩展名(后缀)
path.extname('c:/a/b/c/d.html') // .html

// 给定的路径连接在一起
path.join('/a', 'b', 'c') // /a/b/c

__dirname:是nodejs提供的一个内置变量,代表当前文件所在位置的绝对路径

斜杠和反斜杠:通常用来分割路径,“某个文件夹下”的意思,在window系统中,斜杠和反斜杠的意义是一样的,但是建议写斜杠,反斜杠在代码中有特殊含义,转义的意思,在服务器系统中,默认路径就是使用斜杠

url

url字符串是结构化的字符串,包含多个含义不同的地方。解析字符串后返回的URL对象,每个属性对应字符串的各个组成部分。

const url = require('url');
const href = 'http://www.xxx.com:8080/pathname?id=100#bbb'
// 解析网址,返回Url对象
// 参2 如果为true 则 query获取得到的为对象形式
url.parse(href,true)

//以一种 Web 浏览器解析超链接的方式把一个目标 URL 解析成相对于一个基础 URL。
url.resolve('https://lynnn.cn/foo/bar',../'bar') // https://lynnn.cn/bar

querystring

用于解析和格式化URL查询字符串(URL地址的get形式传参)的实用工具。

const querystring = require('querystring')

// query字符串转为对象
querystring.parse('foo=bar&abc=xyz')
querystring.decode('foo=bar&abc=xyz')

// 对象转为query字符串
querystring.stringify({ foo: 'bar',abc: 'xyz'})
querystring.encode({ foo: 'bar',abc: 'xyz'})

http

服务器介绍

服务器指的是用来提供服务的,无论本机还是其他计算机,只要能提供服务就可以将它称之为服务器。

我们这里所说的服务器,应该叫做web服务器,一般指的是网站服务器,就是能提供网站访问服务软件或程序,目前最主流的三个web服务器软件是Apache、Nginx、IIS。

创建服务器

// 导入http模块    
const http = require('http')
// 创建web服务对象实例
const server = http.createServer()
// 绑定监听客户端请求事件request
// on方法做事件监听
server.on('request', (request, response) => {})
/*
request变量和response变量都是对象
request对象中包含了跟客户端请求相关的信息,例如:请求方式、请求路径、请求头 。。。
请求方式:request.method 值是大写的方法
请求路径:request.url 值是从network中看到的请求路径(不是完整的请求地址)
请求头:request.header 值是从network中看到的请求头

response对象是用来提供的响应的对象,其中方法居多
结束响应:response.end() 如果不结束响应,客户端在访问的时候会一直转
响应内容:
	response.end(数据) response.end除了有结束响应的功能,还可以给客户端响应内容,内容格式要求:字符串/buffer
	response.write(数据)
设置响应头:response.setHeader(键, 值)
设置响应状态码和响应头:
	response.writeHead(状态码, 状态描述, {响应头})
*/
server.listen(8080, () => { // 这里的第二个参数回调函数可以省略
    console.log('服务已启动')
})

通常在访问服务器的时候,默认会有一个网站图表的请求,要求服务器提供网站图标。

简写:

require('http').createServer((req, res) => {
    // 处理响应
}).listen(端口号)

静态资源服务器

假设我们写好了一套静态页面,但是需要让别人访问,就需要提供一个服务器,且别人来访问的时候还要能访问到对应的静态页面。这种服务器称之为静态资源服务器,目的只是为了提供访问静态资源。

const path = require('path')
let fs = require('fs')
require('http').createServer((req, res) => {
    // 处理响应
    // 通过请求路径获取到对应的文件路径
    let filePath = path.join(__dirname, 'public', path.basename(req.url))
    let ret = fs.existsSync(filePath) // 判断文件路径是否存在
    // 判断文件路径是否是一个文件
    fs.stat(filePath,(err,stats) => {
        if(stats.isFile()){
            // 读取文件并响应
            res.end(fs.readFileSync(filePath))
        }else{
            // 如果不是文件就响应404
            res.writeHead(404)
            res.end() // 结束响应,避免客户端一直转
        }
    })
}).listen(端口号)

获取get参数

// 导入
const http = require('http');
const url = require('url');
// 创建实例&监听request事件&监听端口
http.createServer((req, res) => {
    //  之前第3步中的回调函数
	// 获取地址栏中 query数据
	let { query } = url.parse(req.url, true);
	console.log(query);
}).listen(8080)

获取post参数

const http = require('http');
const queryString = require('querystring');
http.createServer((req, res) => {
    let str = ''
    // data事件表示数据接收中
    req.on('data', chunk => { // chunk表示接收到的一点一点的数据
        str += chunk.toString()
    });
    // end事件表示数据传输结束了
    req.on('end', () => {
        let postData = queryString.parse(str) // 将接收到的字符串转为对象
        console.log(postData);
    });
}).listen(8080)

第三方模块

就是网上别人已经开发好的模块,我们可以直接拿来借鉴使用,但是需要下载,下载工具使用npm。

npm工具

下载:

npm install/i 包名
npm i 包名 包名 ... # 下载多个模块
npm i 包名@版本号 # 最新版本可以使用 @latest

下载命令执行后,会产生node_modules文件夹,将下载好的包放在这个文件夹中。

这个文件夹的特点:文件比较琐碎,层级嵌套较深,依赖关系较多......

查看模块的所有版本:

npm view 模块 versions

 查看所有安装好的依赖包:

npm list # 简写 npm ls

卸载:

npm uninstall/un 包名

下载/卸载参数

--save-dev 简写 -D 表示下载的这个包是一个开发依赖,将来上线后将不需要,只是在本地开发阶段需要
--save 简写 -S 表示下载的这个包是一个生产依赖,将来项目上线后还需要,本地开发和远程上线都需要,npm默认使用--save参数
--global 简写 -g 表示下载的这个包是一个命令,需要在计算机任何一个位置都能使用

初始化:

npm init # 手动输入整个包的信息
npm init -y # 自动生成整个包的信息 - 不能在中文文件夹下使用
# 初始化命令执行以后,会生成package.json文件,生成后在当前目录下安装的所有包,都会自动记录在这个文件中,方便查看、下载、卸载、分析等操作
npm install/i # 安装所有package.json中记录好的包,只安装生产依赖(之前用过-S),不安装开发依赖(之前安装用-D)

初始化的原因:

我们在开发的时候需要很多依赖包,等开发完成后,项目需要传到服务器环境下运行上线,但node_modules文件由于自身特点,不方便上传,可能在上传过程中造成无法上传文件或文件丢失等问题,所以,我们将项目中依赖的包记录在package.json文件中,在服务器环境中根据记录的包的信息,再次下载即可。

npm切换镜像源

npm config set registry 镜像源地址 # 切换命令
npm config get registry # 查看镜像源地址
npm --registry https://registry.npm.taobao.org install node-red-contrib-composer@latest # 临时切换使用

 查看所有全局包:

npm list -g

清除缓存:

npm cache clear --force/-f

下载好的模块如果不知道怎么使用,上网查询npm 。所有使用npm下载好的模块,都在这个网站上能找到。

爬虫

const http = require('http');
const cheerio = require('cheerio')
// http模块提供了get方法用来做爬虫
http.get(地址,res=>{
    let str = ''
    // 像接收post数据一样通过事件接收数据
    res.on('data', chunk => {
        str += chunk.toString()
    })
    res.on('end', () => {
        console.log(str)
        /*
        响应回来的str是爬到的目标网页中的所有内容,对于爬回来的数据处理,有2种方式:
        1.正则匹配
        2.利用cheerio第三方模块去处理
        */
        const $ = cheerio.load(str)
        // $的时候可以像jquery中的$一样,直接能获取到爬回来的数据中的节点
    })
})

代理

const http = require('http')http-proxy-middleware
// 服务器中的代理,需要使用第三方模块
const proxy = require('http-proxy-middleware')
// 创建代理
let fn = proxy.createProxyMiddleware({
    target: '', // 要代理的目标地址
    changeOrigin: true, // 转换请求源
    pathRewrite: {
        '/daili':'' // 将原地址从目标地址中过滤掉
    }
})
http.createServer((req, res) => {
  	let url = req.url
    if(url === '/daili'){
    	 // 调用代理函数
        fn(req, res)
    }
})

模块查找顺序:系统中>node_modules

其他工具

http-server 

启动一个web服务器。

下载安装:

npm i http-server -g

 启动:

http-server

 json-server

依赖一个json文件启动web服务器,且自带了对json文件操作的接口:

下载安装:

npm i json-server -g

使用:

json-server json文件

 然后就启动了一个http服务器。且可以通过post、delete、put、get四种请求来对json文件中的数据做增删改查。

也就是说这个服务器内置json数据的操作接口,接口地址显示如下:

get	http://localhost:端口号/json的键 - 获取所有数据
post http://localhost:端口号/json的键 请求主体中传送数据 - 新增一条数据
delete http://localhost:端口号/json的键/id - 删除指定id的数据
put http://localhost:端口号/json的键/id 请求主体中传送数据 - 修改指定id的数据
get http://localhost:端口号/json的键/id - 获取指定id对应的数据

yarn工具 

yarn跟npm一样,是一个第三方包的管理工具,比起npm,yarn工具更加高效快捷。

通常在下载一些较为复杂的包的时候,多个包之间总会有一些依赖关系,npm下载的时候,使用续发形式下载,也就是同步下载,而yarn是并发式下载,也就是异步下载,效率更高。例如:我们需模块A,但是模块A需要依赖模块B,模块B又需要依赖模块C,npm下载的时候是按照顺序:C...>B...>A;yarn下载的时候是并发下载:A和B和C同时下载。

yarn不是一个自带工具,需要手动下载安装,下载地址安装 | Yarn 中文文档

检测安装:

yarn --version

初始化:

yarn init
yarn init -y

 下载安装包:

yarn add 包
yarn add 包@版本号

卸载包:

yarn remove 包

 安装全部依赖:

yarn 
yarn install

nodemon工具 

这是一个全局工具,用法和node一样,但nodemon可以自动监视文件变化,当文件发生变化会自动重新执行命令。

下载安装:

npm i nodemon -g

 使用:

nodemon 待执行的js文件

当文件发生改变后,会自动重新启动,无需重启。 

你可能感兴趣的:(node.js,前端,javascript)