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

64 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第14天

Node.js是一个开源和跨平台的JavaScript运行时环境。

Node.js的应用场景

1. 前端工程化:Node.js赋予了js开发者在浏览器外运行代码的能力,加速催生了这些项目的出现

2. Web服务器应用:使用Node.js开发Web服务器应用

3. Electron应用:Electron由Node.js+Chromium+Native APIs构成。它是一个得到了Node.js和基于不同平台的Native APIs加强的Chromium浏览器,可以用来开发跨平台的桌面级应用。

Node.js运行时结构

image.png

参考自Node.js Core贡献入门

  • v8主要包含了JavaScript Runtime,诊断调试工具inspector

  • libuv:基于事件驱动的异步IO模型库,js代码发出请求,最终由libuv完成,所设置的回调函数则是在libuv触发。用于事件循环、系统调用

Node.js特点

  • 异步I/O:在Node中,绝大多数的操作都以异步的方式进行调用
  • 单线程:Node保持了JavaScript在浏览器中单线程的特点,Node采用了与Web Workers相同的思路来解决单线程中大计算量的问题:child_process
  • 跨平台:Node.js跨平台的特点+JS无需编译环境,使开发成本低,整体学习成本低

编写HTTP Server

编写 HTTP Server + Client

common.js介绍

编写http_server.js

const http = require('http');

const port = 3000;

const server = http.createServer((req,res)=>{    
    res.end("hello");
})

server.listen(port,()=>{
    console.log(`server listens on ${port}`);
})

在cmd里执行node命令,打开浏览器输入localhost:3000访问页面得到hello

image.png

Node.js说明文档

编写http_server_json.js

const http = require('http');

const port = 3000;

const server = http.createServer((req, res) => {
    const bufs = [];
    req.on('data', buf => {
        bufs.push(buf)
    })
    req.on('end', () => {
        // Buffer.concat——Node 缓冲区合并
        const buf = Buffer.concat(bufs).toString('utf-8')
        let msg = 'hello'
        try {
            // JSON.parse(),数据变成一个 JavaScript 对象。
            const ret = JSON.parse(buf)
            msg = ret.msg
        } catch (error) {
            // receive invalid json data
        }
        const responseJson = {
            msg: `receive :${msg}`
        }
        res.setHeader('Content-Type', 'application/json')
        res.end(JSON.stringify(responseJson))
    })
})

server.listen(port, () => {
    console.log(`server listens on ${port}`);
})
image.png

编写http_client.js

const http = require('http')

const body = JSON.stringify({
    msg:'Hello from my own client',
})

const req = http.request('http://127.0.0.1:3000',{
    method:'POST',
    headers:{
        'Content-Type':'application/json',
    }
},(res) => {
    const bufs = []
    res.on('data',(buf)=>{
        bufs.push(buf)
    })
    res.on('end',()=>{
        const buf = Buffer.concat(bufs)
        const json = JSON.parse(buf)
        console.log('json.msg is:',json.msg);
    })
})

req.end(body)
image.png

async await 异步操作参考:

  1. MDN文档
  2. 异步解决方案 async-await

编写静态文件服务器

编写static_server.js:在同级static文件夹中写一个index.html

const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');

const port = 3000;

const folderPath = path.resolve(__dirname,'./static')

const server = http.createServer((req, res) => {
    // expectede http://127.0.0.1:3000/index.html?abc=10
    const info = url.parse(req.url)
    
    // static/index.html
    const filepath = path.resolve(folderPath, './' + info.path) 
    
    console.log('filepath is:',filepath);
    // 更倾向于用stream API读取数据 
    const filestream= fs.createReadStream(filepath)
    filestream.pipe(res)
})

server.listen(port, () => {
    console.log(`server listens on ${port}`);
})

编写React SSR服务

CSR,SSR和SSG是什么,有什么优缺点?

SSR的难点:

  1. 需要处理打包代码 require('./static.style.css')
  2. 需要思考前端代码在服务端运行时的逻辑
        async componentDidMount() {
            const res = await fetch('http://my.server.domain')
    
  3. 移除对服务端无意义的副作用,或者重置环境

使用inspector进行调试、诊断

在启动时使用node --inspect +文件名 然后open http://localhost:9229/json

场景:

  • 查看console.log内容
  • breakpoint
  • 高CPU、死循环:cpuprofile
  • 高内存占用:heapsnapshot
  • 性能分析