.

Tags:

When writing a large JavaScript application, it is quite often that console.log and other debugging statements are sprinkled here and there. Obviously, at one point those extraneous statements need to be removed for the production version or even when the code needs to be checked in into the source repository. There are many different ways to do this, there exists a new tool called groundskeeper which can do this removal for you.

Written for Node.js, groundskeeper (GitHub: github.com/Couto/groundskeeper) is created by Luís Couto to handle logging removal by understanding the syntax tree of the code and deleting the relevant parts. It is not based on regular expression at all. Groundskeeper parses the code (via Esprima) and modify the syntax nodes (via falafel) associated with any logging. Beside a command-line tool, groundskeeper is also a library ready to be used in any other tools and build systems.

Using groundskeeper is terribly simple (as its documentation explained). Let’s assume we have the following filter-debug.js:

function filter(list, age) {
  var result = [];
  list.forEach(function (person) {
    if (person.name && person.age > age) {
      console.log('including', person.name);
      result.push(person);
    }
  });
  return result;
}

After its package is installed, running something like:

groundskeeper < filter-debug.js > filter.js

will give the following filter.js:

function filter(list, age) {
  var result = [];
  list.forEach(function (person) {
    if (person.name && person.age > age) {
 
      result.push(person);
    }
  });
  return result;
}

The line containing console.log is now a blank line. Because groundskeeper doesn’t delete the line, the processed output still has the same amount of lines of code as the original one.

How about debugger? We know that this statement may cause some problems with old web browsers. Fortunately groundskeeper can also get rid of any debugger statements in the code. In fact, you can even nuke any other custom application logger you might have. Here is a code fragment:

debugger
var list = filter(customers, 25);
RentalApp.Logger.print(JSON.stringify(list, null, 2));

which can be processed via:

groundskeeper -n RentalApp.Logger < rental.js

and give you the remaining output:

var list = filter(customers, 25);

The biggest benefit of automatic removal is when it is combined with Git pre-commit hook so that no more manual step is necessary. This is pretty similar to the use of syntax validation trick. Here is an example of such a hook:

files=$(git diff-index --name-only --diff-filter=ACM HEAD | grep -P '\.js$')
for file in $files; do
  groundskeeper < $file > $file.tmp && mv $file.tmp $file
done

All touched *.js files will be processed via groundskeeper before they are checked in. This way, none of them will have stray console.log, debugger statements, or any other custom logger calls anymore. Thus, your repository is guaranteed to be free from debugging leftovers!

  • http://andreehansson.se/ Andrée Hansson

    Looks pretty cool. What’s the benefit compared to using something like a jshint pre-commit hook (and if warnings found, fail the commit)?

    How smart is it, would it remove the if-block from this for example? I’m just a bit worried that tools like these could potentially start to sprinkle unnecessary/irrelevant logic around in the projects that are not easily found compared to, say jshint warnings.

    “`
    if (foo > 50) {
    debugger;
    }
    “`

    Thanks for a great write-up!

    • http://ariya.ofilabs.com/ Ariya Hidayat

      groundskeeper’s README has some info on the problem with conditional statement.

  • http://schinckel.net Matthew Schinckel

    Yeah, I’m not sure I’m prepared to just let a pre-commit hook mangle my code.

    Surely a better solution is to prevent the commit, output the error (and the line number), and let the developer fix it?

    • http://ariya.ofilabs.com/ Ariya Hidayat

      Sure! You can customize the hook to suit your workflow better, that example was given just as an example :)

  • vishal kumar

    How can we remove alert?

    groundskeeper -n alert filter.js doesn’t work

    • http://ariya.ofilabs.com/ Ariya Hidayat

      You may want to file a feature request at the project site, not here.

  • Matt Perdeck

    Interesting tools. However, did you consider using a JavaScript logging library such as JSNLog (js.jsnlog.com)?

    It enables you to switch on/off all or some of your loggers from a single location in your code, so you don’t need a tool that messes with your code in multiple places.

    • http://ariya.ofilabs.com/ Ariya Hidayat

      “custom logger” is already mentioned in the blog post. The use of it doesn’t eliminate the need to exclude whatever deemed extraneous in the production version.

      • Vince

        Logging code is essential. Removing it means the next developer needs to write logging statements. This is best left as a build task.

        • http://ariya.ofilabs.com/ Ariya Hidayat

          Build task, commit hook, or any other step, it doesn’t matter (each project is different). The point is that there will be some form of statement (e.g. debugger) which everyone needs to exclude at some point and that is better left to a tool.