第一次接触 Node 是 2013 年中旬,那时候还是 .net 程序员,偶尔也会写页面,所以接触过 JavaScript,听说 Node 很流行,饶有兴致的看了一下,觉得平淡无奇,无非是一门用 JavaScript 做方言的后端语言,并没有什么大 .net 没有的特性,那时候 Node 基础确实薄弱,连 Stream 还是第三方的包,也有有 Cluster 模块,基础设施薄弱无法应用到生产环境,所以就搁置没有继续学习
后来有幸到了现在公司,回顾一天的工作,除了开会都是围绕 Node 展开
- 本地代码开发使用了 JSX、ES6 等高级语法,需要 webpack 及周边工具构建、热更新、模拟环境等
- 单元测试使用 jest、mocha、chai 等
- UI 自动化使用 headless 工具 Puppeteer 、selenium-webdriver
- 代码发布前的打包、压缩、合并等使用 NodeJS 开发的工具支持
- 代码上线运行的 Web Server 是阿里巴巴封装的 Koa 上层框架 egg
- 甚至出于 SEO 友好、性能等原因 react 组件使用了同构,Server 端的渲染同样使用的 Node
- 性能监控、前端接口报警的系统也是前端使用 Node 构建的系统
现代的前端从本地开发、测试、上线、运行、运维都已经和 Node 息息相关,从 14 年会使用 Node 是加分项,到现在前端熟悉 Node 已经是对实习生的基本要求,2017 不使用 Node 的前端已经 out!
前面也有提到,我最开始时对 Node 不屑一顾有非常多的误解,后来工作使用,但因为一些误解导致学习过程颇为坎坷,我们在面试的时候也经常遇到生成自己熟悉 Node 使用,但问下来无非使用 Express 或者 Koa 做过简单的网站,对于 Node 本身了解却非常少,基础相当薄弱,问到一些问题的解决的时候毫无思路,如同看到了辟邪剑谱,学到了一些招式,但没有内功基础,一击就破。
写篇文章和大家分享一下自己现在对 Node 一些简单的理解,希望可以让初学者少走弯路。
NodeJS 是什么对 NodeJS 最大的误解莫过于认为 NodeJS 就是 JavaScript,我们来看一下官网对 NodeJS 的定义
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js' package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
简单翻译就是
- Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
- Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
- Node.js 的包管理器 npm,是全球最大的开源库生态系统。
所以 Node 并不是一门语言,而是一个 runtime,也就是我们经常说的运行时,和我们非常熟悉的 JRE—— Java Runtime Environment 非常类似。如同浏览器是 JavaScript 的运行时,我们有时候也会称之为宿主环境或者运行环境,Node 是 JavaScript 在服务器端的一个运行时。
个人感觉称 Node 为 JavaScript runtime 也不是很准确,因为 JavaScript 除了 ECMAScript 还包括了其在浏览器端的实现 BOM、DOM,这些在 Node 中是不存在的,叫 ERE 会更贴切一些,但是 Node 因为运行在服务器端,虽然缺失的 BOM、DOM,但是多了很多针对服务器编程常用的封装,我们来简单了解一下 Node 的组成
- ECMAScript 解释器
- npm—— node package manager
- CommonJS module system:NodeJS 诞生在 JavaScript 没有官方模块系统的年代,只能自己做一个规范并且内置实现(最新的 8.5 已经开始支持 ES6 modules)
- debugger:方便开发者进行代码调试
- fs、Stream、http、util 等常用内置模块
在上层我们经常接触的就是这些,到这里我们可以了解 Node 并不是运营在服务器端的 JavaScript,而是在服务器端的 JavaScript runtime。
Node 好在哪里好多同学会有和我一样的感觉,Node 一夜爆红,变成了前端的必备技能,面试要求掌握一门后端语言,我们也可以大大方方说熟悉 Node 了。那么 Node 就行好在哪里,为什么会忽然编程前端界的网红?
使用 JavaScript 作为方言毋庸置疑是非常重要一个原因,前端都其语法很熟悉,有天然的亲切感。然而这并不是全部原因,甚至不是主要原因,在更早之前已经有了在服务器端运行 JavaScript 的尝试 —— Rhino,但并没有达到 Node 的成就,真正使 Node 流行的原因是其官方定义中的第二句
Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.
首先需要了解几个基本常识
- CPU 运算远远快于 I/O 操作
- Web 是典型的 I/O 密集场景
- 虽然JavaScript 是单线程(随着 JavaScript 演进,这条马上要不成立),但 JavaScript 的 runtime Node 并不是,毕竟人家很多代码是 C++
Node 使用了事件驱动和非阻塞的 I/O 模型,使 Node 轻量高效,非常适合 I/O 密集的 Web 场景。
很多语言是依赖的多进程、线程解决高并发,一个线程处理一条用户请求,处理完成了释放线程,在阻塞 I/O 模型下, I/O 期间该用户线程所占用的 CPU 资源(虽然十分微量,大部分交给了 DMA)什么都不做,等待 I/O,然后响应用户,而且开启多个进程/线程 CPU 切换 Context 的时间也十分可观。
就像饭店的服务员只负责点菜,如果给每个厨师都配一个服务员,服务员把客人菜单给大厨后就玩手机等着一样,你是老板你也生气,况且不同于饭店大厨工资高于服务员,在计算机世界,CPU 资源比 I/O 宝贵的多。
说 NodeJS 在高并发、I/O 密集场景性能高,也就是 Web 场景性能高主要也是解决这个问题,没必要一个厨师配一个服务员,整个饭店说不定一个服务员就够了,剩下的钱可以随便做其它事情。
用户请求来了, CPU 的部分做完不用等待 I/O,交给底层完成,然后可以接着处理下一个请求了,快就快在
- 非阻塞 I/O
- Web 场景 I/O 密集
- 没那么多线程 Context 切换,多出来的开销是检查一个 EventLoop
除了 Web 场景的高性能,Node 可以流行起来还有一个重要原因——恰逢其时。
回头看这三年前端经过了可以成为大爆炸的时代,代码构建、自动化、单元测试等等随着前端工作职责范围扩大和代码复杂度膨胀充斥到所有前端眼前,前端不再是附庸在 HTML 上的小玩具,而是整个用户体验的中心。相应的前端对周边工具的要求越来越多,让前端用 Java 写相关工具或者让后端同学帮忙写都不是最好的选择,前端的问题前端自己解决才是最合适的,Node 以其足够简单了的特性,迅速扩充了其生态,各种好用的工具应运而生,正如前辈们说的——所有可以通过 JavaScript 解决的问题都将用 JavaScript 解决。
可以看看知乎上讨论,小芋头君说的团队用 Node 的理由
Node 学习路径对于我们团队,其实使用NodeJS的理由,反而提现在其他方面:
生态活跃,解决方案众多,我们的Node服务化,架构,协作方式都很先进,因为社区活跃,有很多思路可以借鉴,架构变得越来越优,开发方式也变得越来越趋向社区规范。反观java,一直在玩老掉牙的架构,每天就是在搞环境问题,大部分开发完全不知道内部原理,而且没有什么大的技术追求。
轻量,部署轻量,开发轻量。我们可以用最小的阿里云配置就部署出一个小应用来,用来做微服务化架构非常完美。想想把一个java系统拆分成十几个微服务(java)的场景,每个进程启动起来都要1G内存吧至少,high起来吧阿里云。
我们公司技术栈采用多语言,多一个语言就多一种可能性,例如一些用node实现特别适合的服务,Phantomjs类的服务(图片,模拟操作等),WebSocket啊之类的。
作者:小芋头君链接:https://www.zhihu.com/question/37619635/answer/73914788
Node 这么好又这么流行,是该学起来了,但是 Node 小白改如何开始学习 Node 呢,给大家推荐一下我的学习心得
因为 Node 发展及其迅猛,市面上大部分有质量的相关书籍其实已经过时(没错,朴老湿的也已经过时),买本书学会 Node 已经不再现实
工欲善其事,必先利其器
- vscode,调试 Node 特别方便,比 web storm 轻量,比 sublime 更像是各 IDE,atom 就不吐槽了
- supervisior,我们在修改 Node 程序的时候需要不断重启才能看到结果,supervisor 可以帮我们监视文件变化,自动重启应用代码
- 如果使用 Mac 的话,iTerm2 是必备
这样就可以了,开发 Node 并不需要准备太多
兴趣是最好的老师
如果我们有一定的 JavaScript 基础,那么从头看文档是一件很无趣的事情,我们可以做一件很有成就感的小事情来帮助我们培养对 Node 的兴趣,同时了解到大部分常用的 API,给大家推荐的兴趣项目是做一个爬虫,我们可以随便无恶意的爬取一些网页内容,使用数据库或者文件保存到本地
- 使用 Chrome 团队的 headless 工具 Puppeteer 发起请求,获得异步数据
- 使用 async/await 解决异步回调问题
- 使用 fs、stream 保存文件到本地,甚至可以练习一下 json 转 csv,顺便处理中文乱码问题
- 使用 mongoose 保存数据到数据库
这样的一个小项目让我们可以体验用 Node 编程的乐趣,同时在写代码过程中会用到请求、文件处理等我们在浏览器端很少遇到的问题,对 Node 有了全貌的了解之后,我们就可以通过官方文档系统的学习了
官方文档
Node 的官方文档不止是 API 的调用,也是很多模块的教程,尤其是 Stream 相关,是学习必备,关于 debug 技巧的 Debugging Node.js Apps 是我们开篇需要看的,推荐大家使用 vscode,调试最简单
一般来讲我们肯定需要看的常用模块
- buffer
- fs
- path
- http
- url
- stream
- events
如果英文文档阅读有些障碍,可以看一下 Node 中文文档
静态资源服务器
有些前面知识之后我们可以尝试写一个 Node 最常用的场景——静态资源服务器,来锻炼我们
- HTTP 协议
- fs
- stream
- 代码构建
- 单元测试
- 命令行工具书写
- 发布 npm 包
朴灵老师的 anywhere 是一个绝佳的效果,但是我们需要做到尽量不依赖第三方包自己从头到尾做一下实现,并且把代码构建为 Node 6 支持的代码,做好单元测试,然后发布到 npm。
做完这些相信我们就对 Node 有了一定的了解,可以开始尝试s使用 Koa、egg 搭建我们自己的的 Node 站点了。
Node 未来关于 Node 的未来每个人都有不同的看法和期待,我认为 Node 至少会在下面几点有所发展
- 语言本身的完善
- 前端周边生态的繁荣
- web 应用上层框架甚至解决方案的出现
Node 的发展已经为 ECMAScript 规范指定做了很多贡献,不同于在浏览器端使用,前端受限于客户浏览器兼容性问题,不敢使用新式的语法,Node 运行在服务器,运行环境我们可以自己控制,结合上代码构建能力,使大量新的规范可以被广泛使用,随着 Node 对 async/await、ES module 的给特性支持,相信 Node 会继续引领语言规范的发展。
如同小芋头君提到的团队使用 Node 更侧重的是其生态,npm 已经是世界上最大的开源模块系统,随着前端的繁重这一优势将会得到继续保持甚至扩大,届时或许真的会实现:可以使用 JavaScript 解决的问题都将用 javaScript 解决。
简单工具繁荣了,整套 Node web 开发解决方案必将出现,egg 已经是一个先行者,后续一些差异化的垂直解决方案也会应运而生。
小伙伴们还在等什么?快上车!
热门评论
先看小例子,因为语法就是 JS,不会有障碍
你好,我看了你的nodejs课程,你在初始化的时候课程里并没有讲到你是怎样生成的src文件夹的和node_module文件夹的,我希望你能帮我解答
很喜欢node,Samaritan大大能留下你的github吗?