Node.js学习|青训营笔记

56 阅读3分钟

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

Node.js学习|青训营笔记

Node.js 就是运行在服务端的 JavaScript。

Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。

Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 Javascript 的速度非常快,性能非常好。

Node.js的应用场景(Why)

1. 前端工程化

现状难以替代

2. Web服务端应用

  • 学习曲线平缓,开发效率较高
  • 运行效率接近于常见的编译语言
  • 社区生态丰富及工具链成熟
  • 与前端结合的场景会有优势(SSR)
  • 现状:竞争激烈,node.js有自己独特的优势
  • 3. Electron跨桌面应用

  • 商业应用:vscode,slack,discord,zoom
  • 大型公司内的效率工具
  • 现状:大部分场景在选型时,都值得考虑
  • Node.js运行时结构(what)

    image.png

    异步UI

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

    单线程

  • JS单线程
    实际:JS线程+uv线程池+V8任务线程池+V8 Inspector线程
  • 优点:不用考虑多线程状态同步问题,也就不需要锁;同时还能高效地利用系统资源
  • 缺点:阻塞会产生更多负面影响
    解决方法:多进程或多线程
  • 跨平台

  • 跨平台(大部分功能,API)
  • Node.js跨平台+JS无需编译环境(+Web跨平台+诊断工具跨平台)
    =开发成本低(大部分场景不需要考虑跨平台问题),整体学习成本低
  • 编写Http Server(how)

    安装Node.js

    Mac,Linux 推荐使用nvm,多版本管理

    Windows可以用官方安装包

    官方网站

    编写http Server+Client

    Server:

    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){
    
            }
            res.setHeader('Content-Type','application/json')
            res.end(JSON.stringify({
                echo:reqData.msg||'Hello',
            }))
    
        })
    })
    
    server.listen(port,()=>{
        console.log(`server listen on: ${port}`)
    })
    

    client:

    const http = require('http')
    
    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)
    

    编写静态文件服务器

    const http=require('http')
    const fs=require('fs')
    const path=require('path')
    const url=require('url')
    const { pipeline } = require('stream')
    
    const folderpath = path.resolve(__dirname,'./static')
    
    const server = http.createServer((req,res) => {
        const info = url.parse(req.url)
    
        const filepath = path.resolve(folderpath,'./'+info.path)
    
        const filestream = fs.createReadStream(filepath);
    
        filestream.pipe(res)
    })
    
    const port=3000
    
    server.listen(port,()=>{
        console.log('listening on ',port)
    })
    

    此时地静态文件服务与高性能,可靠的服务相比还差什么?

    1. CDN:缓存+加速
    2. 分布式存储,容灾

    编写React SSR服务

    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>
            <head>
                <title>
                    My application
                </title>
            </head>
            <body>
                ${ReactDOMServer.renderToString(
                    React.createElement(App,{},'my_content')
                )}
            </body>
        </html>`)
    })
    
    const port=3000
    server.listen(port,()=>{
        console.log('listening on ',port)
    })
    
    

    server side render(SSR) 前端页面的产生是由服务器端生成的,我们就称之为服务端渲染

    特点:

    1. 相比传统html模板引擎:避免重复编写代码
    2. 相比SPA(single page application) :首屏渲染更快,SEO友好

    缺点:通常qps较低,前端代码编写时需要考虑服务端渲染情况

    使用inspector进行调试,诊断

    V8 Inspector:开箱即用,特性丰富强大,与前端开发一致,跨平台

    使用代码 node --inspect 执行文件名即可使用 随后进入http://loaclhost:9229进入调试界面

    场景:

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

  • 部署要解决的问题
    • 守护进程:当进程退出时,重新拉起
    • 多进程:cluster编写地利用多进程
    • 记录进程状态,用于诊断
  • 容器环境
    • 通常有健康检查地手段,只需考虑多核cpu利用率即可
  • 延申话题

    node.js贡献代码

    Node.js core 贡献入门

    好处:

    1. 从使用者地角色逐步理解底层细节,可以解决更复杂的问题
    2. 自我证明,有助于职业发展
    3. 解决社区问题,促进社区发展

    难点:花时间

    编译node.js

  • 为什么要学习变异node.js
    • 认知:黑盒到白盒,发生问题有迹可循
    • 贡献代码地第一步
  • 诊断/追踪

  • 诊断是一个低频,重要有挑战地方向,是企业衡量自己能否依赖一门语言地重要参考

  • 技术咨询行业中地热门角色

  • 难点
    • 需要了解node.js的底层,需要了解OS以及各种工具
    • 需要很多经验