How do I add comments to package.json for npm install?
Asked Answered
P

24

597

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?

{
  "name": "My Project",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "express": "3.x",
    "mongoose": "3.x"
  },
  "devDependencies" :  {
    "should": "*"
    /* "mocha": "*" not needed as should be globally installed */
  }
}

The example comment above doesn't work as npm breaks. I've also tried // style comments.

Pluckless answered 8/1, 2013 at 18:23 Comment(5)
possible duplicate of Can I comment a JSON file?Meta
@YehudaKatz - I don't think it's a duplicate in that this question is specific to package.json files and there is a package.json specific answer on the NodeJS mailing list.Agnes
One of the core npm developers has refused to consider comments support in package.json. Please comment on that issue - maybe we can show how useful comments can be.Ayah
One single tag <sarcasm />. JSON5 supports comments json5.orgCrocker
More generally, Can comments be used in JSON? (the canonical question)Luster
H
602

This has recently been discussed on the Node.js mailing list.

According to Isaac Schlueter who created npm:

... the "//" key will never be used by npm for any purpose, and is reserved for comments ... If you want to use a multiple line comment, you can use either an array, or multiple "//" keys.

When using your usual tools (npm, yarn, etc.), multiple "//" keys will be removed. This survives:

{ "//": [
  "first line",
  "second line" ] }

This will not survive:

{ "//": "this is the first line of a comment",
  "//": "this is the second line of the comment" }

One must be aware that "//" can only be used at the root of the package.json object. For example

{ 
  "//": "comment!", 
  "dependencies": {...}
} 

is valid but

{ 
  "dependencies": { 
     "//": "comment?" 
  }
}

is invalid.

-- @david_p comment

Haehaecceity answered 8/1, 2013 at 18:36 Comment(15)
is there a way to doc what each entry in the 'dependencies' section is? the "//" trick does not work when its an attr of 'dependencies'.Duhon
@Duhon Yes, I also had to use the other hack (duplicating the key of the dependencies entry). I added an answer.Submergible
This is the only correct answer, because like @Phillipp Claßen wrote in his answer as an update, npm install --save is removing duplicate keys, so the answer of Jonathan Warden is also not usefull in real world development.Rehabilitate
Note that using multiple comments as in the first example { "//": "first", "//": "second"} prevents you from using npm version and other command line utils which usually reparse whole JSON and discard the duplicate keys in process.Cense
One must be aware that "//" can only be used at the root of the package.json object. For example { "dependencies": { "//": "comment?" }} is invalid but { "//": "comment!", "dependencies":{}} is valid.Sandblast
Even Douglas Crockford has no problem with putting comments in JSON config files. The situation with NPM is silly to say the least.Farreaching
in my experience the "//" key and its value get wiped eventually. is there a way to have permanent comments?Upside
doing a lot of reading on this, my thought is a cross between a few approaches -- since "//" is valid and suggested -- why not something like "//scripts", "//dependencies", "//devDependencies" etc as commentary sections (as immediate siblings of the applicable section)? this keeps things local to the file, no need for pre-process through jsmin (as suggested by crockford -- and fully broken for npm), allows duplicate stripping and npm normal processing to ignore it and runs nearly 0 chance of conflict/collision -- worst drawback is direct locality -- but otherwise best of all situationsRhenium
You have to be careful where you put the "//" key: npm ERR! code EINVALIDPACKAGENAME npm ERR! Invalid package name "//": name can only contain URL-friendly charactersRepute
@MuhammadRehanSaeed Has his opinion changed since this? plus.google.com/+DouglasCrockfordEsq/posts/RK8qyGVaGSrMarashio
@muhammadRehanSaeed: No, but his thoughts were more nuanced than people understood.Boak
Not working for clang compile_commands.json, they require every tag is in the predefined set which doesn't contain "//". No comments is absolutely the bad design of a json format. Already waste 10+ minutes due to no comments thereCounterproductive
Assert json doesn't need comments is like assert 1MB Ram is enough for PC. Now Json is everywhere, not limited to object data. Many use cases naturally need comments, like json as configuration file.Counterproductive
In addition to the global // comment or array of comments, you can use the semver pipe separator for comments on particular dependencies, e.g. "@types/node": "^16.11.7 || keep-same-major-version-as-node"Lindie
This solution broke npx update-browserslist-db@latest for me, leading to a very confusing error must provide string spec error. gkond's solutions works.Sprag
I
280

After wasting an hour on complex and hacky solutions, I've found both simple and valid solution for commenting my bulky dependencies section in package.json. Just like this:

{
  "name": "package name",
  "version": "1.0",
  "description": "package description",
  "scripts": {
    "start": "npm install && node server.js"
  },
  "scriptsComments": {
    "start": "Runs development build on a local server configured by server.js"
  },
  "dependencies": {
    "ajv": "^5.2.2"
  },
  "dependenciesComments": {
    "ajv": "JSON-Schema Validator for validation of API data"
  }
}

When sorted the same way, it's now very easy for me to track these pairs of dependencies/comments either in Git commit diffs or in an editor while working with file package.json.

And no extra tools are involved, just plain and valid JSON.

Instantly answered 22/8, 2017 at 10:38 Comment(7)
Thanks for a non-hacky solution that is technically valid and semantically helpful.Demarco
For comments about scripts, why not provide "help" scripts, e.g. "scripts": { "postinstall": "echo postinstall stuff goes here", "help-postinstall": "echo helpful stuff goes here" }Homesteader
@Homesteader thanks! The only downside I see is that actual scripts will be blended with comments.Instantly
Works for me... and I combine it with using an array [] for multi-line comments. Like in @Igor Soarez's answer.Volute
npm v6+ allows pre and post prefixes that allow echo output as well. docs.npmjs.com/cli/v8/using-npm/scripts#pre--post-scripts "scripts": { "prefoo": "echo 'Before'", "foo": "echo 'FOO!'", "postfoo": "echo 'After'" }Unfix
Would it be more readable and less likely to conflict if we use "//scripts" instead of "scriptsComments"?Female
Neat! Using this!Downwards
E
128

DISCLAIMER: you probably should not use this hack. See comments below.


Here is another hack for adding comments in JSON. Since:

{"a": 1, "a": 2}

Is equivalent to:

{"a": 2}

You can do something like:

{
  "devDependencies": "'mocha' is not needed as it should be globally installed",
  "devDependencies" :  {
    "should": "*"
  }
}
Epitaph answered 4/8, 2013 at 22:18 Comment(9)
This works at the specific package level too. For example. "express": "makes routing better so I don't want to gouge my eyes out", "express": "3.x". So, yes, "yuck" as ColinE says, and also "thanks" as ColinE says.Urga
Note though that this hack prevents you from ever changing the package.json in a programmatic way, say by npm version 1.2.3 to bump the version - the redundant entries will be removed from the resulting JSON.Cense
This is bad advice, because the order an object is interpreted isn't guaranteed. For example, in some situations, your example might end up with a being 1 instead of 2.Anthrax
@JosiahSprague The order of the keys in a JavaScript object isn't guaranteed, but as long as the JSON is parsed sequentially it doesn't matter.Baptist
@Baptist The risk is that there is no guarantee that the code parsing the JSON will do it sequentially.Anthrax
For the record, the RFC explicitly says: " When the names within an object are not unique, the behavior of software that receives such an object is unpredictable. Many implementations report the last name/value pair only. Other implementations report an error or fail to parse the object, and some implementations report all of the name/value pairs, including duplicates. "Corruptible
npm 5.6.0 removes the duplicates during npm installGlandule
this solution is way too dangerous - as per all the comment - so does not merit the number of upvotes. Why play Russian Roulette with your code?Loggia
This is Heisenbug waiting to happen. I can hear Archer's voice saying, "Do you want Heisenbugs? Because this is how you get Heisenbugs."Disprize
B
79

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

Even better if you are using yarn.

yarn about:clean

Also, as pointed out by @Dakota Jang in comments, you can use keys like //something to make it even more clear that this is a comment.
Like so:

{
  ...
  "scripts": {
    "//clean": "echo 'Say something about the clean script'",
    "clean": "do something",
    "//build": "echo 'Say something about building it'",
    "build": "do something",
    "//watch": "echo 'Say something about how watch works'",
    "watch": "do something",
  }
  ...
}

And then run:

npm run //build
# or
yarn //build

And you will have a helper output in your terminal, and a "comment" in your package.json as well.

Bournemouth answered 15/6, 2018 at 14:55 Comment(2)
In my opinion, this is the best option, as it allows users to get info on the commands without needing to actually open the package.json.Brownie
I am doing "//build": "echo 'something about build'". It makes the key a bit more prominent in my opinion...Tektite
S
28

NPS (Node Package Scripts) solved this problem for me. It lets you put your NPM scripts into a separate JavaScript file, where you can add comments galore and any other JavaScript logic you need to. https://www.npmjs.com/package/nps

Sample of the package-scripts.js from one of my projects:

module.exports = {
  scripts: {
    // makes sure e2e webdrivers are up to date
    postinstall: 'nps webdriver-update',

    // run the webpack dev server and open it in browser on port 7000
    server: 'webpack-dev-server --inline --progress --port 7000 --open',

    // start webpack dev server with full reload on each change
    default: 'nps server',

    // start webpack dev server with hot module replacement
    hmr: 'nps server -- --hot',

    // generates icon font via a gulp task
    iconFont: 'gulp default --gulpfile src/deps/build-scripts/gulp-icon-font.js',

    // No longer used
    // copyFonts: 'copyfiles -f src/app/glb/font/webfonts/**/* dist/1-0-0/font'
  }
}

I just did a local install npm install nps -save-dev and put this in my package.json scripts.

"scripts": {
   "start": "nps",
   "test": "nps test"
}
Seismo answered 14/7, 2017 at 12:24 Comment(1)
This is my favorite answer. And I use [nps] to do more, can use js code to control the flow of commands .Quattlebaum
A
28

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"
  }
}
Accordance answered 12/5, 2019 at 10:42 Comment(1)
I like this better, although the mailing list said "//" is reserved which means "//<TEXT>" is not reservedUniformize
D
23

Since most developers are familiar with tag/annotation-based documentation, the convention I have been using is similar. I like how the @ symbol stands out from the normal declarations.

Here is a taste:

{
  "@comment dependencies": {
    "@comment": [
      "These are the general/global comments for the `dependencies` section.",
      "They are not specific to a particular package.",
      "See below for how to add comments specific to a package.",
    ],
    "@package express": [
      "Use `@package {package-name}` to make comments specific to a package.",
      "",
      "This is a good place to explain why the version range isn't ", 
      "`^version` or why the latest major version isn't being used, ",
      "e.g., ESM is not supported in the project at the moment."
    ],
    "@package lodash": [
      "Until we add a tool to tree shake unused parts of a lodash, ",
      "only depend on the [per method packages](https://www.npmjs.com/search?q=keywords:lodash-modularized) ",
      "such as `lodash.debounce`."
    ]
  },
  "dependencies": {
    ...
  },
  "@comment scripts": {
    "@comment Use with NPM": [
      "Be sure to add ` -- ` before adding options.",
      "For example, `npm run build -- --opt1 val1`."
    ],
    "@comment Use with Yarn": "...",
    "@script build": "This comment is about the build script.",
    "@script start": [
      "This comment is about the `start` script.",
      "It is wrapped in an array to allow line formatting.",
      "",
      "@option {number} --port - The port the server should listen on."
    ],
    "@script test": "This comment is about the test script.",
  },
  "scripts": {
    "build": "...",
    "start": "...",
    "test": "..."
  }
}

Note: The name of the section being commented is included in the key after the @comment {section-name} 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. If the keys weren't unique, JSON validators, such as ones built into IDEs, will complain, or some tools, such as running npm install something, will rewrite the package.json file but with duplicate keys removed.

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.

It is recommended to use Markdown or something similar to help clarify your comments.

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: For the dependencies, devDependencies, scripts, etc. sections, the embedded @comment keys may or may not contain a section name.

Older dependencies Recommendation

The following was my previous recommendation for the various dependency sections (dependencies, devDependencies, etc).

{
  "@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": {
    ...
  },

Older scripts Recommendation

The following was my previous recommendation. It in-lined comments for the scripts, but I've come to realize that those comments show up as "commands" in some tools (in VS Code > Explorer > NPM Scripts section). The latest recommendation does not suffer from this issue but the script comments are no longer co-located.

{
  "@comment dependencies": [
    ...
  ],
  "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: In certain contexts, such as in the "scripts" object, some editors/IDEs may complain about the array. In the scripts context, VS Code expects a string for the value — not an array.

Dichlorodifluoromethane answered 15/10, 2019 at 0:0 Comment(2)
This is the best solution I've come across, because it allows associating each comment with a specific key. This puts things in context much better than the "//" method, so the the comment can exist outside the object it references without any confusion. That's great for documenting config trees where the tool expects strict rules (eg eslint), and borks if it discovers anything foreign.Deery
Nice one - I actually just use #, so for example inside scripts: { scripts: { "# my comments for dev go here":"or here", "dev": "npm-run-all build:watch~ serve:watch~ test:watch~" }} without any @tag etc, inside scripts, and it works great! I dont execute scripts from IDE's etc, I prefer the CLI, so it doesn't matter... What's with the tilda~? They start in their own Terminal and return control ;-)Paraldehyde
F
16

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.

Flak answered 21/5, 2014 at 18:32 Comment(3)
The "//" hack does not work inside devDependencies. NPM tries to resolve a UNC path.Firewarden
Thanks for update sentence but again it cannot comment mocha attribute. Just it can add more than one of it and will be used by npm at the end.Killie
"When I tested it, it did not work with "dependencies" sections" see this comment, the "//" key only works at the root.Riding
C
11

I have a funny hack idea.

Create an npm package name suitably as a comment divider for dependencies and devDependencies block in file package.json, for example x----x----x

{
    "name": "app-name",
    "dependencies": {
        "x----x----x": "this is the first line of a comment",
        "babel-cli": "6.x.x",
        "babel-core": "6.x.x",
        "x----x----x": "this is the second line of a comment",
        "knex": "^0.11.1",
        "mocha": "1.20.1",
        "x----x----x": "*"
    }
}

NOTE: You must add the last comment divider line with a valid version, like * in the block.

Capote answered 13/5, 2016 at 10:7 Comment(3)
yay, it's actually available: npmjs.com/package/x----x----xIllconditioned
Was thrilled about this answer but after I ran npm install (using npm 5) my duplicate keys were automatically removed :(Furlana
@EricMajerus oops~, npm5 break my heart also :(Capote
S
10

So far, most "hacks" here suggest to abuse JSON. But instead, why not abuse the underlying scripting language?

Edit The initial response was putting the description on the right using # add comments here to wrap it; however, this does not work on Windows, because flags (e.g., npm run myframework -- --myframework-flags) would be ignored. I changed my response to make it work on all platforms, and added some indents for readability purposes.

{
 "scripts": {
   "help": "       echo 'Display help information (this screen)';          npm run",
   "myframework": "echo 'Run myframework binary';                          myframework",
   "develop": "    echo 'Run in development mode (with terminal output)';  npm run myframework"
   "start": "      echo 'Start myFramework as a daemon';                   myframework start",
   "stop":  "      echo 'Stop the myFramework daemon';                     myframework stop"
   "test": "echo \"Error: no test specified\" && exit 1"
 }
}

This will:

  1. Not break JSON compliance (or at least it's not a hack, and your IDE will not give you warnings for doing strange, dangerous stuff)
  2. Works cross platform (tested on macOS and Windows, assuming it would work just fine on Linux)
  3. Does not get in the way of running npm run myframework -- --help
  4. Will output meaningful info when running npm run (which is the actual command to run to get information about available scripts)
  5. Presents a more explicit help command (in case some developers are not aware that npm run presents such output)
  6. Will show both the commands and its description when running the command itself
  7. Is somewhat readable when just opening package.json (using less or your favorite IDE)
Specialty answered 4/4, 2017 at 5:3 Comment(7)
Argh, actually on Windows it would just ignore flags, so 3. is not true :/Specialty
Make it windows cmd compatible with: && instead of ; so the first command becomes: "help": "echo 'Display help information (this screen)' && npm run",Ilka
Yes, thats what I ended up doing. Good catch!Specialty
It only works in the scripts section. package.json is many other things.Dowling
Correct. Then again, what else would you feel the need to document in there?Specialty
@MarcTrudel: the reason why I had to add an obscure devDependency, or a TODO to upgrade one after a bug is fixed.Ayah
Very good point... so much hacking around for a simple thing :/Specialty
L
10

As this answer explains, the // key was reserved, so it can be used conventionally for comments. The problem with // comment is that it's not practical, because it can't be used multiple times. Duplicate keys are deleted on package.json automatic updates:

"//": "this comment about dependencies stays",
"dependencies": {}
"//": "this comment disappears",
"devDependencies": {}

Another problem is that // comment can't be used inside dependencies and devDependencies because it's treated as a regular dependency:

"dependencies": {
  "//": "comment"
}

npm ERR! code EINVALIDPACKAGENAME

npm ERR! Invalid package name "//": name can only contain URL-friendly characters

A workaround that works in NPM, but not Yarn, is to use a non-string value:

"dependencies": {
  "foo": ["unused package"],
}

A workaround that works in NPM and Yarn is a comment added as a part of semantic versioning:

"dependencies": {
  "bar": "^2",
  "foo": "^2 || should be removed in 1.x release"
}

Notice that if the first part before OR doesn't match, versions from a comment can be parsed, e.g. 1.x.

Packages that need to be commented, but not installed, should be moved to another key, e.g. dependencies //:

"dependencies //": {
  "baz": "unused package",
}
Lenalenard answered 18/2, 2019 at 10:47 Comment(4)
With npm 8.5.2., the syntax "foo": "^2 || should be removed in 1.x release" worked with a local npm install, but in CI it gave me the error "Please update your lock file with npm install before continuing. Invalid: lock file's foo@2 does not satisfy foo@^2 || should be removed in 1.x release". Might be my problem. I did push the lock file.Richert
@Richert Interesting. What happened during CI, was it npm install or npm ci that was used?Lenalenard
It's good to know that you still consider it ought to work. It was npm ci. I would guess then that I have a Node version mismatch on my Jenkins, as per https://mcmap.net/q/65657/-npm-ci-can-only-install-packages-with-an-existing-package-lock-json-or-npm-shrinkwrap-json-with-lockfileversion-gt-1. Thanks.Richert
@Richert Yes, didn't have problems with this approach so far. I'd pay the attention to NPM versions mismatch, it's the first thing to check for lockfile problemsLenalenard
E
7

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

Estipulate answered 7/2, 2015 at 9:27 Comment(3)
I think this is the "correct" answer in many ways (task to strip comments with diff patching to account for post-strip changes) -- however, I get the sense that the added weight of a grunt task is not what some people are after, For small projects, probably best to keep an external file for commentary and use NPM scrpts (avoids build tasks altogether). For large projects, you're probably using some form of task runner, so this approach seems solid. Between the two, I think maybe adapting the "//" suggestion to taste (avoiding one's particular pain points) is about the best that can be done.Rhenium
I like this idea, but as someone asked on the gist, what about the case where you're modifying the original package.json through npm install --save or --save-dev?Caitlyncaitrin
yeah I keep missing those comments; theres no good solution, I used to look at git diffs and update my .js file after updatingEstipulate
S
7

To summarise all of these answers:

  1. Add a single top-level field called // that contains a comment string. This works, but it sucks because you can't put comments near the thing they are commenting on.

  2. Add multiple top-level fields starting with //, e.g. //dependencies that contains a comment string. This is better, but it still only allows you to make top-level comments. You can't comment individual dependencies.

  3. Add echo commands to your scripts. This works, but it sucks because you can only use it in scripts.

These solutions are also all not very readable. They add a ton of visual noise and IDEs will not syntax highlight them as comments.

I think the only reasonable solution is to generate the package.json from another file. The simplest way is to write your JSON as JavaScript and use Node.js to write it to package.json. Save this file as package.json.mjs, chmod +x it, and then you can just run it to generate your package.json.

#!/usr/bin/env node

import { writeFileSync } from "fs";

const config = {
  // TODO: Think of better name.
  name: "foo",
  dependencies: {
    // Bar 2.0 does not work due to bug 12345.
    bar: "^1.2.0",
  },
  // Look at these beautify comments. Perfectly syntax highlighted, you
  // can put them anywhere and there no risk of some tool removing them.
};

writeFileSync("package.json", JSON.stringify({
    "//": "This file is \x40generated from package.json.mjs; do not edit.",
    ...config
  }, null, 2));

It uses the // key to warn people from editing it. \x40generated is deliberate. It turns into @generated in package.json and means some code review systems will collapse that file by default.

It's an extra step in your build system, but it beats all of the other hacks here.

Soubriquet answered 20/5, 2020 at 16:48 Comment(1)
I do like this approach, but then again there comes the problem of running npm i ... and keeping the dependencies up to date in the source fileUniformize
V
4

I ended up with a scripts like that:

  "scripts": {
    "//-1a": "---------------------------------------------------------------",
    "//-1b": "---------------------- from node_modules ----------------------",
    "//-1c": "---------------------------------------------------------------",
    "ng": "ng",
    "prettier": "prettier",
    "tslint": "tslint",
    "//-2a": "---------------------------------------------------------------",
    "//-2b": "--------------------------- backend ---------------------------",
    "//-2c": "---------------------------------------------------------------",
    "back:start": "node backend/index.js",
    "back:start:watch": "nodemon",
    "back:build:prod": "tsc -p backend/tsconfig.json",
    "back:serve:prod": "NODE_ENV=production node backend/dist/main.js",
    "back:lint:check": "tslint -c ./backend/tslint.json './backend/src/**/*.ts'",
    "back:lint:fix": "yarn run back:lint:check --fix",
    "back:check": "yarn run back:lint:check && yarn run back:prettier:check",
    "back:check:fix": "yarn run back:lint:fix; yarn run back:prettier:fix",
    "back:prettier:base-files": "yarn run prettier './backend/**/*.ts'",
    "back:prettier:fix": "yarn run back:prettier:base-files --write",
    "back:prettier:check": "yarn run back:prettier:base-files -l",
    "back:test": "ts-node --project backend/tsconfig.json node_modules/jasmine/bin/jasmine ./backend/**/*spec.ts",
    "back:test:watch": "watch 'yarn run back:test' backend",
    "back:test:coverage": "echo TODO",
    "//-3a": "---------------------------------------------------------------",
    "//-3b": "-------------------------- frontend ---------------------------",
    "//-3c": "---------------------------------------------------------------",
    "front:start": "yarn run ng serve",
    "front:test": "yarn run ng test",
    "front:test:ci": "yarn run front:test --single-run --progress=false",
    "front:e2e": "yarn run ng e2e",
    "front:e2e:ci": "yarn run ng e2e --prod --progress=false",
    "front:build:prod": "yarn run ng build --prod --e=prod --no-sourcemap --build-optimizer",
    "front:lint:check": "yarn run ng lint --type-check",
    "front:lint:fix": "yarn run front:lint:check --fix",
    "front:check": "yarn run front:lint:check && yarn run front:prettier:check",
    "front:check:fix": "yarn run front:lint:fix; yarn run front:prettier:fix",
    "front:prettier:base-files": "yarn run prettier \"./frontend/{e2e,src}/**/*.{scss,ts}\"",
    "front:prettier:fix": "yarn run front:prettier:base-files --write",
    "front:prettier:check": "yarn run front:prettier:base-files -l",
    "front:postbuild": "gulp compress",
    "//-4a": "---------------------------------------------------------------",
    "//-4b": "--------------------------- cypress ---------------------------",
    "//-4c": "---------------------------------------------------------------",
    "cy:open": "cypress open",
    "cy:headless": "cypress run",
    "cy:prettier:base-files": "yarn run prettier \"./cypress/**/*.{js,ts}\"",
    "cy:prettier:fix": "yarn run front:prettier:base-files --write",
    "cy:prettier:check": "yarn run front:prettier:base-files -l",
    "//-5a": "---------------------------------------------------------------",
    "//-5b": "--------------------------- common ----------------------------",
    "//-5c": "---------------------------------------------------------------",
    "all:check": "yarn run back:check && yarn run front:check && yarn run cy:prettier:check",
    "all:check:fix": "yarn run back:check:fix && yarn run front:check:fix && yarn run cy:prettier:fix",
    "//-6a": "---------------------------------------------------------------",
    "//-6b": "--------------------------- hooks -----------------------------",
    "//-6c": "---------------------------------------------------------------",
    "precommit": "lint-staged",
    "prepush": "yarn run back:lint:check && yarn run front:lint:check"
  },

My intent here is not to clarify one line, just to have some sort of delimiters between my scripts for backend, frontend, all, etc.

I'm not a huge fan of 1a, 1b, 1c, 2a, ... but the keys are different and I do not have any problem at all like that.

Vanillic answered 4/3, 2018 at 14:43 Comment(0)
D
2

As of pnpm 7.17.1, which was just released, you can switch to pnpm for package management, move your package.json to package.json5, and comments in package.json5 are allowed and will be preserved by pnpm. Note however that for publishing as a package to use on the npm registry (for example), a package.json5 will not be recognized by other package managers and I doubt by all of the registry's processing. So you would have to convert the package.json5 to a package.json before publishing. On the other hand, for "top-level applications" that are unlikely to be included as packages in other projects, a package.json5 seems to work just fine, as long as you then stick with pnpm as your package manager.

Deberadeberry answered 27/11, 2022 at 2:0 Comment(0)
F
1

As duplicate comment keys are removed running package.json tools (npm, yarn, etc.), I came to using a hashed version which allows for better reading as multiple lines and keys like:

"//": {
  "alpaca": "we use the bootstrap version",
  "eonasdan-bootstrap-datetimepicker": "instead of bootstrap-datetimepicker",
  "moment-with-locales": "is part of moment"
},

which is 'valid' according to my IDE as a root key, but within dependencies it complains expecting a string value.

Fricative answered 6/6, 2018 at 7:36 Comment(1)
yeah b/c you can't really but the // key everywhere, it's not really a good substitute for comments, especially when comments can have nice syntax highlighting with an editor etc.Liliuokalani
F
1

I do something that's some of you might like:

This // inside of the name means it's a comment for me:

  "//":"Main and typings are used till ES5",
  "//main": "build/index",
  "//typings": "build/index",
Flatt answered 3/7, 2020 at 18:43 Comment(0)
M
1

Commands in "scripts" are bash code - and we can comment bash:

"dedup": "yarn-deduplicate && yarn # TODO remove this on yarn/npm v2 because integrated"

Bonus: when you run it - you will see the comment too:yarn deduplication comment

Manifesto answered 14/10, 2022 at 12:37 Comment(0)
D
0

Another hack

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"

}}}
Dominance answered 3/3, 2019 at 20:18 Comment(0)
A
0

For npm's package.json, I have found two ways (after reading this conversation):

  "devDependencies": {
    "del-comment": [
      "some-text"
    ],
    "del": "^5.1.0 ! inner comment",
    "envify-comment": [
      "some-text"
    ],
    "envify": "4.1.0 ! inner comment"
  }

But with the update or reinstall of package with "--save" or "--save-dev, a comment like "^4.1.0 ! comment" in the corresponding place will be deleted. And all this will break npm audit.

Aviculture answered 30/1, 2020 at 11:2 Comment(1)
wouldn't this try to install packages named del-comment and envify-comment ?Hindward
A
0

I like this:

  "scripts": {
    "⏬⏬⏬ Jenkins Build - in this order ⏬⏬⏬                                                                                                  ": "",
    "purge": "lerna run something",
    "clean:test": "lerna exec --ignore nanana"
}

There are extra spaces in the command name, so in Visual Studio Code's NPM Scripts plugin you have a better look.

Ambassadoratlarge answered 18/6, 2020 at 19:25 Comment(1)
Perhaps finally a reasonable way of using emojis?Luster
J
0

Here is another take on that matter - for commenting scripts in npm.

Consider that scripts are arguments to 'npm run'. So what is the standard way of getting description of some commands passed through arguments?

One is usually typing executable command --help to get help on a command, another common pattern is executable help command. Following the second pattern you can have following code in your npm scripts:

"scripts": {
"help": "node -e \"const {spawn} = require('child_process');spawn('npm', ['run','help '+process.argv[1]],{stdio:'inherit'})\"",

"help some-command":"echo 'some-command executes a command sequence, the command line is: npm run some-command [--some-switch] [--some-parameter=value] '"

"some-command":"execute; command; sequence",
}

Now you can run intuitive command npm run help some-command and it will run the script "help some-command".

The "help" script is for convenience as it's only purpose is to not be forced to type unintuitive npm run "help some-command" with quotes in order to run the "help some-command" script.

Jowett answered 14/8, 2023 at 9:22 Comment(0)
C
-1

My take on the frustration of no comments in JSON. I create new nodes, named for the nodes they refer to, but prefixed with underscores. This is imperfect, but functional.

{
  "name": "myapp",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "react-scripts": "1.1.4"
  },
  "scripts": {
    "__start": [
        "a note about how the start script works"
    ],
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "__proxy": [
    "A note about how proxy works",
    "multilines are easy enough to add"
  ],
  "proxy": "http://server.whatever.com:8000"
}
Chihuahua answered 30/5, 2018 at 22:30 Comment(1)
using start_comment would be better, because then it will order alphabeticallyLiliuokalani
L
-1

In addition to the global // comment (or array of comments), you can use the semver pipe separator for comments on particular dependencies, e.g.

"@types/node": "^16.11.7 || keep-same-major-version-as-node"

Lindie answered 5/7, 2022 at 9:29 Comment(1)
That looks very nice, but it would also lead to npm trying to resolve your comment as a package version / try to download itKristalkristan

© 2022 - 2024 — McMap. All rights reserved.