Node.js源码解析----自己实现一个Node.js的难点与思路

前言:

最近在看Node.js,看了一段时间后便想着自己实现一个Node.js现在已经实现了个大概(绝大部分是模仿人家,不过自己实现一遍基本上就理解Node.js的原理了)下面便说说这个过程中的坑,以及一些需要注意的地方;

Node.js需要一定C++基础,建议看完C++Primer再看,否则V8的好多表达方式,指针,引用,模板之类的会看不懂;

代码已上传GitHub地址:   https://github.com/sven36/cNode

编译:我用的win10的环境,具体编译请参考Node.js的编译说明:https://github.com/nodejs/node/blob/master/BUILDING.md

其中的坑:Python应该是2.6或2.7,不要装3.0或以上的,因为node.js有的py文件3.0编译出错Visual C++ Build Tools必须是2015,安装官方的链接就是,因为Node.js在Windows平台的编译用的是vs2015的v140平台工具集,用低版本的或者vs2017的v141平台工具集都会报错;

编译流程:安装完python和Visual C++ Build Tools2015之后,下载node.js的源码  node-v6.10.0.tar.gz  然后用Visual C++ Build Tools2015的命令行运行解压目录下的vcbuild.bat处理文件就会开始编译了;编译成功后解压目录下就会出现.sln文件就可以使用vs打开了(vs也需要是2015或2017,并且项目的平台工具集也需要是v140否则编译报错);如图:

自己实现一个Node.js的难点与思路:

V8引擎:

因为node.js其实就是嵌入V8的一个C++程序;首先要对v8的Isolate,LocalHandle,Scope等概念有一个了解,此处不展开了,请参考这个文档:

https://github.com/Chunlin-Li/Chunlin-Li.github.io/blob/master/blogs/javascript/V8_Embedder‘s_Guide_CHS.md

在我的代码里面我也加了一些注释,在src目录下的node.cpp文件内,可以参考;

C++编译与平常的面向对象编译方式的不同

在.NET或Java之类的语言中,可以不必关注方法的声明顺序,比如:

private void a(){

b();

}

private void b(){

console.log(1);

}

不过在C++中这样是不行的,调用b之前,必须完全声明b;也就是把b放在方法a之前(这也是node.cpp文件中为什么把开始方法Start放在最下端);

为什么Node.js的头文件要用namespace node包起来:

是为了更好的解耦node.js的各个模块;在C++中命名空间相同而内部成员名字不同,它们会自动合并为同一个命名空间,可以理解为追加;

Node.js里面比较复杂的宏定义:

Node.js和V8用了很多复杂的宏定义,如果不理解它们看起来会很费力;在C++中,宏定义里面的##符号是连接字符串的意思;

比如:env-inl.h文件下的宏定义:

#define VP(PropertyName, StringValue) V(v8::Private, PropertyName, StringValue)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName, StringValue)
#define V(TypeName, PropertyName, StringValue)                                \
  inline                                                                      \
  v8::Local<TypeName> Environment::IsolateData::PropertyName() const {        \
    /* Strings are immutable so casting away const-ness here is okay. */      \
    return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate());  \
  }
    PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
        PER_ISOLATE_STRING_PROPERTIES(VS)
#undef V
#undef VS
#undef VP

它最后的编译形式是:

inline v8::Local<v8::String> Environment::IsolateData::async_queue_string() const {
        return const_cast<IsolateData*>(this)->async_queue_string_.Get(isolate());
    }

这种地方多一些耐心仔细分析一下就会懂了;我写的代码里面基本上这种宏定义第一个字符串我都是这种手写的,其余的是按照原先的宏定义的方式声明,可以参考;

使用VS编译需要注意的地方

node.js项目文件其实是用google的GYP工具生产的,所以VS项目编译的过程也在各个项目下的.gyp文件内。

了解gyp工具请参考:http://www.cnblogs.com/nanvann/p/3913880.html#conditions

当然还有很多具体的C++问题就需要靠自己多思考,勤搜索了;

 

 

时间: 2025-01-11 19:26:20

Node.js源码解析----自己实现一个Node.js的难点与思路的相关文章

underscore.js源码解析(二)

前几天我对underscore.js的整体结构做了分析,今天我将针对underscore封装的方法进行具体的分析,代码的一些解释都写在了注释里,那么废话不多说进入今天的正文. 没看过上一篇的可以猛戳这里:underscore.js源码解析(一) underscore.js源码GitHub地址: https://github.com/jashkenas/underscore/blob/master/underscore.js 本文解析的underscore.js版本是1.8.3 _.each 1

zepto.js 源码解析

zepto.js 源码解析 JavaScript移动端框架一 --- zepto zepto.js API中文文档 原文地址:https://www.cnblogs.com/hool/p/12631466.html

underscore.js源码解析

一直想针对一个框架的源码好好的学习一下编程思想和技巧,提高一下自己的水平,但是看过一些框架的源码,都感觉看的莫名其妙,看不太懂,最后找到这个underscore.js由于这个比较简短,一千多行,而且读起来容易一些,所以就决定是它了,那废话不多说开始我们的源码学习. underscore.js源码GitHub地址: https://github.com/jashkenas/underscore/blob/master/underscore.js 本文解析的underscore.js版本是1.8.3

转:backbone.js源码解析:extend、Backbone.View

源:http://www.cnblogs.com/mxw09/archive/2012/07/06/2579329.html backbone版本:0.9.2 1.解析Backbone.Model(Collection | Router | View).extend (1).找到extend的定义 //定义extend函数  var extend = function (protoProps, classProps) {    /*    通常我们以Backbone.XXX.extend的方式建

impress.js 源码解析系列(2)

1 /** 2 * [impress description] 定义 impress 函数 3 * @param {[type]} rootId [description] 4 * @return {[type]} [description] 5 */ 6 var impress = window.impress = function( rootId ) { 7 // 如果浏览器不支持,则退出 8 if ( !impressSupported ) { 9 return { 10 init: em

143行js顶部进度条最小插件-nanobar.js源码解析

网页顶部进度条插件的有四五种,基本原理就是动态地创建一个元素,然后通过设置它的width来实现动画效果,width增长到达指定位置时,将其去掉.来看看nanobar.js作者jacoborus是怎么做到的吧! /* http://nanobar.micronube.com/ || https://github.com/jacoborus/nanobar/ MIT LICENSE */ (function (root) { 'use strict' // container styles var

underscore.js源码解析【集合部分】

// Collection Functions // -------------------- // The cornerstone, an `each` implementation, aka `forEach`. // Handles raw objects in addition to array-likes. Treats all // sparse array-likes as if they were dense. /* params: 数组.对象或类数组对象,函数,函数执行环境 *

underscore.js源码解析【函数】

// Function (ahem) Functions // ------------------ // Determines whether to execute a function as a constructor // or a normal function with the provided arguments. /* 判断一个函数是按照构造函数还是普通函数执行?????????????????????????????????????????????????????????? */

underscore.js源码解析【对象】

// Object Functions // ---------------- // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. /* ie9以下版本中,对象中的key是不能被遍历的 */ var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); var nonEnumerableProps = ['valueO