102

Does someone used node-inspector with Grunt for application debugging? If not, Can you recommend a debugging tool for Grunt based apps?

I'm working with nodejs for a server side app and I have Grunt to use separated tasks (this is because users can execute tasks separately).

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
JuanO
  • 2,500
  • 3
  • 18
  • 20
  • console.log is your friend.. I would love to access node-inspector, but i think the debug tools are not part of V8. As i understand it, the debug tools are a web app in their own right. Correct me if im wrong here because I would like to do what your attempting. – iancrowther Sep 05 '12 at 14:11
  • Yes, logging system (I mean console.log or other kind of logging mechanism) will be always our friend, but what I am needing, is a different and more debuggable way. By now, I found some missing requirements to my project with grunt so I've removed by now and I am using nodejs as it own so I can debug using node-inspector now. I know, it is not the solution, but it works. I think, in a future, I will add grunt again with node-inspector and other tools/features added. Last but not least, grunt it's awesome! I'm using it in other projects and really rocks! – JuanO Sep 05 '12 at 20:39
  • Just started playing around with Grunt, also interested in that question... – Dmitry Pashkevich Sep 13 '12 at 14:56
  • @iancrowther, the tools web inspector uses are in V8. There is a project called `node-inspector` that talks to `node --debug`, providing the debug info to a browser that connects. This is awesome, because you can then connect Chrome to the node-inspector process, and use all the web inspector tools to debug your app. https://github.com/dannycoates/node-inspector – David Souther Oct 05 '12 at 03:52

7 Answers7

135

To run grunt in debug, you need to pass the grunt script to node explicitly:

node-debug $(which grunt) task

and put a debugger; line in your task. node-inspector will then open a browser with debugging tools.

Edit 28 Feb 2014

node-inspector has added the command node-debug, which launches node in a --debug state and opens the browser to the node-inspector page, stopping when it hits the first debugger line or set breakpoint.

Edit 30 January 2015

On Windows, things are a touch more complicated. See the answer from @e.gluhotorenko for instructions.

David Souther
  • 8,125
  • 2
  • 36
  • 53
  • 1
    This is great. It also works on other globally installed npm bins. – pllee Jan 30 '14 at 15:40
  • 1
    node debug $(which grunt) task uses nodejs default debugger – Tomas Romero Feb 25 '14 at 19:06
  • 3
    I'm having a bit of trouble with this. Could you clarify what `$(which grunt)` is? Is it just the Gruntfile.js I want to debug? And for `task` do I put (using `serve` as an example) `grunt serve` or just `serve`? I have tried `node-debug Gruntfile.js serve` and a lot of other things but I just cannot get this to work. Node-inspector opens and it breaks on the first line, but I cannot break into the `serve` task even if I put a `debugger;` line as the first line of the function. – Brett Mar 10 '14 at 06:08
  • 2
    @brett, are you on windows or OSX/Linux? On unix, $(which grunt) gets replaced with the full path to the grunt-cli `grunt.js` script. That is the script that actually runs Grunt. If you're on windows, look at http://stackoverflow.com/a/13443026/240358 (the answer below this) for a possible location of the grunt-cli script. That takes the place of `grunt` in your command - in your example, replace `task` with `serve` – David Souther Mar 10 '14 at 16:26
  • Thanks @DavidSouther, do you want to add the windows-specific part to your answer? I really should just make the move to linux... – Brett Mar 11 '14 at 01:26
39

Windows solution

Run

node --debug-brk c:\Users\username\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt taskname

from cmd in the directory with your Gruntfile.js. Do not forget to put debugger; line in necessary places.

Community
  • 1
  • 1
Eugene Gluhotorenko
  • 3,094
  • 2
  • 33
  • 52
  • 3
    Starting with grunt 0.4 the grunt entry point is part of the `grunt-cli` package: `node --debug-brk [..]\node_modules\grunt-cli\bin\grunt` – mistaecko Mar 20 '13 at 06:35
  • 4
    Thank you so much for the Windows instructions. In powershell you can use the tilde to make this a bit less fragile `node --debug-brk (Resolve-Path ~\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt) taskname` – George Mauer Jan 19 '14 at 21:54
  • Man, I just spent 30 minutes figuring this out then updating my answer! I should have just scrolled down! – David Souther Jan 30 '15 at 20:25
  • 1
    Do not forget to open another console and run `node-inspector` – valter.santos.matos Aug 05 '15 at 07:36
  • @valter.santos.matos actually it is now you should use the node --inspect mentioned below – Jackie Jun 28 '17 at 14:53
7

To debug, we have to modify the grunt file under bin. On my machine, grunt is installed globally, so I went to /usr/local/lib/node_modules/grunt/bin I opened the file and modified:

#!/usr/bin/env node

To

#!/usr/bin/env node --debug-brk

--debug-brk will break on the first line of javascript ran.

Doing that alone isn't quite enough though, since you won't be able to find you're grunt task js file in the drop down in node inspector, so you have to modify the file you're interested in debugging by adding debugger; where you want the breakpoint to happen. Now you can click continue after the first break, and you'll break on you're debugger; line

Pretty kludgy, but it's the only way I've found so far.

user1577390
  • 135
  • 1
  • 4
6

I recently created grunt-node-inspector to easily configure node-inspector with the rest of your grunt workflow, check it out: https://github.com/ChrisWren/grunt-node-inspector

Here is a section of a Gruntfile which illustrates how you can debug a grunt task using grunt-node-inspector, grunt-concurrent, and grunt-shell: https://github.com/CabinJS/Cabin/blob/master/Gruntfile.js#L44-L77

ChrisWren
  • 436
  • 8
  • 8
  • You're thinking, run `node --debug-brk $(which grunt) node-inspector build test` sort of thing? I like that. – David Souther Nov 25 '13 at 17:06
  • Pretty much, except I use concurrent, because `node-inspector` won't exit and allow `build` and `test` to run since it runs forever. I added a link to a snippet where I have it setup. – ChrisWren Nov 27 '13 at 06:13
  • Hmm. On second thought... my workflow has me just starting `node-inspector &`, leaving it in the background, and calling it done. Any thoughts of yours about that? – David Souther Nov 27 '13 at 14:53
  • 1
    Not sure why, but this doesn't seem to work for me. I run the command `grunt node-inspector` and then go to the localhost url and I see no source files. Just empty debugger tools. – khollenbeck May 30 '14 at 15:03
  • I managed to get the source to show up by running two separate commands. `grunt node-inspector` and `node --debug-brk Gruntfile.js` from my grunt directory. However when I set a breakpoint in the grunt file it just crashes with a connection error. – khollenbeck Jun 02 '14 at 18:10
4

I have done a task to run my app and launch node-inspector. It is far better than current proposition, you just have to add this task in gruntfile:

  grunt.registerTask('debug', 'My debug task.', function() {
        var done = this.async();
        grunt.util.spawn({
            cmd: 'node',
            args: ['--debug', 'app.js'],
            opts: {
                //cwd: current workin directory
            }
        },
        function (error, result, code) {
            if (error) {
                grunt.log.write (result);
                grunt.fail.fatal(error);
            }
            done();
        });
        grunt.log.writeln ('node started');
        grunt.util.spawn({
            cmd: 'node-inspector',
            args: ['&'],
            opts: {
                //cwd: current workin directory
            }
        },
        function (error, result, code) {
            if (error) {
                grunt.log.write (result);
                grunt.fail.fatal(error);
            }
            done();
        });
        grunt.log.writeln ('inspector started');
    });
olivier dufour
  • 332
  • 1
  • 7
  • 1
    The author of grunt-node-inspector has it right. This solution only works on posix environments while his is easier to configure node-inspector and with concurrent, works on posix and windows. – rainabba Dec 14 '13 at 04:58
3

Great answers here. In 2017, now you can do

node --inspect --debug-brk $(which grunt) taskName

Which prints something like.

To start debugging, open the following URL in Chrome: chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/232652c3-f63c-4b00-8de9-17dfad5db471

Open that URL in chrome, and you're good to go!

I'm using Node 7.3.0 and I'm on Mac. You might have to follow some of the advice in other posts to get it going on Windows.

RoccoB
  • 2,439
  • 2
  • 27
  • 30
2

2019 update

  • If you want to launch the grunt task in debug mode and break at first line:

    node --inspect-brk $(which grunt) taskName

  • If you want to launch the grunt task in debug mode at a specific port:

    node --inspect-brk=8080 $(which grunt) taskName

  • if you want to attache VSCODE to the node process running the debugging session of grunt, use the following configuration in vscode:

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    
    {
      "type": "node",
      "request": "attach",
      "name": "Attach by port IP 5656",
      "port": 8080
    }
  ]
}

Community
  • 1
  • 1
ZEE
  • 5,669
  • 4
  • 35
  • 53