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

67 阅读2分钟

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

这是我参与【第四届青训营】笔记创作活动的第9天

一、Node.js的应用场景
前端工程化
  • Bundle:webpack,vite,esbuild,parcel
  • Uglify:uglifyjs
  • Transpile:bablejs,typescript
Web服务端应用
  • 学习曲线平缓,开发效率较高
  • 运行效率接近常见的编译语言
  • 社区生态丰富及工具链成熟(npm,V8 inspector)
  • 与前端结合的场景会有优势(SSR)
Electron跨端桌面应用
  • 商业应用:vscode,slack,discord,zoom
  • 大型公司内的效率工具
二、Node.js运行时结构

image-20220809135529116

  • V8:JavaScript Runtime,诊断调试工具
  • libuv:eventloop(事件循环),syscall(系统调用)
特点
  • 异步I/O

当Node.js执行I/O操作时,会在响应返回后恢复操作,而不是阻塞线程并占用额外内存等待

image-20220809135948339.png

  • 单线程

    • 实际:JS线程+UV线程池+V8任务线程池+V8 Inspector线程

    • 优点:不用考虑多线程状态同步问题,也不需要锁;同时还能比较高效地利用系统资源;

    • 缺点:阻塞会产生更多负面影响

      • 解决办法:多进程或多线程
  • 跨平台

    • Node.js跨平台+JS无需编译环境(+Web跨平台+诊断工具跨平台)
      • 开发成本低,整体学习成本低
三、编写Http Server

Hello World

const http = require('http')

const port = 3000

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

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

JSON

const server = http.createServer((req,res)=>{
    const bufs = []
    req.on('data',data=>{
        bufs.push(data)
    })
    req.on('end',()=>{
        let reqData = {}
        try {
            reqData = JSON.parse(Buffer.concat(bufs).toString())
        } catch (err) {
                
            }
            res.setHeader('Content-Type','application/json')
            res.end(JSON.stringify({
                echo:reqData.msg || 'Hello',
            }))
    })
})
Client
const http = require('http')

const body = JSON.string({msg:'hello from my client'})

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

req.end(body)
                     
用Promise + async await重写

将callback转换成promise

function wait(t) {
return new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve()
    },t)
})
}

wait(1000).then(() =>{ console.log('get called') })
简单的静态文件服务
const http = require('http')
const fs = require('fs')
const path = require('path')
const url = require('url')

const port = 3000

const server = http.createServer((req,res)=>{
    const info = url.parse(req.url)
    const file = fs.createReaderStream(path.resolve(_dirname,'.'+ info.pathname))
    file.pipe(res)
})

server.listen(port,() => {
    console.log(`server listen on:${port}`)
})
React SSR

服务端渲染(Server-Side Rendering),页面上的内容是通过服务端渲染生成的,服务端直接返回拼接好的html,浏览器直接显示服务端返回的html就可以了

image-20220816133253207.png

SSR(server side rendering)特点:

  • 相比传统HTML模板引擎:避免重复编写代码
  • 相比SPA(single page application):首屏渲染更快,SEO友好
  • 缺点:
    • 通常qps较低,前端代码编写时需要考虑服务端渲染情况