Node.js 与前端开发实战
0x1 Node.js 的应用场景
- 前端工程化
- 打包工具:webpack、vite、esbuild、parce
- 代码压缩:uglifyjs
- 语法转换:babeljs,typescript
- 难以替代
- Web 服务端应用
- 学习曲线平缓,开发效率较高
- 运行效率接近常见的编程语言
- 社区生态丰富及工具链成熟(npm)
- 与前端结合的场景会有优势(SSR)
- 竞争激烈
- Electron 跨端桌面应用
- 商业应用:vscode、slack、discord、zoom
- 大型公司内的效率工具
- 值得考虑
0x2 Node.js 运行时结构
V8、libuv
- V8:JavaScript Runtime,诊断调试工具(inspector)
- libuv:eventloop(事件循环)、syscall(系统调用)
特点
异步 I/O
setTimeout(() => {
console.log('B');
});
console.log('A');
- 当 Node.js 执行 I/O 操作时,会在响应后恢复操作,而非阻塞线程,并占用额外内存等待
举例:在执行读取文件功能
readFile()时,执行fs.readFile()方法后,会将方法的请求异步调用至 Node 中处理的同时,继续执行其他调用,并在执行该功能回调前,将 Node 的处理结果返回回来,从而完成异步 I/O单线程
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 线程
- 优点
- 不用考虑多线程状态同步问题,不需要锁
- 比较高效地利用系统资源
- 缺点
- 阻塞会产生更多负面影响
- JS 单线程
跨平台
const net = require('net');
const socket = new net.Socket('/tmp/scoket.sock')
- Node.js 跨平台+JS 无需编译环境(+Web 跨平台+诊断工具跨平台)=开发和整体学习成本低
0x3 编写 Http Server
安装 Node.js
推荐使用 nvm 安装 Node.js,可以有效解决跨版本问题(Windows 系统使用 nvm4w)
编写 Http Server + Client,进行收发 GET、POST 请求
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}`)
})
编写静态文件服务器
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}`)
})
编写 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 难点:
需要打包处理
require('./static/style.css')需要思考前端代码在服务端运行时的逻辑
async componentDidMount() {
const res = await fetch('http://my.server.domain')
}
移除对服务端无意义的副作用,或重置环境
- SSR(Server Side Rendering) 特点
适用 Inspector 进行调试、诊断
- V8 Inspector
node --inspectopen http://localhost:9229/json
- 场景
- 查看
console.log()内容 - 断点
- 高 CPU、死循环:
cpuprofile - 高内存占用:
heapasnapshot - 性能分析
- 查看
- V8 Inspector
部署
- 需要解决的问题
- 守护进程:当进程退出时,重新拉起
- 多进程:cluster 便捷地利用多进程
- 记录进程状态,用于诊断
- 容器环境
- 通常有健康检查的手段,只需考虑多核 CPU 利用率
- 需要解决的问题
0x4 延申
Node.js 贡献代码
- 好处
- 理解底层细节
- 自我证明
- 解决社区问题
- 难点
- 费时
- 好处
编译 Node.js
- 从认知角度:发生问题时能有迹可循
- 是贡献代码的第一步
- 如何编译
./config && make install
诊断 / 追踪
诊断
- 低频但重要,充满挑战性的方向
- 利于企业衡量是否可依赖某种语言的重要参考
难点
需要理解 Node.js 底层、操作系统以及各种工具
需要经验
WASM、NAPI
- WASM:WebAssembly
- NAPI:NewAPI
-End-
Node.js 与前端开发实战的更多相关文章
- Node JS后端项目开发与生产环境总结
原文地址:Node JS后端项目开发与生产环境总结 Node JS常用后端框架有express.koa.sails.国产框架有个egg js,已经在cnode投入生产了,还有个think js,类似t ...
- Web前端开发实战6:CSS实现导航菜单结合二级下拉式菜单的简单变换
前面几篇博文都在讲导航菜单和二级下拉式菜单,事实上有非常多方法都能够实现的.详细的情况还要视情况而定. 在后面学习到jQuery框架之后,会有更丰富的动画效果.因为在学习Ajax和jQuery的初步阶 ...
- 深入浅出node.js游戏服务器开发1——基础架构与框架介绍
2013年04月19日 14:09:37 MJiao 阅读数:4614 深入浅出node.js游戏服务器开发1——基础架构与框架介绍 游戏服务器概述 没开发过游戏的人会觉得游戏服务器是很神秘的 ...
- Node.js 从零开发 web server博客项目[express重构博客项目]
web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...
- Node.js 从零开发 web server博客项目[安全]
web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...
- Node.js 从零开发 web server博客项目[日志]
web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...
- Node.js 从零开发 web server博客项目[登录]
web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...
- Node.js 从零开发 web server博客项目[项目介绍]
web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...
- JS高级前端开发群加群说明及如何晋级
JS高级前端开发群加群说明 一.文章背景: 二. 高级群: 三. 加入方式: 四. 说明: 一.文章背景: 去年年初建了几个群,在不经意间火了,一直排在“前端开发”关键字搜索结果第一名.当然取得这 ...
- 前端进阶试题css(来自js高级前端开发---豪情)既然被发现了HOHO,那我就置顶了嘿嘿!觉得自己技术OK的可以把这套题目做完哦,然后加入高级前端的社区咯
http://www.cnblogs.com/jikey/p/4426105.html js高级前端开发加群方法(此群很难进,里面纯技术,严禁广告,水群) 完整题目做完发邮箱(jikeytang@16 ...
随机推荐
- C++ //常用算术生成算法 //#include<numeric> accumulate //fill //向容器中填充指定的元素
1 //常用算术生成算法 //#include<numeric> accumulate 2 //fill //向容器中填充指定的元素 3 #include<iostream> ...
- 从华为WeAutomate数字机器人论坛,看政企领域的“政务新智理”
从华为WeAutomate数字机器人论坛,看政企领域的"政务新智理" 从政务治理到"政务新智理",华为WeAutomate在政务领域的思考与实践 华为WeAut ...
- 面试准备不充分,被Java守护线程干懵了,面试官主打一个东西没用但你得会
写在开头 面试官:小伙子请聊一聊Java中的精灵线程? 我:什么?精灵线程?啥时候精灵线程? 面试官:精灵线程没听过?那守护线程呢? 我:守护线程知道,就是为普通线程服务的线程嘛. 面试官:没了?守护 ...
- 摆脱鼠标系列 Trigger Suggest 快捷键 改成 Shift + Space
摆脱鼠标系列 Trigger Suggest 快捷键 改成 Shift + Space 看marp插件的时候,发现用ctrl + space 自动提示,但是我这里是输入法
- C#实现一个简单的日志类
目录 自定义日志类 NLog版本的日志类 Serilog版本的日志类 上个月换工作,新项目又要重新搭建基础框架,把日志实现部分单独记录下来方便以后参考. 自定义日志类 代码大部分使用ChatGPT生成 ...
- 【python】使用百度api进行音频文件转写
[python]使用百度api进行音频文件转写 脚本目标: 智能云的音频文件转写文档只给了个demo,每次只能传1分钟以内的音频啥的,不好直接用,简单打包一下,做到把音频放文件夹,直接出转写结果就行了 ...
- 解决jenkins Git Publisher自动打tag的问题
简单配置一下 然后开始构建,然后报错如下 The recommended git tool is: NONE using credential 647ee613-5032-4894-aaeb-fe07 ...
- B站Aimls的JavaFx教程目录合集
B站里有时候不太好去找资源,用JS爬了下,整出标题和链接,方便后续查询某个知识点的使用! JavaFX视频教程第1课,hello world JavaFX视频教程第2课,application的启动方 ...
- 浅谈Rust数据所有权
Rust的目标之一,是能够作为一门内存高效且内存安全的语言.本文我们将重点关注Rust关于"内存高效"的语言设计,让读者能够建立起对Rust的基本认知. 内存高效 一个不恰当的比喻 ...
- WPF状态保存
由于WPF做客户端的时候,它不像BS那样有Session,Cookie给你使用,所以保存状态你首先想到的就是数据库了. 但是你不可能什么都放在数据库,为此还专门为它建立一张表. 而WPF中能用到的除了 ...