0x1 Node.js 的应用场景

  1. 前端工程化

    • 打包工具:webpack、vite、esbuild、parce
    • 代码压缩:uglifyjs
    • 语法转换:babeljs,typescript
    • 难以替代
  2. Web 服务端应用
    • 学习曲线平缓,开发效率较高
    • 运行效率接近常见的编程语言
    • 社区生态丰富及工具链成熟(npm)
    • 与前端结合的场景会有优势(SSR)
    • 竞争激烈
  3. Electron 跨端桌面应用
    • 商业应用:vscode、slack、discord、zoom
    • 大型公司内的效率工具
    • 值得考虑

0x2 Node.js 运行时结构

  1. V8、libuv

    • V8:JavaScript Runtime,诊断调试工具(inspector)
    • libuv:eventloop(事件循环)、syscall(系统调用)
  2. 特点

    1. 异步 I/O

      setTimeout(() => {
      console.log('B');
      });
      console.log('A');
      • 当 Node.js 执行 I/O 操作时,会在响应后恢复操作,而非阻塞线程,并占用额外内存等待

      举例:在执行读取文件功能readFile()时,执行fs.readFile()方法后,会将方法的请求异步调用至 Node 中处理的同时,继续执行其他调用,并在执行该功能回调前,将 Node 的处理结果返回回来,从而完成异步 I/O

    2. 单线程

      function fibonacci(num: number): number{
      if(num == 1 || num == 2)
      return 1;
      return fibonacci(num - 1) + fibonacci(num - 2);
      } fibonacci(2)
      fibonacci(3)
      • JS 单线程

        • 实际情况:JS 线程+uv 线程+V8 任务线程池+V8 Inspector 线程
      • 优点
        • 不用考虑多线程状态同步问题,不需要锁
        • 比较高效地利用系统资源
      • 缺点
        • 阻塞会产生更多负面影响
    3. 跨平台

      const net = require('net');
      const socket = new net.Socket('/tmp/scoket.sock')
      • Node.js 跨平台+JS 无需编译环境(+Web 跨平台+诊断工具跨平台)=开发和整体学习成本低

0x3 编写 Http Server

  1. 安装 Node.js

    推荐使用 nvm 安装 Node.js,可以有效解决跨版本问题(Windows 系统使用 nvm4w)

  2. 编写 Http Server + Client,进行收发 GET、POST 请求

    1. Http Server

      项目:Hello World

      /* filename: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}`)
      })
      /* filename:jsonServer.js */
      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) {
      // receive invalid json data
      }
      res.setHeader('Content-Type', 'application/json');
      res.end(JSON.stringify({
      echo: reqData.msg || 'Hello',
      }))
      })
      })
      server.listen(port, () => {
      console.log(`server listens on: ${port}`)
      })
  3. 编写静态文件服务器

    const http = require('http')
    const fs = require('fs')
    const path = require('path')
    const url = reuqire('url') 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}`)
    })
  4. 编写 React SSR 服务

    • SSR(Server Side Rendering) 特点

      • 相比传统 HTML 模板引擎,可以避免重复编写代码
      • 相比 SPA(Single Page Application),可以更快渲染首屏,对 SEO(Search Engine Optimization) 友好
      • 缺点:通常 qps 较低,编写代码时需要考虑服务端渲染情况

    举例:

    HTML:

    const http = require('http')
    const port = 3000
    const server = http.createServer((req, res) => {
    res.setHeader('Content-Type', 'text/html')
    res.end(`
    <!DOCTYPE html>
    <html>
    <head>
    <title>Title</title>
    </head>
    <body>
    <p>Content</p>
    </body>
    </html>
    `)
    }) server.listen(port, () => {
    console.log(`server listens on: ${port}`)
    })

    替换成 React:

    const http = require('http')
    const React = require('react')
    const ReactDOMServer = require('react-dom/server')
    function App() {
    return React.createElement('p', {
    children: 'Hello'
    })
    }
    const port = 3000
    const server = http.createServer((req, res) => {
    res.setHeader('Content-Type', 'text/html')
    res.end(`
    <!DOCTYPE html>
    <html>
    <head>
    <title>Title</title>
    </head>
    <body>
    <div id="main">
    ${ReactDOMServer.renderToString(React.createElement(App))}
    </div>
    </body>
    </html>
    `)
    }) server.listen(port, () => {
    console.log(`server listens on: ${port}`)
    })
    • SSR 难点:

      1. 需要打包处理

        require('./static/style.css')

      2. 需要思考前端代码在服务端运行时的逻辑

        async componentDidMount() {
        const res = await fetch('http://my.server.domain')
        }
      3. 移除对服务端无意义的副作用,或重置环境

  5. 适用 Inspector 进行调试、诊断

    • V8 Inspector

      • node --inspect
      • open http://localhost:9229/json
    • 场景
      • 查看console.log()内容
      • 断点
      • 高 CPU、死循环:cpuprofile
      • 高内存占用:heapasnapshot
      • 性能分析
  6. 部署

    • 需要解决的问题

      • 守护进程:当进程退出时,重新拉起
      • 多进程:cluster 便捷地利用多进程
      • 记录进程状态,用于诊断
    • 容器环境
      • 通常有健康检查的手段,只需考虑多核 CPU 利用率

0x4 延申

  1. Node.js 贡献代码

    • 好处

      • 理解底层细节
      • 自我证明
      • 解决社区问题
    • 难点
      • 费时
  2. 编译 Node.js

    • 从认知角度:发生问题时能有迹可循
    • 是贡献代码的第一步
    • 如何编译
      • ./config && make install
  3. 诊断 / 追踪

    • 诊断

      • 低频但重要,充满挑战性的方向
      • 利于企业衡量是否可依赖某种语言的重要参考
    • 难点

      • 需要理解 Node.js 底层、操作系统以及各种工具

      • 需要经验

  4. WASM、NAPI

    • WASM:WebAssembly
    • NAPI:NewAPI

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

-End-

Node.js 与前端开发实战的更多相关文章

  1. Node JS后端项目开发与生产环境总结

    原文地址:Node JS后端项目开发与生产环境总结 Node JS常用后端框架有express.koa.sails.国产框架有个egg js,已经在cnode投入生产了,还有个think js,类似t ...

  2. Web前端开发实战6:CSS实现导航菜单结合二级下拉式菜单的简单变换

    前面几篇博文都在讲导航菜单和二级下拉式菜单,事实上有非常多方法都能够实现的.详细的情况还要视情况而定. 在后面学习到jQuery框架之后,会有更丰富的动画效果.因为在学习Ajax和jQuery的初步阶 ...

  3. 深入浅出node.js游戏服务器开发1——基础架构与框架介绍

    2013年04月19日 14:09:37 MJiao 阅读数:4614   深入浅出node.js游戏服务器开发1——基础架构与框架介绍   游戏服务器概述 没开发过游戏的人会觉得游戏服务器是很神秘的 ...

  4. Node.js 从零开发 web server博客项目[express重构博客项目]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  5. Node.js 从零开发 web server博客项目[安全]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  6. Node.js 从零开发 web server博客项目[日志]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  7. Node.js 从零开发 web server博客项目[登录]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  8. Node.js 从零开发 web server博客项目[项目介绍]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  9. JS高级前端开发群加群说明及如何晋级

    JS高级前端开发群加群说明 一.文章背景: 二. 高级群: 三. 加入方式: 四. 说明:   一.文章背景: 去年年初建了几个群,在不经意间火了,一直排在“前端开发”关键字搜索结果第一名.当然取得这 ...

  10. 前端进阶试题css(来自js高级前端开发---豪情)既然被发现了HOHO,那我就置顶了嘿嘿!觉得自己技术OK的可以把这套题目做完哦,然后加入高级前端的社区咯

    http://www.cnblogs.com/jikey/p/4426105.html js高级前端开发加群方法(此群很难进,里面纯技术,严禁广告,水群) 完整题目做完发邮箱(jikeytang@16 ...

随机推荐

  1. Docker的使用记录

    开始 这是第一个尝试在Leanote上面编写文章,我觉得最重要的事情就是能够保证md文件是能够移植的,否则如果这个软件不靠谱的话,我还能把文章移动到别的地方去.所以先写一篇文章看看效果如何,方便不方便 ...

  2. Android---TextView基础属性 + 跑马灯的三种方式

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_wid ...

  3. Java 常用类 String的常用方法(2)

    1 /** 2 * String 常用方法(2) 3 * boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束 4 * boolean startsWith ...

  4. python 打包 exe文件

    操作步骤: 先安装pyinstaller,在终端中输入pip install pyinstaller即可. 打包程序: pyinstaller --console --onefile 7.py 在di ...

  5. Github无法读取远程仓库

    主页 个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/ Git无法访问 今早起来访问Github炸了,Git不能用了,提示: ...

  6. 音标 舌侧音 /l/ 的发音 - 英语

    音标 舌侧音 /l/ 的发音 这个音标 首先确定下 就是一个音 发 了(注意 发音方式不是中文的了,是英文的了) 注意发音方式很重要 中文 '了',重点在 偏鼻音(发射方向为前上方) 英文 '了',重 ...

  7. vscode 格式化 vue 和 js代码 vetur prettier beautify

    这个文档 不涉及eslint 只专注自动格式化 格式化个性化需求: js中 自动去分号 js中 双引号变单引号 最大空换行数 是2 vue template中 属性自动折行 vue 的自动格式化 需要 ...

  8. 01-【HAL库】STM32实现串口打印

    一.什么是串口 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输 ...

  9. WPF自定义Panel:让拖拽变得更简单

    在 WPF 应用程序中,拖放操作是实现用户交互的重要组成部分.通过拖放操作,用户可以轻松地将数据从一个位置移动到另一个位置,或者将控件从一个容器移动到另一个容器.然而,WPF 中默认的拖放操作可能并不 ...

  10. C++获取任务管理器信息,封装成DLL,C#调用例子

    C++代码 pch.h // pch.h: 这是预编译标头文件. // 下方列出的文件仅编译一次,提高了将来生成的生成性能. // 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏 ...