I\'ve got a simple package.json file and I want to add a comment. Is there a way to do this, or are there any hacks to make this work?
I created a script to read file package.json as the context for a handlebars template.
The code is below, in case someone finds this approach useful:
const templateData = require('../package.json');
const Handlebars = require('handlebars');
const fs = require('fs-extra');
const outputPath = __dirname + '/../package-json-comments.md';
const srcTemplatePath = __dirname + '/package-json-comments/package-json-comments.hbs';
Handlebars.registerHelper('objlist', function() {
// The first argument is an object, and the list is a set of keys for that obj
const obj = arguments[0];
const list = Array.prototype.slice.call(arguments, 1).slice(0,-1);
const mdList = list.map(function(k) {
return '* ' + k + ': ' + obj[k];
});
return new Handlebars.SafeString(mdList.join("\n"));
});
fs.readFile(srcTemplatePath, 'utf8', function(err, srcTemplate){
if (err) throw err;
const template = Handlebars.compile(srcTemplate);
const content = template(templateData);
fs.writeFile(outputPath, content, function(err) {
if (err) throw err;
});
});
handlebars template file package-json-comments.hbs
### Dependency Comments
For package: {{ name }}: {{version}}
#### Current Core Packages
should be safe to update
{{{objlist dependencies
"@material-ui/core"
"@material-ui/icons"
"@material-ui/styles"
}}}
#### Lagging Core Packages
breaks current code if updated
{{{objlist dependencies
"amazon-cognito-identity-js"
}}}
#### Major version change
Not tested yet
{{{objlist dependencies
"react-dev-utils"
"react-redux"
"react-router"
"redux-localstorage-simple"
}}}
Inspired by this thread, here's what we are using:
{
"//dependencies": {
"crypto-exchange": "Unified exchange API"
},
"dependencies": {
"crypto-exchange": "^2.3.3"
},
"//devDependencies": {
"chai": "Assertions",
"mocha": "Unit testing framwork",
"sinon": "Spies, Stubs, Mocks",
"supertest": "Test requests"
},
"devDependencies": {
"chai": "^4.1.2",
"mocha": "^4.0.1",
"sinon": "^4.1.3",
"supertest": "^3.0.0"
}
}
I've been doing this:
{
...
"scripts": {
"about": "echo 'Say something about this project'",
"about:clean": "echo 'Say something about the clean script'",
"clean": "do something",
"about:build": "echo 'Say something about building it'",
"build": "do something",
"about:watch": "echo 'Say something about how watch works'",
"watch": "do something",
}
...
}
This way, I can both read the "pseudo-comments" in the script itself, and also run something like the following, to see some kind of help in the terminal:
npm run about
npm run about:watch
Here's my take on comments within package.json
/ bower.json
:
I have file package.json.js
that contains a script that exports the actual package.json
. Running the script overwrites the old package.json
and tells me what changes it made, perfect to help you keep track of automatic changes npm
made. That way I can even programmatically define what packages I want to use.
The latest Grunt task is here: https://gist.github.com/MarZab/72fa6b85bc9e71de5991
You can always abuse the fact that duplicated keys are overwritten. This is what I just wrote:
"dependencies": {
"grunt": "...",
"grunt-cli": "...",
"api-easy": "# Here is the pull request: https://github.com/...",
"api-easy": "git://..."
"grunt-vows": "...",
"vows": "..."
}
However, it is not clear whether JSON allows duplicated keys (see Does JSON syntax allow duplicate keys in an object?. It seems to work with npm, so I take the risk.
The recommened hack is to use "//"
keys (from the nodejs mailing list). When I tested it, it did not work with "dependencies" sections, though. Also, the example in the post uses multiple "//"
keys, which implies that npm does not reject JSON files with duplicated keys. In other words, the hack above should always be fine.
Update: One annoying disadvantage of the duplicated key hack is that npm install --save
silently eliminates all duplicates. Unfortunately, it is very easy to overlook it and your well-intentioned comments are gone.
The "//"
hack is still the safest as it seems. However, multi-line comments will be removed by npm install --save
, too.
Since most developers are familiar with tag/annotation-based documentation, the convention I have started using is similar. Here is a taste:
{
"@comment dependencies": [
"These are the comments for the `dependencies` section.",
"The name of the section being commented is included in the key after the `@comment` 'annotation'/'tag' to ensure the keys are unique.",
"That is, using just \"@comment\" would not be sufficient to keep keys unique if you need to add another comment at the same level.",
"Because JSON doesn't allow a multi-line string or understand a line continuation operator/character, just use an array for each line of the comment.",
"Since this is embedded in JSON, the keys should be unique.",
"Otherwise JSON validators, such as ones built into IDEs, will complain.",
"Or some tools, such as running `npm install something --save`, will rewrite the `package.json` file but with duplicate keys removed.",
"",
"@package react - Using an `@package` 'annotation` could be how you add comments specific to particular packages."
],
"dependencies": {
...
},
"scripts": {
"@comment build": "This comment is about the build script.",
"build": "...",
"@comment start": [
"This comment is about the `start` script.",
"It is wrapped in an array to allow line formatting.",
"When using npm, as opposed to yarn, to run the script, be sure to add ` -- ` before adding the options.",
"",
"@option {number} --port - The port the server should listen on."
],
"start": "...",
"@comment test": "This comment is about the test script.",
"test": "..."
}
}
Note: For the dependencies
, devDependencies
, etc. sections, the comment annotations can't be added directly above the individual package dependencies inside the configuration object since npm
is expecting the key to be the name of an npm package. Hence the reason for the @comment dependencies
.
Note: In certain contexts, such as in the scripts object, some editors/IDEs may complain about the array. In the scripts context, Visual Studio Code expects a string for the value -- not an array.
I like the annotation/tag style way of adding comments to JSON because the @
symbol stands out from the normal declarations.