Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

我是如何给 github 上万 star 项目修复 bug 的? #14

Open
hustxiaoc opened this issue Apr 19, 2017 · 2 comments
Open

我是如何给 github 上万 star 项目修复 bug 的? #14

hustxiaoc opened this issue Apr 19, 2017 · 2 comments

Comments

@hustxiaoc
Copy link
Owner

不知道小伙伴们日常 Node.js 开发中使用什么方式来调试的,小编从开始接触 Node.js 起就一直使用 Node Inspector,并且在第一次使用它时就已经深深迷上它了,没想到 Node.js 还可以这么调试,简直就是太神奇了,对从前端开发过来的同学来说简直不要太友好,以至于短时间内该项目很快就在github上积累过万star。

一般的功能小编就不说了,亲们可以自行查看官方文档。比较 Cool 的几个feutre 不知道亲们有没有感受过。

  • Node Inspector 使用 webSocket 与 调试服务器通信,能够做到实时断点。
  • 支持远程调试,在本地调试远程 Node.js 服务器,这意味着你能够远程调试各种运行 Node.js 的嵌入式设备。
  • 能够像前端一样实时编辑正在运行的代码,并且能选择性的保存到原文件中。
  • 文件还未被加载到 V8 时就可以设置断点。
  • 能够通过 API 的方式被嵌入到应用中使用。

然而不知道从哪天起,这么好的东西在 Node6.4.x 版本后就没法正常运行了,当然 6.4.x 直接就提供了 --inspect 的调试功能,基本能够覆盖到 Node Inspector, 估计也是这个原因,Node Inspector 有大半年的时间没有更新了。但是 --inspect 一直处于实验阶段,于是小编决定要修复这些 bug, 让它能够继续跑在 6.x 和 7.x 版本上,让各位喜爱 Node Inspector 的小伙伴们能够继续使用,提升开发效率。

Node Inspector 提供了 cpu profile 和 memory dump 的功能,要实现该功能可不是那么简单的。这个过程中间涉及到向应用服务器动态注入一些代码,比如读取文件之类的。可能有的同学就会有疑惑了,读取文件这些不是用 Node.js 本身提供的 fs 模块就可以搞定了吗?

const fs = require('fs');
fs.readFileSync('xxx');

但是你有想过上面的 require 函数是怎么来的吗?调试环境下动态执行的代码里可没法直接使用 require,没有了 require 就像在浏览器里运行 js 时没法调用 DOM API 一样,仅仅只是一个支持 js 语法的 VM。

看看下面官方 VM 模块提供的一个代码示例。

'use strict';
const vm = require('vm');

let code =
`(function(require) {

   const http = require('http');

   http.createServer( (request, response) => {
     response.writeHead(200, {'Content-Type': 'text/plain'});
     response.end('Hello World\\n');
   }).listen(8124);

   console.log('Server running at http://127.0.0.1:8124/');
 })`;

 vm.runInThisContext(code)(require);

VM 执行环境中是没有 require 函数的,为了使用这个功能必须从外部传入。我们平时写的代码中能够使用 require 函数是因为 Node.js 执行时会对用户代码做一层包裹。

(function (exports, require, module, __filename, __dirname) { 
	const http = require('http');	
});

我们需要使用到的 require 函数其实是存在闭包里的,在 REPL 模式下会挂载到 global 下,正常运行时不会。所以如何才能使用到 require 就成了一个比较大的技术难点。Node Inspector 以前的开发者们也遇到了这个问题,还曾经提议让用户在代码最开始的地方就加上 process.require = require node-inspector/node-inspector#336

就像下面一段代码。

(function(){
	var require = function(info){
		console.log(info);
	}
	a();
})();

如何在不修改代码的情况下获取到函数 require 的引用呢, 不妨看看小编是如何解决这个问题的吧。https://github.com/node-inspector/node-inspector/pull/994/files

在这之前还曾经尝试过另一种方案,既然 Node.js 没有暴露 require 函数到全局上,不妨我们就自己构造出一个 require 函数来,就像 Node.js 启动时会先构造出 require 一样,有了这个函数之后各种模块才可以被使用到。 感兴趣的同学可以看看具体的实现,https://github.com/hustxiaoc/node-inspector/blob/104cee60b6275c8183719f603875560a92584fce/lib/patch.js

通过前前后后提了多个 PR 后,Node Inspector 终于可以在 6.x 以及 7.x 版本的 Node.js 上完美运行,小编也有幸成为其当前的 mainatiner。目前通过 --debug 的调试方式在 8.x 版本后已经完全被移除了,官方已经内置 inspector 功能,不过如果你的应用由于网络环境限制无法直接连接服务器调试,这时就需要 Node Inspector 充当中间的代理了,小编也会继续在 Node 8.x 版本中继续支持现有功能,让小伙伴们无缝升级继续快乐的调试着。

BTW,Node Inspector 最近发布了1.1.0版本,除了修复 Node6.x以及7.x 无法运行的 bug 外,还新增了远程调试功能,这意味着只要你本地和服务器之间网络能够联通,就可以使用 Node Inspector 在本地直接调试服务器上的 Node 应用啦,是不是很 Cool,有需求的同学赶紧去试试吧。

@erdun
Copy link

erdun commented Apr 19, 2017

image
这是公司规定的吗?

@hustxiaoc
Copy link
Owner Author

没有,我的模版里自带的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants