这是我参与「第五届青训营 」伴学笔记创作活动的第 七 天
Node.js 的应用场景
前端工程化
前端工程化,就是指对前端进行一些流程的标准化,让开发变得更有效率,且更好地做产品交付。比如使用 webpack, vite, esbuild, parcel 等工具对项目进行打包,使用 uglifyjs 压缩 JS,使用 bablejs, typescript 进行语法的转化。还有许多其他的语言也加入了前端工程化的竞争,如 esbuild, parcel, prisma 等,但是 node 在前端工程化中还是有着不可取代的地位。
Web 服务端应用
对于前端开发者来说,JS 这门语言已经非常熟悉了,因此配合 Node.js 进行一些偏后端的开发时,其学习曲线会比较平缓,开发的效率会更高。Node.js 是一门不需要编译环境的语言,它的运行效率会比较高,在脚本语言中,它的运行效率排在前列,甚至能够比肩一些常见的编译语言。Node.js 的社区生态非常丰富,并且工具链很成熟。Node.js 在与前端相结合的场景中非常有优势,其中许多场景基本只有 Node.js 才能做到。
Electron 跨端桌面应用
目前有不少商业应用都用到了 Electron 的方案,比如 vscode, slack, discord, zoom 等应用,还有一些大型公司内部的效率工具也是基于 Electron 去做,其成本和效果都有优势,而且其跨端特性能够解决许多问题,当然其也有运行较慢,资源消耗较高等问题,但其特点仍能够使我们忽略这些问题。
Node.js 运行时结构
V8,libuv
Node.js 其本身的许多特点都是基于 V8 引擎实现的,其提供了 JavaScript Runtime,诊断调试工具(inspector),使得 Node.js 的效率比较高。libuv 能够实现事件的循环,封装各种操作系统上的 API ,来提供一个跨平台的 IO 工作。
特点
异步IO
当 Node.js 执行IO操作时,会在响应返回后恢复操作,而不是阻塞线程并占用额外内存等待。
单线程
JS 单线程
实际:JS 线程+uv 线程池+V8 任务线程池 +V8 Inspector 线程
优点:不用考虑多线程状态同步问题,也就不需要锁;同时还能比较高效地利用系统资源;
缺点:阻塞会产生更多负面影响
解决办法:多进程或多线程
跨平台
跨平台(大部分功能、api)
Node.js 跨平台+JS 无需编译环境(+Web 跨平台+诊断工具跨平台)
开发成本低(大部分场景无需担心跨平台问题),整体学习成本低
编写 Http Server
安装Node.js
通过 官网 提供的下载地址下载安装包,根据指示进行安装。
检测 PATH 环境变量是否配置了 Node.js,点击开始=》运行=》输入"cmd" => 输入命令"path",查看环境变量中是否已经包含了C:\Program Files\nodejs\。通过 node - v指令查看 node.js 版本。
express 创建服务器
//导入express
const express = require('express')
//创建web服务器
const app = express()
//监听客户端的GET和POST请求,并向客户端相应具体的内容
app.get('/user',(req,res) => {
//调用express提供的res.send()方法,向客户端相应一个JSON对象
res.send({name:'zs',age:20,gender:'男'})
})
app.post('/user',(req,res) => {
//调用express提供的res.send()方法,向客户端响应一个文本字符串
res.send('请求成功')
})
//启动web服务器
app.listen(80,() => {
console.log('express server running at http://127.0.0.1')
})
//:id为动态参数
app.get('/user/:id',(req,res) => {
//req.params 是动态匹配到的 URL参数,默认也是一个空对象
console.log(req.params)
res.send(req.params)
})
跨域代理
在我们进行 Web 服务端开发时,有时会遇到跨域问题,除了在服务端设置解决跨域之外,我们还可以通过 Node.js 设置 cors 或设置跨域代理来解决跨域问题。
const express = require('express');
const app = express()
var request = require('request');
app.use(express.urlencoded({extended:false}))
const cors = require('cors')
//使用cors解决跨域问题
app.use(cors())
//使用代理解决跨域问题
app.get('/api/get',(req,res) => {
res.setHeader('Access-Control-Allow-Origin','*');
request('https://www.mxnzp.com/api/address/list?app_id=&app_secret=', function(err, response, body){
//err 当前接口请求错误信息
//response 一般使用statusCode来获取接口的http的执行状态
//body 当前接口response返回的具体数据 返回的是一个jsonString类型的数据
//需要通过JSON.parse(body)来转换
if(!err && response.statusCode == 200){
//todoJSON.parse(body)
const data = JSON.parse(body);
// console.log(data)
res.send(data)
// res.send(body)
}
})
})