本书讲解了如何在 Node.js 上写 C++ 的原生模块以供使用,包括且不仅限于一些 API 和原理的介绍,但是不包括 Node.js 的基础入门知识(如语法等)。目标是读者能用 C++ 写出 Node.js 原生模块来提高开发和运行效率。
本书以 Chrome V8 的知识作为基础,配合 GYP 的一些内容,将教会大家如何使用 Node.js
提供的一些 API 来编写其 C++ 的原生扩展。此外,还介绍了原生抽象NAN 以及与异步相关的 libuv 知识,最后辅以几个实例来加深理解。
阅读本书,相当于同时学习Chrome V8 开发、libuv 开发以及 Node.js 的原生 C++ 扩展开发知识,物超所值!
本书作者死月是Node.js 核心贡献者(Node.js Core Collaborator)之一,CNode 社区版主之一,杭州 Node Party 组织者之一,曾任大搜车无线架构组 Node.js 团队负责人;浙江大学工程硕士,退役 OI、ACM 选手。
序一
1995 年Brendan Eich 花了10 天时间开发出了一门脚本语言,用来弥补Java Applet 的不足,随后Marc Andreessen 给它起名为Mocha。其最初的定位是,Java 用于大型专业级开发,而Mocha 则是给测试脚本编写人员、业余爱好者、设计师使用的。1995 年5 月,Mocha 被集成到了Netscape 浏览器中,其不久后改名为LiveScript,当年年
底网景公司和Sun 公司达成协议并获得了Java 商标的使用权,其正式更名为JavaScript。有人说Sun 公司的介入限制了Brendan Eich 的手脚。JavaScript 除了某些语法和Java 类似以外,骨子里却是完全不一样的东西。也有人说正式改名为JavaScript 才使得这门语言成为浏览器执行的唯一语言。时至今日JavaScript 已经不仅仅局限于为网页做特效了,而真正发展成为一门全功能的编程语言:
? 2008 年Chrome 发布、V8 发布;
? 2009 年Node.js 发布;
? 2010 年NPM 发布;
? 2014 年12 月,多位核心Node.js 开发者不满于Joyent 对Node.js 的管理制度,创建了io.js;
? 2015 年初Node.js 基金会成立;
? 2015 年9 月Node.js 4.0 发布,Node.js 和io.js 正式合并。
Node.js 4.0 版引入了ES6 的语言特性和“长期支持版本”的发布周期。
如今Node.js 社区已经成为最活跃的编程社区之一,而从NPM 的包数量来看,其已经超越了Java 的Manven、Ruby 的gem、PHP 的composer。
但是Node.js 仍有很多不足之处,Node.js 的使用者绝大部分仅仅把Node.js 作为前端开发的辅助工具。大家把Node.js 作为后端主力开发平台使用时,遇到CPU 密集的场景时又不得不借助Java 或者Go。虽然V8 引擎一直致力于让JavaScript 运行得更快,但是和Java、C++ 相比,还有不小的性能差距。
虽然关于JavaScript 的书已经汗牛充栋,但是有关Node.js 原理的书却屈指可数。而目前真正能够深入介绍原理的,国内的图书中也只有朴灵的《深入浅出Node.js》了,但如今四五年过去了依然没有等到该书的第2 版,而死月的这本书却可以弥补这一方面的不足。
所有的编程语言底层都会回归C/C++,Node.js 的底层依赖库V8 使用C++ 开发,libuv 则使用C 语言。而使用C++ 开发Node.js 扩展将直接把擅长CPU 的C++ 和擅长I/O 的Node.js结合在了一起,弥补了JavaScript 在计算密集型应用方面的不足。
我从2015 年开始研究V8,认识死月的时间则更早。死月不仅仅精通C++,他也是国内的Node.js 布道师之一。从我认识他起,他就一直在使用Node.js。如果你想深入了解Node.js 的原理,或者想打开Node.js 另一个世界的大门,这本《Node.js:来一打C++ 扩展》值得你精读。
——迷渡(justjavac),Flarum 中文社区创始人,国内知名前端技术专家
2018 年3 月22 日于天津
序二
我跟死月相识于GitHub,那时我们经常会向Node.js 贡献一些代码,彼此也会在微信上讨论一些技术问题。当我听说死月在写一本关于Node.js C++ 扩展相关的图书时,激动得几乎要从床上蹦起来。因为我深知一个对Node.js 与V8 引擎都如此了解之人,愿意将他所知所想分享出来,这将是给予社区的一份大礼。
从我个人的角度来看,这本书非常适合这类开发者:他们对于Node.js 的使用已经了然于胸,但却苦于没有底层开发经验,对整个V8 虚拟机也一知半解。这时,他们可以从第3 章开始读起。本书用了很长的篇幅介绍JavaScript 代码究竟在虚拟机里是怎么运行的,它们又都分别对应着哪一类数据结构等。因为作者深知,只有把这些基础理解透了,则无论是开发C++ 扩展,还是写纯JavaScript 代码,大家都能更得心应手。
本书像是在述说着Node.js 在C++ 扩展这一课题中曲折而又有趣的历史进程。首先从最原始的V8 API 时代开始。对于每个原始时代,开发者最痛苦的莫过于解决各种版本的兼容问题。之后迎来的是NAN 时代。它解决了原始时代的接口抽象问题,接口也更丰富多样,异步接口也封装在内。最后,是还在路上的N-API。它与NAN 一脉相承,拥有更官方的支持和更友好的接口。
另外,我们通常在写一个C++ 扩展时,多数情况下会跟异步打交道,这其中包含着如何非阻塞地调用底层接口,如何将异步的结果返回到JavaScript 的回调函数中,以及如何正确地在异步封装中释放你的资源。对这些内容特别感兴趣的读者,可以打开第6 章一睹为快。
Node.js 已快走完它的第一个10 年,尽管被人诟病于其回调地狱、虚假繁荣、超高并发场景下的不适应性,以及低端设备上的内存等问题,但这仍旧无法阻止它前进的步伐。然而对于我们Node.js 工程师来说,除了掌握好这门语言之外,学习如何写C++ 扩展、了解它如何运转将是我们下一阶段的重要功课。相信《Node.js:来一打C++ 扩展》将会成为常伴大家左右的另一本《代码大全》。
——刘亚中(Yorkie),Rokid 系统工程师,tensorflow-nodejs 作者
2018 年3 月22 日于杭州
第6个扩展我终于编译过啦,✌️!!!
124页中在第三行到第四中应该是析构函数,不是构造函数