背景
nodejs的native插件是典型的混合语言开发场景(js + C)。为了辅助评估多语言运行时的价值,希望获取nodejs社区中native插件的总代码量。
方法
nodejs社区有中心分发系统,可以认为绝大部分的native插件都会进入npmjs这个中心网站。我们可以利用npmjs提供的查询功能来统计native 插件的数量,获取插件的源码,然后使用cloc等工具来最终得到代码行数。
获取native插件总量
npmjs中没有特异性的标签用于确定哪一个npm包是native插件,获取插件总量的确切数量非常困难。
一个比较取巧的方案是利用npmjs中的包依赖信息。nodejs主要的native插件都依赖两个接口机制NAN(Native Abstractions for Node.js 其较为成熟)和NAPI(较新的接口层,功能更强更简洁)。这两个机制分别对应https://www.npmjs.com/package/nan 和 https://www.npmjs.com/package/node-addon-api 这两个npm包。因此,只需要查看这两个npm包被依赖的数量,就可以估算出npmjs中的native插件数量了。在本文档写作时,NAN有5564个依赖,NAPI有986个依赖。
较为粗略的估算,当前nodejs的native插件数量大致是6500个
获取native插件的代码并统计代码行数
使用cloc等工具统计代码较为简单,核心问题是需要从nan和napi包的依赖信息中抽取出各native插件的源代码。
调研了各种方案后,当前的唯一可行的方案是(需要说明的是,即使是使用这个方案,也无法完整获取所有的信息。因为在超过396个依赖后,npmjs就拒绝再展示后面的依赖条目了):
基于 https://www.npmjs.com/browse/depended/nan 这样的页面信息分析nan的依赖包 (npmjs rest api接口中已经无法直接获取依赖信息了,可能是由于负载较重的原因)
取出包名后,通过 npmjs 的 restapi 可以查询到该 native 插件的源代码地址
使用git 取出源代码后,使用cloc 统计代码行数
第一条的依赖分析可使用现成的npm包,如下所示,可以将依赖信息导出到文本文件中。
1 | npm install npm-dependants |
使用curl可以访问内npmjs的restapi获取插件的代码位置,示例脚本如下。
1 | #set -x |
上面文件依赖的cloc-git.sh 是一个对cloc工具的简单封装,如下代码所示.
1 |
|
上面步骤执行完成后,可以得到一系列cloc的输出文件,再用如下脚本抽取所需的代码行号信息。
注意我们不能直接提取SUM的结果,因为native 插件中可能包含原始的工程项目(如C代码和其相关的文档说明)。
为了减小干扰,我们只提取c++和js的信息(插件中包含原c++工程的,后续通过代码行数量来过滤)。
1 | #set -x |
这里可以得到如下所示的输出。
1 | results/64.git.log:63:1941:13:45:0:119 |
这样的数据就便于分析了,可以按需进行数据处理。
估算总代码行数
在得到上面的分析数据后,通过抽样观察,过滤掉满足如下条件之一的项目(以屏蔽native插件中包含原工程的场景):
1 c++代码行超过10000行
2 c++头文件代码超过5000行
3 js代码超过5000行
对nan总共得到270条数据,数值如下。
c++_header_comment | cpp_header_code | cpp_comment | cpp_code | js_comment | js_code | SUM |
---|---|---|---|---|---|---|
286.678392 | 584.8241206 | 96.65055762 | 848.3197026 | 147.6666667 | 1026.724138 | 2990.863577 |
对napi总共得到225条数据,数值如下。
c++_header_comment | cpp_header_code | cpp_comment | cpp_code | js_comment | js_code | SUM |
---|---|---|---|---|---|---|
237.8641975 | 450.3703704 | 66.64516129 | 536.4193548 | 56.06542056 | 460.5 | 1807.864505 |
根据上述数据,估算native插件总代码数量如下:
2000 行/每个插件 * 6500 个插件 = 6.5k * 2k = 13m = 一千三百万行
较为粗略的估算,当前nodejs的native插件总代码行为 一千三百万行 。
需要注意到,整个分析过程中出现了很多干扰因素,上面的数据可能产生较大偏差。
可能导致数据低估的因素:
有一些由于行数过多被过滤掉的项目,其实并没有包含原工程(如nodegui)。
NAPI中出现了对接Object C++和RUST的情况,这些语言的代码行没有被统计
可能导致数据高估的因素:
过滤后仍然有部分项目含有了原工程
可能导致数据不定向偏差的因素:
由于npmjs的限制,只能获得396个插件的抽样统计数据,抽样导致的偏差不可控
结论
依据上面的分析,nodejs的native插件生态维护的代码行数应该在数百万行到数千万行之间。