How to organise NPM scripts in package.json?

I love using npm script as my build tool. By doing so, we could make sure the scripts are not sooooo complicated and easy to read (comparing to gulp/grunt in my opinion).

But as the project grows larger, there are more and more scripts that are added to package.json and things become less and less maintainable.

You probably tried adding empty lines in between scripts, but figure npm install will just remove your empty lines and leave you with only disappointment.

Here is a little trick which allow us to, kind of, group our scripts into categories.

{
  "scripts": {
    "test": "nyc mocha --recursive",
    "preversion": "git checkout master && git merge --squash dev && npm test",
    "version": "git add -A",
    "postversion": "git push && git push --tags && git checkout -",
    "\n# TESTING SCRIPTS:": "",
    "createTestPages": "node ./scripts/createTestPages.js",
    "test:watch": "mocha --recursive --watch",
    "coverage": "nyc report --reporter=lcov > coverage.lcov && codecov",
    "lint:js": "eslint .",
    "\n# HUSKY GIT HOOKS:": "",
    "precommit": "lint-staged"
  }
}

The trick here is to define some category keys. By adding \n to the front of the key, we would get a pretty darn neat npm run result.

> npm run
Lifecycle scripts included in grab-lyrics:
  test
    nyc mocha --recursive
  preversion
    git checkout master && git merge --squash dev && npm test
  version
    git add -A
  postversion
    git push && git push --tags && git checkout -

available via `npm run-script`:
  
# TESTING SCRIPTS:
    
  createTestPages
    node ./scripts/createTestPages.js
  test:watch
    mocha --recursive --watch
  coverage
    nyc report --reporter=lcov > coverage.lcov && codecov
  lint:js
    eslint .
  
# HUSKY GIT HOOKS:
    
  precommit
    lint-staged

One thing to keep in mind is to always put NPM lifecycle hooks at the top of the script because NPM will just grab them and put them at the top.

What do you think about this trick?