Description
不知道小伙伴们日常 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,有需求的同学赶紧去试试吧。