Node.js 是个啥?

news2025/1/12 15:57:58

趣学 Node.js - 死月 - 掘金小册带你重新体悟 Node.js 之美。「趣学 Node.js」由死月撰写,1923人购买https://s.juejin.cn/ds/SYVvuDw/

在这里,我们先装作对 Node.js 不了解,从头来过吧。你有没有假装不了解 Node.js 我不知道,但我就当作你不了解了。

本节会跟大家详细剖析一下 Node.js 到底是个什么东西。在它官网上是这么讲的:

Node.js® is an open-source, cross-platform JavaScript runtime environment.

翻译过来:Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。这里要敲黑板划重点了,JavaScript 运行时环境

JavaScript 运行时环境

网上其实有很多人图一时嘴快,包括很多招聘的 JD 也都这么写(估计你也没少见过):

熟悉(精通、blahblah……)Node.js 语言。

这其实是一个非常常见的常识错误。Node.js 并不是语言,而是一个 JavaScript 运行时环境,它的语言是 JavaScript。这就跟 PHP、Python、Ruby 这类不一样,它们既代表语言,也可代表执行它们的运行时环境(或解释器)。

Node.js 与 JavaScript 真要按分层说,大概是这么个意思吧,如下图:

这里我们从下往上梳理。

  • 最下面一层是脚本语言规范(Spec) ,由于我们讲的是 Node.js,所以这里最下层只写 ECMAScript。

  • 再往上一层就是对于该规范的实现了,如 JavaScript、JScript 以及 ActionScript 等都属于对 ECMAScript 的实现。

  • 然后就是执行引擎,JavaScript 常见的引擎有 V8、SpiderMonkey、QuickJS 等(其相关 Logo 如下图所示)。

  • 最上面就是运行时环境了,比如基于 V8 封装的运行时环境有 Chromium、Node.js、Deno、CloudFlare Workers 等等。而我们所说的 Node.js 就是在运行时环境这一层。

可以看到,JavaScript 在第二层,Node.js 则在第四层。

冷知识

几年前微软的 Edge 浏览器还在用 Chakra 引擎的时候,Node.js 其实有个官方的 Chakra 发行版。其原理是,为 Chakra 引擎做一层 V8 的适配层(Shim API)。后来 Edge 浏览器转投 V8 怀抱,微软也就放弃了对 Chakra 引擎的维护。Node.js 的 Chakra 发行版自然而然就不维护了,而 Chakra 引擎也交予社区发展。

  • Chakra 仓库:github.com/chakra-core…
  • Node.js Chakra 仓库:github.com/nodejs/node…

本节关于 JavaScript、ECMAScript 的掰扯点到为止。如果大家想多看看关于这一块内容的八卦的话,推荐大家去读一下《JavaScript 20 年》。

总之,以后出去千万别再说 “Node.js 语言”这个词啦,要说 “Node.js 运行时”。

Node.js 原初

Node.js 是由 Ryan Dahl 在 2009 年初次发布的。但是关于 Node.js 为什么会在这个时间点发布,这得回溯到更早,我们还是得扒一扒一些历史。

JavaScript 本身是在 1995 年发行的,由 Brendan Eich 花了不到两周时间搞出一个初始版本,能跑在网景浏览器中做一些动态的效果等。本来 JavaScript 叫 Mocha,后来改名 LiveScript,再后来为了蹭 Java 热度,改成了 JavaScript。

兜兜转转十多年,JavaScript 一直是运行在浏览器里面的简单语言,哪怕在 1997 年,它就开始 ECMAScript 标准化。因为跑在浏览器里,又是做一些简单的操作,所以性能什么的无关紧要。这一切的转折点在 2008 年。

当年浏览器大战在白热化阶段,国内各种套皮的浏览器不算,最大的主战场在 IE、FireFox、Opera 等中间。2008 年谷歌入局,推出了 Chrome 浏览器及其开源版本 Chromium。以前的浏览器中,JavaScript 虽然重要,但是也没有到极致优化的程度。但是 Chrome 的出现搭载上了 V8 引擎,而这个引擎的开发小组是一群正儿八经的编程语言专家。当时主导这个项目的核心工程师是 HotSpot VM 和 Strongtalk 的工程师 Lars Bak。自此,JavaScript 逐渐摆脱了它在脚本语言中性能也很低的名头。

书归正传,JavaScript 性能开始有了质的飞跃,自然就有人瞄上了服务端领域。比较像 PHP、Python、Ruby 这些也都是脚本语言,也都在服务端领域吃得开;还有像在游戏领域大行其道的 Lua,等等。

基于上面的这些原因,Node.js 在 2009 年横空出世便显得有迹可循了。但这玩意儿从传入国内并开始慢慢火起来,还是经历了一两年的。就像天猪,是在 2011 年无意间刷 OSChina 资讯时看到 Node.js 的新闻,当时他第一反应是:“又一个 jQuery 轮子?切!”没成想,无聊时候随意研究了一下就走上了这条不归路。

Node.js 思潮

上面讲了这么多,Node.js 到底适合做什么呢?其实这个问题的答案随着时间推移是一直在变化的

在 Node.js 创造之初,主推的是“单线程”“天然异步 API”下的高性能运行时。单线程,意味着业务逻辑不用考虑各种锁的问题;天然异步 API,意味着可以方便地处理并发。这种方式自然适合做服务端

事实上,Ryan 的确也是这么想的。

Node.js 提供了基于事件驱动和非阻塞的接口,可用于编写高并发状态下的程序,而且 JavaScript 的匿名函数、闭包、回调函数等特性就是为事件驱动而设计的。

Node.js 的一些内置模块如 httpnetfs 等,就是为服务端设计的。无论是 HTTP 服务端,还是其他一些 TCP、UDP 的服务端。各种框架开始冒出,最有名的如 Express.js、Koa.js 等,以及像 LoopBack 这类在国内可能并不那么有名的。与其说框架,Express.js 和 Koa.js 更像是对于 HTTP 服务端 API 的上层封装,实际上远没到框架级别。

除了 HTTP 服务,RPC 服务自然也是可以的。各种 RPC 的服务在各大公司都有各自的最佳实践。其实 RPC 与 HTTP 类似,都是要异步处理并发。只不过可能在长短连接上会有不同,在协议的序列化与反序列化上不一样而已。各种社区流行的 RPC 协议也都有 Node.js 的 SDK,如 gRPC 等。

都说 2011、2012 年左右 Node.js 在国内开始萌芽,2013、2014 年开始爆炸,其实是差不多的。在服务端领域,网易也曾在 2012 年末开源了基于 Node.js 的分布式游戏服务端引擎 pomelo。这个引擎的开源和商用,也昭示着其的确可以在游戏领域也吃得开。

2014~2015 年:Node.js 与 io.js

Node.js 社区其实在 2014 年底的时候经历过一波社区分裂。有一部分核心开发者从 Node.js v0.12 的源码 Fork 出来,发布 io.js。起因是当时的 GateKeeper 者 Isaac Z. Schlueter 卸任之后,Node.js 的发展(发版)变得缓慢,当时控制 Node.js 的公司 Joyent 又不作为,Node.js v1.0 遥遥无期;再加上本身社区处于一个急速上升期,这自然就引发社区的不满,于是开始自己搞。但又由于可能存在的商标问题,Fork 出来的项目就叫 io.js 了。

io.js 采用 CTC(核心技术委员会,Core Technical Committee)模式来运作,由他们来决定技术的方向、项目管理和流程、贡献的原则、管理附加的合作者等。并引入 Core Collaborators,代码仓库的维护不仅仅局限在几个核心贡献者手中。不过现在 Node.js 已经没有 CTC 了,而是转成了 TSC(技术指导委员会,Technical Steering Committee)。

io.js 在 2015 年初就马上发布了 v1.0 版本,后续 v2.0 版本也很快就跟上。彼时 Node.js 还在 v0.13、v0.14 徘徊。后来 Node.js 与 io.js 达成了和解,Joyent 公司做出了让步,并将 Node.js 迁移至基金会。后续 Node.js 和 io.js 在合并之前仍各自发展,直至最终融合。

下图是目前 Node.js 官方文档站里面列出的“版本们”,我们可以看到 Node.js v0.12.x 之后,缺失了 v1.x、v2.x 和 v3.x。这就是 Node.js 与 io.js 分裂时期,合并之后,Node.js 直接从 v0.12.x 版本跨越到了 v4.x。

除了服务端外,Node.js 提供的形如 ttyreplreadline 等内置模块,同时又为创造各种工具提供了方便的能力。前端生态也因此变得庞大,虽然现在 Rust 开始乱入,但泛前端领域自身的 CLI 大抵都还是 Node.js 写的。

Node.js 还有一个用途就是桌面端。一路发展过来,从 NW.js(前身 node-webkit)到 Electron.js(前身 Atom Shell),以及之前网易也搞过一个叫 heX 的桌面端运行时,之前的有道词典就是基于他们自己的 heX 开发的。heX 一样也是诞生于百花齐放、神仙打架的年代,2013 年。那个时候 Node.js 的土壤简直不要太好。其实很多有名的软件都是基于 Electron 开发的,比如微软的代码编辑器 Visual Studio Code,又比如 1Password、钉钉等。

桌面端应用以外,Node.js 一样有可能在端游上产生价值。Lua、Python、Ruby 都能写端游(泛指,并不只指各种次时代、巨型游戏),同为脚本语言,JavaScript 自然也可以,而且有 V8 的加持至少性能上不会劣化。除了通过 WebGL 在浏览器里面写前端页面上的游戏、通过 Electron 封装成看起来像端游的游戏,JavaScript 自然还能通过 Node.js 的 binding 去使用 OpenGL 甚至 DirectX 去写货真价实桌面上的游戏,比如 sfml.js(一些小游戏,以及一个 NES 模拟器)。

但目前来看,Node.js 最大的场景已经变成了泛前端领域的工具链了。也正是因为泛前端生态的涌入,Node.js 的趋势越来越往前端生态的补足发展,加上桌面端领域,统称泛前端,服务端领域日渐式微。这个时间点基本上就是在 Node.js 合并快速发展的一两年左右,也就是 2017、2018 年左右。

  • 一方面是泛前端生态的涌入,让更多的前端开发者有了更多、更广泛的 Node.js 使用场景,从而出现了国内 Node.js 后端开发者的断层现象,现在招一个 Node.js 后端开发真的是太难了,找来找去就是那么几个熟悉的面孔。
  • 另一方面,其他语言或框架也逐渐更现代化起来,原来 Node.js 的异步机制已不再是一家独大和独易用。

我写本小册的一个私心,就是想填补国内这块开发者的断层。

后来 Serverless 出现了,Node.js 再次迎来一波焕新。相较于其他的运行时(比如 Java),它在冷启动速度上有着绝对的优势,所占资源也小很多。再加上这两年 Node.js 在冷启动速度上下了比较大的功夫,从 Node.js 自身的 Snapshot 再到用户侧 Snapshot,一一解决。所以很多 Serverless 或者 FaaS 场景下,大家都乐意用 JavaScript 来写,写得快,弹得也快。这里的 JavaScript 底层自然就是指 Node.js 了。当然也有不是 Node.js 的,这个是后话。

一圈看下来,Node.js 可适配的领域涵盖了泛前端和后端,传统服务和 Serverless,工具、商业、游戏等等。什么?你说机器学习?看看 pipcook。阿特伍德定律有云:

Any application that can be written in JavaScript, will eventually be written in JavaScript.

虽然各领域的板子长短参差不齐,但好歹该有的能力都有了。毕竟底层是 C++ 实现的,想要什么能力,binding 一个就好了。

总之,即使你别的语言都不会,只会 JavaScript 也没关系。虽然不一定精,但有了 Node.js 之后,好歹自己想要什么都能自给自足了。

Node.js 与 Web-interoperable Runtime

既然这两年风口是 Serverless,这里就不得不提一下 Web-interoperable Runtime,以及 Node.js 与它的关系。

Web-interoperable Runtime 简称 Winter,Web 可互操(cāo)运行时。这里有一个核心的单词叫 interoperable,就是可互操。什么是可互操?就是运行时之间是可以互相替代、互相兼容的。各种浏览器之间就是 interoperable,经过标准化之后,大家 API 长的都一样,这就是所谓的互通性。

Winter 就是针对服务端 JavaScript 提出的一种规范。只要大家都遵循了 Winter 规范,那么整个生态又是可共享的。因为好多厂商都基于 V8 做了 JavaScript 的运行时,但是后来经过标准化、规范化之后,国际上的几家厂商就一起给它起了一个新的名字,并且开始做一些标准化的事情,组建了一个组织叫做 WinterCG(Web-interoperable Runtimes Community Group),它是由几家国际公司联合起来搞的 W3C 下的一个社区组,致力于做 Web-interoperable Runtime 标准化。

大家可以在 WinterCG 的官网首页上看有哪几个公司正在遵循 Winter 的标准做他们的运行时,如下图所示:

Winter 目前遵循的路线就是,取 Web API(Service Worker)的子集,并不定义新的 API。当然运行时自己想新增也是没问题的,只要保证满足 Winter 的 API 就可以算是合格的 Web-interoperable Runtime 了。

相较于轻量级的 Winter 来说,其实 Node.js 还是显得重了。比如,阿里巴巴动辄亚毫秒级进程冷启动速度的 Noslate,以及字节跳动用于 FaaS、边缘等业务的 Hourai.js,都属于更轻量级的 Winter。市面上有名的 Winter 还有 CloudFlare Workers。

不过其实 Node.js 也正在往 Winter 标准上靠,比如它实现了 WHATWG 的 URLTextEncoderTextDecoderfetch 等等。这是后话了。大家都在往标准上做,往标准上靠,殊途同归。

有了 Web-interoperable Runtime 的加持,Node.js 也能在后续持续投入和使用广大 Winter 共同的社区生态,这也算是为未来的 Serverless 架构铺路了。

小结

Node.js 经过了十多年发展,其可覆盖的领域已非常完善。从最开始的专注于服务端,到后面泛前端工具链、桌面端、游戏等一应俱全。部署模式也从传统应用到了现在的 Serverless。但如果想要更深地理解自己在写的代码,还是需要对 Node.js 有一个更深的了解,而不仅仅是看文档、用 API。

知其然,知其所以然。这是本小册所期望带给大家的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/379632.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

界面开发(2)--- 使用PyQt5制作用户登陆界面

使用PyQt5制作用户登陆界面 上篇文章已经介绍了如何配置PyQt5环境,这篇文章在此基础上展开,主要记录一下如何使用 PyQt5 制作用户登陆界面,并对一些基础操作进行介绍。 下面是具体步骤,一起来看看吧! 1. 打开 Pychar…

【IoT】2023裁员潮还在继续,构建规划能力也许是一剂良方

今天要分享的主题是华为的市场管理方法论。 市场管理这个词总体来说还是有些抽象,本质上来看或者说从个人的角度来看,其实就是一种规划的能力。 无论是创业,还是作为职场人,规划能力必将是你不可或缺的一种基础能力。 尤其是在这样…

Maven说明

目录 1.说明 2.详细说明 3.Maven模型 4.Maven常用的命令 5.Maven生命周期 6.Maven坐标 7.依赖管理与依赖范围 1.说明 Maven是专门用于管理和构建Java项目的工具,它是基于项目对象模型(POM)的概念,主要功能有: 提供了一套标准化的项目…

Ubuntu 下NGINX 的简单使用

1.NGINX的安装与卸载 1.1.安装NGINX apt-get install nginx1.2.NGINX操作命令 service nginx start #启动 service nginx reload #重新加载配置文件 service nginx restart #重启 service nginx status #查看运行状态 1.3.卸载NGINX apt-get remove nginx nginx-common #…

28 openEuler管理网络-配置主机名

文章目录28 openEuler管理网络-配置主机名28.1 简介28.2 使用hostnamectl配置主机名28.2.1 查看所有主机名28.2.2 设定所有主机名28.2.3 设定特定主机名28.2.4 清除特定主机名28.2.5 远程更改主机名28.3 使用nmcli配置主机名28 openEuler管理网络-配置主机名 28.1 简介 hostn…

XXL-JOB的基本使用

1、执行器 1.1下边配置执行器 下边配置执行器&#xff0c;执行器负责与调度中心通信接收调度中心发起的任务调度请求。 1、首先在媒资管理模块的service工程添加依赖&#xff0c;在项目的父工程已约定了版本2.3.1 XML <dependency><groupId>com.xuxueli</gro…

【Web安全社工篇】——水坑攻击

作者名&#xff1a;白昼安全主页面链接&#xff1a; 主页传送门创作初心&#xff1a; 以后赚大钱座右铭&#xff1a; 不要让时代的悲哀成为你的悲哀专研方向&#xff1a; web安全&#xff0c;后渗透技术每日鸡汤&#xff1a;努力赚钱不是因为爱钱“水坑攻击”&#xff0c;黑客攻…

CVPR 2023 接收结果出炉!再创历史新高!录用2360篇!(附10篇最新论文)

点击下方卡片&#xff0c;关注“CVer”公众号AI/CV重磅干货&#xff0c;第一时间送达点击进入—>【计算机视觉】微信技术交流群2023 年 2 月 28 日凌晨&#xff0c;CVPR 2023 顶会论文接收结果出炉&#xff01;这次没有先放出论文 ID List&#xff0c;而是直接 email 通知作…

【C语言】位段

位段 一.简介 位段和结构体很相似。不同的是&#xff1a; 位段的成员&#xff1a;成员名 : 数字且其成员必须是整型(char、int、unsigned int……) 示例&#xff1a; struct S {char a : 3;char b : 2;char c : 7; };S就是一个位段类型&#xff0c;其成员a为占3个比特位的…

【趣味学Python】Python基础语法讲解

目录 编码 标识符 python保留字 注释 实例(Python 3.0) 实例(Python 3.0) 行与缩进 实例(Python 3.0) 实例 多行语句 数字(Number)类型 字符串(String) 实例(Python 3.0) 空行 等待用户输入 实例(Python 3.0) 同一行显示多条语句 实例(Python 3.0) 多个语句构…

【Day02数据结构 空间复杂度】

最近太忙了都好久没有更新博客了,太难了,抽空水一篇文章,大佬们多多支持. 上篇:时间复杂度分析 目录 前言 一、空间复杂度概念&#xff1f; 二、实例展示 三、.有复杂度要求的算法题练习 1.题目链接&#xff1a;力扣--消失的数字 2.题目链接&#xff1a;力扣--旋转数组 总结: 1…

去课工场成都基地学Java,可行吗?

当然可行&#xff0c;不管是你选择自学Java&#xff0c;还是去培训机构学习都是非常不错的职业选择。选择好赛道能让你的未来收获更多。 2023年了&#xff0c;随着数字经济的发展&#xff0c;互联网已经渗入我们生活工作的方方面面&#xff0c;现在即使是吃个饭点个餐很多时候…

SpringBoot解决跨域方式

跨域是指在 Web 应用中&#xff0c;一个服务器资源或应用访问另一个服务器资源或应用的资源时候。由于浏览器的同源策略&#xff0c;一般情况下同一个域中的网站或应用可以互相访问资源&#xff0c;但跨域访问会被浏览器拒绝。浏览器出于安全考虑&#xff0c;会限制跨域访问&am…

深度学习领域的多任务学习综述

文章目录前言1. 什么是多任务学习&#xff1f;2. 为何要使用多任务学习&#xff1f;3. 多任务学习有哪些类型&#xff1f;3.1 基于硬参数共享的多任务学习3.2 基于软参数共享的多任务学习4. 为什么多任务学习能提升模型的性能&#xff1f;4.1 隐藏数据扩充&#xff08;Implicit…

关于sudo配置

前言这里做一个小补充&#xff0c;主要讲一下关于利用sudo对指令提权以及普通用户无法使用sudo指令的问题。在前面的文章【Linux】一文掌握Linux权限中&#xff0c;我们讲到了关于权限的一些问题。我们知道root身份下&#xff0c;一切畅通无阻&#xff0c;而权限只是用来限制我…

urp SpotLight 衰减方式扩展

背景&#xff1a; 解决默认spotLight 的衰减模式下&#xff0c; 在距离灯光特别近的时候&#xff0c;灯光过爆的情况 解决方法&#xff1a; 修改SpotLight的衰减方式 下图是unity给出的几种衰减模式以及图示&#xff1a; 其中InverseSquare是当前2021.2 unity版本中urp(12.1…

相恨见晚的办公插件神器,颠覆我们对辅助工具的认知

不坑盒子 这是一个非常好用的插件工具&#xff0c;专门应用在Word文档和wps&#xff0c;支持Office 2010以上的版本&#xff0c;操作也简单且实用。 不坑盒子下载及使用说明 一键排版功能 像是下面的自动排版功能&#xff0c;可以在配置里面先设定好需要的格式&#xff0c;…

结合java中的锁聊聊锁的本质

在操作系统里面&#xff0c;也会遇到什么信号量、互斥量&#xff0c;然后说利用互斥量、信号量可以实现锁的功能&#xff0c;而操作系统提供的原语有又mutex锁在学习数据库的时候&#xff0c;什么表锁、行锁、读锁、写锁、排它锁、意向锁、meta锁等等&#xff0c;各种各样的锁的…

mysql数据库limit的四种用法

文章目录前言一、语法二、参数说明三、常用示例-4种用法总结前言 mysql数据库中limit子句可以被用于强制select语句返回指定的记录数。limit接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数&#xff0c;第一个参数指定第一个返回记录行的偏移量&#xff0c…

实践数据湖iceberg 第四十一课 iceberg的实时性-业界的checkpoint配置

系列文章目录 实践数据湖iceberg 第一课 入门 实践数据湖iceberg 第二课 iceberg基于hadoop的底层数据格式 实践数据湖iceberg 第三课 在sqlclient中&#xff0c;以sql方式从kafka读数据到iceberg 实践数据湖iceberg 第四课 在sqlclient中&#xff0c;以sql方式从kafka读数据到…