Node.js与前端开发|青训营笔记

70 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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 边界的利用多进程
    • 记录进程状态,用于诊断