Node.js | 青训营笔记

44 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天

1.重点内容

  • Node.js的应用场景
  • Node.js运行时的结构
  • 编写HTTP Server

2.详细知识点

2.1 Node.js的应用场景

前端工程化

前端工程化是使用软件工程

常见工具有webpack, vite, esbuild, parcel

web服务端应用

可以使用node.js开发服务端应用, 常见服务端框架有express等,优势:

  • 学习曲线平缓,开发效率搞
  • 运行效率接近常见的编译语言
  • 社区生态丰富及工具链成熟
  • 与前端结合的场景会有优势(SSR)

Electron跨端桌面应用

使用node.js的跨端框架ELectron,允许保持一个javaScript代码库并创建在window|macOS|Linux的跨平台应用,常见产品:vscode, discord, 等

2.2 node.js运行时的结构

QQ截图20230131140038.png

特点:

  • 异步I/O:node.js执行IO操作时,会在响应返回后恢复操作, 而不是阻塞线程
  • 单线程:node.js 因为javaScript引擎的关系,node默认的是单线程(js线程+UV线程池+V8任务线程池+V8 Inspector线程)
  • 跨平台:node.js 大部分功能API都是跨平台的, 大部分场景无需单选跨平台问题, 整体学习成本低

2.3 编写HTTP Server

创建一个简单的HTTP server

const http = require('http')

const server = http.createServer((req, res) => {
  // 接收客户端数据
  const bufs = []
  req.on('data', (buf) => {
    bufs.push(buf)
  })

  req.on('end', () => {
    res.setHeader('Content-Type', 'application/json')

    const buf = Buffer.concat(bufs).toString('utf-8')
    try {
      const ret = JSON.parse(buf)
      const msg = ret.msg || 'Hello'
      const responseJson = {
        msg: `receive: ${msg}`,
      }

      // 返回数据
      res.end(JSON.stringify(responseJson))
    } catch (err) {
      res.end('invalid json')
    }
  })
})

const port = 3000

server.listen(port, () => {
  console.log('listening on: ', port)
})

创建一个简单的客户端

const http = require('http')
const { resolve } = require('path')

const body = JSON.stringify({ 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)

2.4 SSR

SSR服务端渲染:页面上的内容是通过服务端渲染生成的,浏览器直接显示服务端返回的html

通过react 实现一个简单的服务端渲染

const React = require('react')
const ReactDOMServer = require('react-dom/server')
const http = require('http')

function App(props) {
  return React.createElement('div', {}, props.children || 'Hello')
}

const server = http.createServer((req, res) => {
  res.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" />
      <link rel="shortcut icon" href="#" />
      <title>Document</title>
    </head>
    <body>
      ${ReactDOMServer.renderToString(React.createElement(App, {}, 'my_content'))}
    </body>
  </html>
  
  `)
})

const port = 3000

server.listen(port, () => {
  console.log('listen http://127.0.0.1:3000')
})

2.5 Debug

node -inspect=指定端口 脚本名称

浏览器访问端口:http://127.0.0.1:9229/json 拉起DEVTool

QQ截图20230131202348.png

扩展

QPS

每秒查询率(queries Per Second), 指一台服务器每秒能够响应查询次数