本文转载自微信公众号《编程杂技》,作者theanarkh。转载本文请联系编程杂技公众号。前几天有个同学跟我说他在看nodejs的源码,但是不知道为什么要看,也不知道能从中学到什么。所以今天想说说阅读nodejs源码的意义。阅读其他源代码类似。首先,阅读源码的目的无外乎两个:1、深入了解和了解他或者一些底层原理;2、从中学习一些优秀的设计思想和实践。如果你没有两个目的,那么其实也没有必要看源码。然后说说阅读nodejs源码能得到什么。首先,我们需要深入了解nodejs是什么?大家都知道nodejs是一个js运行时。那么nodejs中有什么?每个部分的含义是什么?首先,nodejs由libuv、v8、第三方库组成。nodejs的定位首先是服务器,所以其实libuv就够了。那么剩下的组件有什么用呢?第三方库的作用是显而易见的。就是复用业界已有的方案,扩展nodejs的一些功能,这不是nodejs的核心。v8的意义在于因为nodejs使用的是js语言,所以需要js引擎。否则不用v8,直接将libuv和第三方库编译成二进制即可,类似于nginx和redis。这是一个高级视图。从底层来看,libuv是对操作系统功能的封装,v8是一个js解释器。那么看nodejs源码的意义就很明显了。nodejs的源码纵向分为以下三部分:1js层2c++层(使用v8桥接js和libuv以及一些自定义的c++逻辑)3c层阅读js层,可以理解一些上层逻辑由nodejs,虽然最后js层还是依赖底层,但是js层也有很多逻辑。理解了js层之后,在使用nodejs的时候,可以更深刻的理解自己在做什么,nodejs在做什么。但是js层远远不够。因为他只是一个躯壳。那么接下来,就得去读c++层,读c++层的代码,多了解v8的使用方法。假设你以后想在你的其他项目中单独使用v8,那么nodejs的代码就是一个参考。那么我们了解v8的用途有什么意义呢?这道题相当于用了一种语言,然后理解了他的编译器/解释器的意思。很多时候,我们不需要这样做,这完全取决于您的兴趣。如果你以后想使用v8,或者你想了解js实现的底层原理,或者你想了解一个编译器/解释器是如何实现的。然后你就可以去学习v8了。首先,v8是一个js引擎。它具有编译器/解释器通用逻辑、词法分析、语法分析、代码生成、代码优化等功能。然后还包括了js语言本身的实现细节,比如一个js数组和一个js对象在v8中是如何实现的。最后,了解v8为我们暴露了哪些接口,以及我们可以使用v8做什么。最后是读libuv。nodejs的重心是作为服务端,所以相对来说重心还是在读libuv。我们都知道v8只是一个js引擎,并没有网络、dns、文件等能力。在前端,js文件、网络等能力来自宿主浏览器。在nodejs中,这些能力来自libuv。这就是为什么nodejs被称为nodejs,而不是v8的原因。因为他不仅仅是v8。他还实现了自己的一些功能。所以你也可以实现自己的功能,添加v8的能力,创建一个新的服务器。言归正传,读libuv能学到什么?libuv是实现服务器的核心。所以我们可以从libuv学习用来实现一个服务器的技术。从libuv官网我们也可以知道,libuv包括进程、线程、定时器、文件、tcp、udp、unix域、线程池、dns等能力,操作系统能力的使用包括进程间通信(pipelines,unix域),eventfd),线程池,事件驱动(epoll,select,poll,kqueue等),inotify机制,文件操作等,使用二叉堆,红黑树等数据结构和算法,queue等。一般来说,阅读nodejs源码最直接的方式就是了解nodejs的工作原理和nodejs的本质。如果你是一名nodejs开发者,这无疑是一个不错的收获。其次,如果你有兴趣,还可以了解一下编译器和操作系统。另外,也可以从早期的版本到后期的重构背景,学习一些nodejs中的设计思想,比如定时器的设计。或者你设计一个服务器,你怎么设计。理论上讲了一些阅读nodejs源码的看法。顺便说说我自己的看法和经历。阅读nodejs源码的原因很直接,因为我希望自己能成为一名优秀的nodejs工程师。我对v8和libuv本身不太感兴趣。虽然我一直是前端工程师,但是我不会看js引擎的源码。至于lib??uv,有很多相关的异步io库,而在服务端设计方面,nginx和redis无疑更值得一读。但是要成为一名优秀的nodejs工程师,非常有必要对nodejs本身有深刻的理解和深刻的理解。相对来说,nodejs是非常原生的。很多时候我们觉得阅读nodejs源码是没有意义的,因为使用nodejs没有深度和广度。可能只是停留在框架层面,照搬业务的最佳实践,成功规避了一些陷阱。当你遇到一些问题,却又难以解决,甚至业界都没有解决方案时,你就会深刻体会到阅读源码的意义。当然这样的次数可能不多(比如https://cnodejs.org/topic/600b9de15d04ac76cf2181a7和https://cnodejs.org/topic/6018f1b103d797fb8e66e71c#6019f31903d7976d1066e9d2等)。从开始阅读nodejs源码到现在,我觉得这是一段非常艰难、快乐而又深刻的经历。他不仅让我更好的认识和理解了nodejs,还让我更上一层楼。虽然我一直在推动阅读nodejs源码,写了很多文章,和其他同学交流。但这并不意味着您必须阅读源代码。我个人认为阅读源码是一个好习惯,也是让自己变得优秀的一个途径,但是因为阅读哪些源码完全取决于个人的兴趣和选择。不要盲目阅读,要有目的的阅读。个人还是很感谢nodejs的,也很佩服nodejs的作者和贡献者,但是我觉得自己看nodejs源码的时候,对nodejs的原理了解的更多一些,学不到什么想学东西,v8是一方面,还有libuv的内容,我觉得看nginx和操作系统内核可能是更好的选择,但是libuv相比起来可能更轻,理解起来更快异步框架的设计。这里顺便提一下nodejs源码的分享。有的同学希望我讲的通俗些,或者结合应用讲。以下是我分享的一些想法。首先,我是一个在nodejs源码里学习的人,而不是站在nodejs上面的人,也就是说我也在慢慢学,而且因为时间紧,没办法像这样讲一个图文系列,一个码农翻身写的很好,也很容易看懂。因为我的初衷其实是做个笔记,然后分享给有兴趣的人,然后大家一起做这个。我不是大家的老师,这也不是我的初衷和目的。我几乎总是免费分享内容和回答问题。但是我很少遇到真正志同道合的人,大家还是希望我说话通俗易懂,这对我来说太难了。我承认,如何讲好技术,做好分享,是值得学习的,但我觉得这不是我现阶段的目标。而且我觉得对于一个有上进心的程序员来说,多动动手多动脑也不过分。一个人的力量是有限的,希望大家理解。最后提前祝大家新年快乐!对nodejs感兴趣的同学也可以找我一起交流学习!
