这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天,下面是我的 Node.js 学习笔记。
Node.js的应用场景
- 前端工程化
- Web 服务端应用
- Electros 跨端应用
Node.js运行时结构
- V8:JavaScript Runtime,诊断调试工具(inspector)
- libuv:eventloop(事件循环),syscall(系统调用)
特点:
- 异步I/O
- 单线程
- 跨平台
编写 Http Server
Http Server
Hello World
const http = require('http');
//创建服务
const server = http.createServer((req,res) =>{
res.end('hello world!');
});
const port = 3000;
//监听端口
server.listen(port, ()=>{
console.log('listening on: ',port);
});
JSON
const http = require('http');
//创建服务
const server = http.createServer((request,response) =>{
const bufs = [];
request.on('data',(buf) => {
bufs.push(buf);
})
request.on('end',() => {
//bufs
const buf = Buffer.concat(bufs).toString('utf8');
let msg = 'Hello World!';
//尝试解析buf数据
try{
const ret = JSON.parse(buf);
msg = ret.msg;
}catch(err){
console.log('Invalid msg!');
}
//设置返回数据
const responseJson = {
msg: `receive: ${msg}`
}
response.setHeader('Content-Type','application/json');
response.end(JSON.stringify(responseJson));
})
});
const port = 3000;
//设置监听端口
server.listen(port, ()=>{
console.log('listening on: ',port);
});
Http Client
const http = require('http');
const body = JSON.stringify({msg: 'Hello World from my own client!'});
//发起post请求
const request = http.request('http://127.0.0.1:3000',{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': body.length,
},
}, (response) => {
const bufs = [];
response.on('data',(data) => {
bufs.push(data);
});
//设置响应数据
response.on('end', () => {
const buf = Buffer.concat(bufs);
const json = JSON.parse(buf);
console.log('json msg is:',json);
});
});
//设置请求体
request.end(body);
静态文件
编写一个简单的静态文件服务
const http = require('http')
const fs = require('fs')
const path = require('path')
const url = require('url')
const folderPath = path.resolve(__dirname,'./static');
const server = http.createServer((request,response) => {
//http:127.0.0.1:3000/index.html?abc=10
const info = url.parse(request.url);
//求文件路径
const filepath = path.resolve(folderPath,'./'+info.path);
//获取文件流
const filestream = fs.createReadStream(filepath);
filestream.pipe(response);
});
const port = 3000;
server.listen(port, () => {
console.log("listening on:",port);
});
React SSR(server side rendering)
优点:
- 避免重复编写代码
- 首屏渲染更快,SEO友好 缺点:
- 通常 qps 较低,前端代码编写时需要考虑服务端渲染情况
示例
const http = require('http');
const react = require('react');
const reactDomServer = require('react-dom/server');
function fun(){
return react.createElement('h1',{
children: 'hello world!',
});
}
//创建服务
const server = http.createServer((request,response) =>{
response.end(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
${reactDomServer.renderToString(
react.createElement(fun)
)}
</body>
</html>
`);
});
const port = 3000;
server.listen(port, ()=>{
console.log('listening on: ',port);
});
V8 Inspector
使用方法:node --inspect
场景:
- 查看 console.log 内容
- 设置断点
- 高cpu、死循环:cpuprofile
- 高内存占用:heapsnapshot
- 性能分析
部署
- 部署要解决的问题
- 守护进程:当进程退出时,重新拉起
- 多进程:cluster 边界的利用多进程
- 记录进程状态,用于诊断