node.js学习笔记

应用场景

image.png

1. 前端工程化

我们最早期写前端页面的时候,往往一个页面就是一个文件,HTML、CSS、JS都写在一起,没有吧结构层、表现层和行为层分离。随着前端工程的复杂化,我们需要考虑多人协作、项目维护、开发效率的问题。所以,前端工程化的主要作用就是将前端项目当成系统工程进行分析、组织和构建,从而达到项目结构清晰、分工明确、团队配合默契、开发效率提高的目的。

有许多前端工程化相关的库都是由node.js写的,比如说连接js依赖文件的bundle.js压缩js的uglify.js转换js模块格式的Transpile.js等等。

2. web服务端应用

Node开发web服务端应用,也就是后端服务。服务端应用需要接受客户端的请求(request),并对请求做出响应(response)。

特点:

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

SSR:服务端渲染。SSR通过将组件或页面通过服务器生成html字符串,再发送到浏览器,最后将静态标记"混合"为客户端上完全交互的应用程序。渲染时请求页面,返回的body里已经存在服务器生成的html结构,之后只需要结合css显示出来。这就节省了访问时间和优化了资源的请求。

SSR能够更有利于网站的SEO(搜索引擎优化)和首屏页面的渲染。
image.png

  1. Electron 跨端桌面应用
    Electron现在所开发的商业应用有:vscode,slack,discord,zoom。这种商业应用一般是大型公司内的效率工具。大部分场景在选型时都值得考虑通过node.js开发桌面应用。

    总体来说,现阶段还有更多其它语言加入竞争,但node.js从生态和效率上都有其独特的优势,难以被替代。

  2. node.js在字节

  • BFF应用、SSR应用:Modern.js
  • 服务端应用:头条搜索,西瓜视频,懂车帝
  • Electron应用:飞连,飞书
  • 每年新增1000+Node.js应用

Node.js运行时结构

image.png

V8 inspector在上面有讲过,是一个node服务工具,能够查看JavaScript Runtime和诊断调试页面。

libuv是一个跨平台聚焦于异步I/O的库,event-loop(事件调用)和syscall(系统调用)就源自于libuv。

举例:当node-fetch发起请求时,
用户代码-> V8 -> Node.jsCore(JavaScript) -> Node.js Core(C++) -> HTTP传输-> Node.js Core(JavaScript) -> 用户代码

  • 特点:
  1. 异步I/O
    image.png
setTimeout(()=>{
  console.log('B')
})
console.log('A')

image.png

  1. 单线程
    JS单线程实际上是:JS线程+uv线程池+V8任务线程池+V8 Inspector线程
    在单线程中,我们不需要考虑多线程状态同步问题,也就不需要锁;能够更高效地利用系统资源。
    但阻塞时会产生更多负面影响,有些场景下还是需要多进程或多线程。
function fibonacci(num: number): number {
  if(num===1 || num===2){
    return 1
  }
  return fibonacci(num-1)+fibonacci(num-2)
}
console.log(fibonacci(42))
console.log(fibonacci(43))

image.png

  1. 跨平台
    Node.js大部分功能和API都是跨平台的。
    通过node.js跨平台+JS无需编译环境(+Web跨平台+诊断工具跨平台),开发成本较低,学习成本低。
const net = require('net')
const socket = new net.Socket('/tmp/socket.sock')

编写Http Server

const http = require('http')
const port = 3000

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

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

image.png

  • JSON
const http = require('http')
const port = 3000

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) {
      console.error('err!')
    }
    
    res.setHeader('Content-Type', 'application/json')
    res.end(
      JSON.stringify({
        echo: reqData.msg || 'Hello',
      })
    )
  })
})

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

image.png

  • 静态文件处理
const http = require('http')
const fs = require('fs')
const url = require('url')
const path = require('path')
const port = 3000

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

server.listen(port, () => {
  console.log(`server listens on:${port},${path}`)
})
  • React SSR
const http = require('http')
const React = require('react')
const ReactDOMServer = require('react-dom/server')

function App() {
  return React.createElement('h1', {
    children: 'Hello',
  })
}

const port = 3000

const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'text/html')
  res.end(`
  <!DOCTYPE html>
  <html lang="en">
    <head>
      <title>My App</title>
    </head>
    <body>
      <div id="main">
      ${ReactDOMServer.renderToString(React.createElement(App))}
    </body>
    </html>
  `)
})

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

SSR难点:

  1. 需要处理打包代码;
  2. 需要思考前端代码在服务端运行时的逻辑;
  3. 移除对服务端无意义的副作用,或重置环境。
  • Debug
    V8 Inspector是一个调试协议,为用户和嵌入者提供了广泛的调试功能。
  • 特点:
    • 开箱即用
    • 特性丰富强大
    • 与前端开发一致
    • 跨平台
  • 场景
    • 查看console.log内容
    • breakpoint
    • 高CPU、死循环: cpuprofile
    • 高内存占用:heapsnapshot
    • 性能分析
  Node --inspect 
  Open http://localhost:9229/json

image.png

  • 部署

部署要解决的问题:

  • 守护进程:当进程退出时,重新拉起

  • 多进程:cluster便捷地利用多进程

  • 记录进程状态,用于诊断
    容器环境

  • 通常由健康检查的手段,只需要考虑多核CPU利用率即可

延伸话题

  • 贡献代码
  • 编译Node.js
  • 诊断/追踪
    image.png
  • WASM,NAPI

参考资料:

https://zhuanlan.zhihu.com/p/92305600

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

https://v8.dev/docs/inspector

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值