从 Node.js 到 Deno:基于 Web 标准构建服务器端 JavaScript 运行时
如果无法正常显示,请先停止浏览器的去广告插件。
1. 从 Node 到 Deno
基于 Web 标准构建服务器端 JavaScript 运行时
迷渡(justjavac)
天津卓朗科技前端技术专家
2. •
Content Title 1
3. 自我介绍
• 我是迷渡,网络ID:justjavac
• 天津卓朗科技,前端技术专家
• Deno 核心代码贡献者
• Deno VSCode 插件作者及主要维护者
4. • Deno 出现的背景与近两年的发展
• Web 标准与 Deno 平台的技术实现
• Deno 未来的发展
• 总结
5. Deno 出现的背景与近两年的发展
6. Node 作者
Deno 作者
7.
8.
9. Ryan Dahl 在 JS Conf 的演讲
•
“10 Things I Regret About Node.js”(2018.06)
10. Node 的问题
• Promise
• 安全问题
• 构建系统(GYP)
• node_modules
• ……
11.
12. Deno 的目标与定位
• 兼容浏览器生态
• 默认安全
• 开箱即用 ts
• 内置 std 标准库
13. Web 标准与 Deno 平台的技术实现
14. Web 标准包括一些什么?
• JavaScript
• TypeScript
• DOM
• BOM
• WEB API
• 其它
15. 一些我们熟知的 Web 标准
• https://html.spec.whatwg.org
• https://console.spec.whatwg.org
• https://encoding.spec.whatwg.org
• https://fetch.spec.whatwg.org
• https://url.spec.whatwg.org
16. Node 平台对标准的追赶与历史包袱
17. request 被废弃
18. request/fetch
• 2009年:在 npm 存在之前 request 库
• 2010年:request 是添加到 npm 的第一批库,周下载量 2200 万(现在)
• ES6: request-promise 发布,周下载量 300万
• 现在:鼓励开发者去使用 fetch-style 的网络库
• node-fetch:2000万
• whatwg-fetch:1000万
19. Node 平台对标准的追赶与历史包袱
+1
20. URL
• Legacy API
• WHATWG API
21.
22. 为什么用 Web API
• Web API 是标准(20多万字的规范)
• 跨平台
23. Node 平台对标准的追赶与历史包袱
+1
24. setTimeout
25. 历史包袱,骑虎难下
• URL 的解决方案是:提供了 2 套不同的 API
• setTimeout:已经有大量的代码依赖 Node.js 的 timer 特性
26. Deno 没有历史包袱
• 基于 Web API 构建
• 兼容浏览器(ES)的模块标准
• Deno 不仅有 fetch、timer,还有 localStorage、Worker、
postMessage、crypto 等
27. Deno 的整体架构
28. Deno 核心组成
• deno_cli:提供 deno 可用的 CLI 命令(deno.exe)
• deno_core:实现 V8-Rust bindings,提供 JsRuntime
• deno_runtime:提供了 Deno.* 的函数
• extensions/*:实现 Web API
29. deno/extensions/*
• console • storage
• crypto • webgpu
• fetch • webidl
• file • websocket
• timers • url
30. Deno 底层如何实现服务器端调用
31.
32. CopyFile 函数的实现:JS
33. CopyFile 函数的实现:Rust
• 从 JS 侧获取参数:from、to
• 检查 from 是否有读权限
• 检查 to 是否有写权限
• 调用 Rust 标准库的 std::fs::copy 完成复制
• 将 Rust 错误转换为 JS/Deno 错误,例如将 InvalidInput 转为 NotFound
34. Rust 代码
• 文件系统、网络、环境变量等的“特权代码”读取由 Rust 实现
• Tokio 维护了一个高效的线程池
• 异步操作使用 Rust 的 Future,这个特性类似于 JavaScript 的
Promises
35. Deno 高层如何实现 Web API 绑定
36. Deno 高层如何实现 Web API 绑定
• 直接使用 JavaScript 编写
• 使用 Rust 编写(native、wasm)
37.
38. File/Blob(Web API)
39.
40.
41. Deno 高层如何实现 Web API 绑定
42. Timer/JS
• JS 记录所有的定时器回调、参数、
• 红黑树实现最近 timer 的快速查找
• 使用 Map 记录所有的 timer ID
• 在 Rust 代码中启动定时器
• 注册 Deno.core.setMacrotaskCallback(timers.handleTimerMacrotask);
43. Timer/Rust
• Rust 获取 JS 传递过来的参数
• Rust 通过 tokio::time::sleep 休眠指定的时间
• 到时间后通过 futures::future::select 创建 future
• 每次只有一个最近的定时器
44. Deno 的安全性与高性能
45. Deno 的安全性
• 使用 Rust 编写,编译器保证内存安全
• 和浏览器与 Node 类似,JS 代码在“沙箱”中运行
• 目前正在讨论类似浏览器的跨域安全问题
• 需要显式的指定代码权限,同时具有类似浏览器的交互式授权方式
46. Deno API 权限
• --allow-env 允许访问环境变量 • --allow-read 允许读取文件
• --allow-hrtime 允许使用高精度时间 • --allow-run 允许运行子进程
• --allow-net 允许访问网络 • --allow-write 允许写文件
• --allow-plugin 允许加载插件
47. ⚠ Deno requests read access to "/foo". Allow? [y/n (y =
yes allow, n = no deny)]
48. Deno 的高性能
• 底层使用 Tokio
• Deno CLI 使用 Rust 编写
• HTTP 模块 Hyper(一个高性能的 Rust 库)
• 一些 std 库使用 wasm(Rust)编写
• 两套 ts 编译器:tsc 和 swc
49. `deno fmt` vs `prettier`
~10x
50. •
Content Title 1
51. `deno lint` vs `eslint`
~100x
52. HTTP Server Throughput
53. 本章小结
• Deno 没有历史包袱
• Deno 有显式的和交互式的权限控制
• Deno 的 HTTP 性能已经超过了 Node,并且还在进一步提升
54. Deno 未来的发展
• Deno 拥抱浏览器生态
• Deno 与 Serverless
• Deno 与 WebAssembly
55. Deno、浏览器、TS
• 只支持 ESM,默认不支持 CommonJS
• 不支持 Import JSON
• 使用 tsc 或者 swc 讲 ts 编译为 js
• 使用 X-TypeScript-Types 为 js 文件提供 .d.ts 类型
56. 很多 CDN 都支持了 Deno
57. Deno 拥抱浏览器生态
• Deno 实现和浏览器相同的 Web API
• 2019 年一份报告指出 npm 上一半以上的包都可以运行在浏览器
• Deno 和浏览器一样使用 esm 加载远程模块
• Deno 支持 import_maps
58. Deno 与 Serverless
• 2021年3月,Ry 官宣成立 Deno 公司,公司第一个业务是 Deno Deploy
• Deno 网站技术栈 Next.js,大部分部署在 Vercel 和 Cloudflare
• deno doc 的服务正在通过 vercel-deno 迁移到 deno
59. deno_serverless_aliyun
冷启~2x, 热启~1x
60. Deno 与 WebAssembly
61. Deno 与 WebAssembly
• 26% 的 WebAssembly 开发者使用 Rust 开发
• Deno 使用 V8 引擎
• deno std 的某些模块是 rust/wasm 写的
• deno/x 已经有了很多高性能的 wasm 模块,例如 sqlite
• deno wasi 已经完成了 80%+
62. 总结
• Deno 基于 Web 标准构建
• Deno 默认安全
• Deno 有显式的和交互式的权限控制
• Deno 具有高性能
63.
64. •
Content Title 1