如何为package.json添加注释以进行npm install?

Wil*_*ver 360 comments npm

我有一个简单的package.json文件,我想添加一个评论.有办法做到这一点,还是有任何黑客可以使这项工作?

{
  "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 */
  }
}
Run Code Online (Sandbox Code Playgroud)

上面的示例注释不适用于npm中断.我也试过//风格评论.

Igo*_*rez 422

最近在node.js邮件列表中讨论过这个问题.

据创建npm的Isaac Schlueter说:

..."@"键永远不会被npm用于任何目的,并保留用于注释...如果要使用多行注释,可以使用数组或多个"//"键.

使用常用工具(npm,纱线等)时,将删除多个"//"键.幸存下来:

{ "//": [ 
  "first line", 
  "second line" ] } 
Run Code Online (Sandbox Code Playgroud)

这将无法生存:

{ "//": "this is the first line of a comment", 
  "//": "this is the second line of the comment" } 
Run Code Online (Sandbox Code Playgroud)

  • 有没有办法记录"依赖"部分中的每个条目是什么?当它是"依赖"的attr时,"//"技巧不起作用. (55认同)
  • 必须要注意"//"只能在`package.json`对象的根*上使用*.例如`{"dependencies":{"//":"comment?" ``无效但是`{"//":"comment!","dependencies":{}}`是有效的. (55认同)
  • 即使Douglas Crockford在JSON配置文件中添加注释也没有问题.NPM的情况至少可以说是愚蠢的. (48认同)
  • 请注意,使用多个注释,如第一个示例`{"//":"first","//":"second"}`阻止您使用`npm version`和其他命令行工具,它们通常会重新整理整个JSON和丢弃正在处理的重复密钥. (6认同)
  • 根据我的经验,"//"`键及其值最终会被擦掉.有没有办法获得永久性评论? (5认同)
  • 您必须小心放置“`//`”键的位置:`npm ERR!代码EINVALIDPACKAGENAME``npm ERR!无效的包名称“ //”:名称只能包含URL友好字符 (3认同)
  • 对此做了很多阅读,我的想法是几种方法之间的交叉-因为“ //”是有效的并建议使用-为什么不像“ // scripts”,“ // dependencies”,“ // devDependencies之类的东西”等作为评论部分(作为适用部分的直接兄弟姐妹)?这样可以将内容保留在文件本地,无需通过jsmin进行预处理(如crockford所建议-并在npm中完全损坏),允许重复剥离和npm正常处理将其忽略,并且发生冲突/冲突的可能性几乎为零- -最糟糕的缺点是直接的地理位置-但是在所有情况下都是最好的 (2认同)
  • 不适用于 clangcompile_commands.json,它们要求每个标签都在不包含“//”的预定义集中。没有注释绝对是 json 格式的糟糕设计。由于没有评论,已经浪费了 10 多分钟 (2认同)
  • 断言 json 不需要注释就像断言 1MB RAM 对于 PC 来说足够了。现在Json无处不在,不仅限于对象数据。许多用例自然需要注释,例如 json 作为配置文件。 (2认同)

Jon*_*den 116

这是在JSON中添加注释的另一个hack.以来:

{"a": 1, "a": 2}
Run Code Online (Sandbox Code Playgroud)

相当于

{"a": 2}
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

{
  "devDependencies": "'mocha' not needed as should be globally installed",
  "devDependencies" :  {
    "should": "*"
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,虽然这个hack阻止你以编程方式更改`package.json`,比如用'npm版本1.2.3`来修改版本 - 冗余条目将从生成的JSON中删除. (17认同)
  • 这是一个糟糕的建议,因为无法保证解释对象的顺序.例如,在某些情况下,您的示例可能最终为1而不是2. (14认同)
  • 这也适用于特定的包级别.例如.`"表达":"使路由更好,所以我不想掏出我的眼睛","表达":"3.x"`.所以,是的,像科林所说的那样"糟糕",而且正如科林所说的那样"谢谢". (12认同)
  • @mpen风险在于无法保证解析JSON的代码会按顺序执行. (6认同)
  • 为了记录,[RFC](https://tools.ietf.org/html/rfc7159)明确地说:"当对象中的名称不唯一时,接收这样一个对象的软件的行为是不可预测的.实现只报告姓氏/值对.其他实现报告错误或解析对象失败,一些实现报告所有名称/值对,包括重复." (5认同)
  • npm 5.6.0会在npm安装过程中删除重复项 (2认同)
  • 这个解决方案太危险了(根据所有评论),因此不值得推荐的数量。为什么要使用您的代码玩俄罗​​斯轮盘赌? (2认同)
  • 这是 Heisenbug 等待发生的事情。我能听到Archer的声音说:“你想要Heisenbugs吗?因为这就是你获得Heisenbugs的方式。” (2认同)

gko*_*ond 85

在浪费了一个小时的复杂和hacky解决方案后,我发现自己是一个非常简单,优雅和有效的解决方案,用于评论我庞大的依赖关系部分package.json.像这样:

{
  "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"
  }
}
Run Code Online (Sandbox Code Playgroud)

当以相同的方式排序时,现在我很容易在git commit diffs或编辑器中跟踪这些依赖关系/注释对package.json.

并没有涉及额外的工具,只是简单而有效的JSON.

希望这有助于任何人.

  • 关于脚本的评论,为什么不提供"帮助"脚本,例如"脚本":{"postinstall":"echo postinstall stuff to here","help-postinstall":"echo helpful stuff goes here"} (4认同)
  • 感谢您提供技术上有效且语义有用的非hacky解决方案. (2认同)
  • @峰谢谢!我看到的唯一缺点是实际脚本将与注释混合。 (2认同)
  • 对我有用......我将它与使用数组“[]”结合起来进行多行注释。就像@Igor Soarez 的回答一样。 (2认同)

thi*_*ign 16

受此线程的启发,这是我们正在使用的内容

{
  "//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"
  }
}
Run Code Online (Sandbox Code Playgroud)


Phi*_*ßen 15

您始终可以滥用重复密钥被覆盖的事实.这就是我刚写的内容:

"dependencies": {
  "grunt": "...",
  "grunt-cli": "...",

  "api-easy": "# Here is the pull request: https://github.com/...",
  "api-easy": "git://..."

  "grunt-vows": "...",
  "vows": "..."
}
Run Code Online (Sandbox Code Playgroud)

但是,目前尚不清楚JSON是否允许重复键(请参阅 JSON语法是否允许对象中的重复键?.它似乎与npm一起使用,因此我承担风险.

推荐的hack是使用"//"密钥(来自nodejs邮件列表).当我测试它时,它不适用于"依赖"部分.此外,帖子中的示例使用多个"//"键,这意味着npm不会拒绝具有重复键的JSON文件.换句话说,上面的黑客应该总是很好.

更新:重复密钥破解的一个令人讨厌的缺点是npm install --save无声地消除所有重复.不幸的是,它很容易被忽视,你的善意评论也消失了.

"//"黑客仍是最安全的,因为它似乎.但是,多行注释也将被删除npm install --save.


Jim*_*yle 13

NPS(Node Package Scripts)为我解决了这个问题.允许您将NPM脚本放入单独的JS文件中,您可以在其中添加注释以及您需要的任何其他JS逻辑. https://www.npmjs.com/package/nps

package-scripts.js来自我的一个项目的示例

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'
  }
}
Run Code Online (Sandbox Code Playgroud)

我刚刚进行了本地安装npm install nps -save-dev并将其放入我的package.json脚本中.

"scripts": {
    "start": "nps",
    "test": "nps test"
}
Run Code Online (Sandbox Code Playgroud)


Fel*_*ura 11

许多有趣的想法。

我一直在做的是这样的:

{
  ...
  "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",
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

这样,我既可以阅读脚本本身中的“伪注释”,也可以运行如下所示的内容,以在终端中查看某种帮助:

npm run about
npm run about:watch
Run Code Online (Sandbox Code Playgroud)

我的2cents在此讨论:)

  • 在我看来,这是最好的选择,因为它允许用户获取命令信息,而无需实际打开“package.json”。 (3认同)
  • 我正在做 `"//build": "echo 'something about build'"`。在我看来,这使得钥匙更加突出...... (3认同)

Est*_*ask 10

正如这个答案所解释的,该//密钥已被保留,因此可以按常规方式用于注释。注释的问题//是它不实用,因为它不能多次使用。package.json自动更新时删除重复的键:

"//": "this comment about dependencies stays",
"dependencies": {}
"//": "this comment disappears",
"devDependencies": {}
Run Code Online (Sandbox Code Playgroud)

另一个问题是//注释不能在内部使用dependenciesdevDependencies因为它被视为常规依赖项:

"dependencies": {
  "//": "comment"
}
Run Code Online (Sandbox Code Playgroud)

npm 错误!代码 EINVALIDPACKAGENAME

npm 错误!无效的包名称“//”:名称只能包含 URL 友好的字符

在 NPM 中有效但在 Yarn 中无效的解决方法是使用非字符串值:

"dependencies": {
  "foo": ["unused package"],
}
Run Code Online (Sandbox Code Playgroud)

在 NPM 和 Yarn 中有效的解决方法是添加注释作为语义版本控制的一部分:

"dependencies": {
  "bar": "^2",
  "foo": "^2 || should be removed in 1.x release"
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果前面的第一部分OR不匹配,则可以解析注释中的版本,例如1.x.

需要注释但未安装的软件包应移至另一个键,例如dependencies //

"dependencies //": {
  "baz": "unused package",
}
Run Code Online (Sandbox Code Playgroud)


Lia*_*Kai 9

我有一个有趣的黑客想法.

例如,在package.json中适当地创建npm包名称作为注释分隔符dependenciesdevDependenciesx----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": "*"
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:必须添加最后一个注释分隔线与有效版本,如*块.

  • 对这个答案感到非常兴奋,但在我运行`npm install`(使用npm 5)后,我的重复键被自动删除了:( (7认同)
  • 是的,它实际上是可用的:https://www.npmjs.com/package/x----x----x (6认同)

Mar*_*del 6

到目前为止,大多数"黑客"都建议滥用JSON.但相反,为什么不滥用底层脚本语言呢?

编辑初始响应是将描述放在右边# add comments here用来包装它; 但是,这在Windows上不起作用,因为标志(例如npm run myframework - --myframework-flags)将被忽略.我更改了我的响应以使其在所有平台上都能正常工作,并为可读性添加了一些缩进.

{
 "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"
  }
}
Run Code Online (Sandbox Code Playgroud)

这将:

  1. 不破坏JSON合规性(或者至少它不是一个黑客,你的IDE不会给你做出奇怪,危险的警告)
  2. 跨平台工作(在macOS和windows上测试,假设它在Linux上运行正常)
  3. 不妨碍跑步 npm run myframework -- --help
  4. 运行时将输出有意义的信息npm run(这是运行以获取有关可用脚本的信息的实际命令)
  5. 提供更明确的帮助命令(如果某些开发人员不知道npm run提供此类输出)
  6. 在运行命令本身时将显示命令及其描述
  7. 只是打开package.json(使用less或您喜欢的IDE)时有点可读

  • 它只适用于`scripts`部分.`package.json`还有很多其他的东西. (2认同)

Mar*_*Zab 5

这是我对package.json/中的评论的看法bower.json:

我有package.json.js一个包含导出实际的脚本package.json.运行脚本会覆盖旧脚本,package.json并告诉我它所做的更改,非常适合帮助您跟踪npm所做的自动更改.这样我甚至可以以编程方式定义我想要使用的包.

最新的grunt任务在这里:https: //gist.github.com/MarZab/72fa6b85bc9e71de5991

  • 我喜欢这个想法,但正如有人问到要旨,你通过 `npm install --save` 或 `--save-dev` 修改原始 package.json 的情况怎么样? (2认同)

Dan*_*urt 5

由于大多数开发人员都熟悉基于标签/注释的文档,因此我开始使用的约定是相似的。这是一个味道:

{
  "@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": {
    ...
  },
  "@comment scripts": {
    "build": "This comment is about the build script.",
    "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."
    ],
    "test": "This comment is about the test script.",
  },
  "scripts": {
    "build": "...",
    "start": "...",
    "test": "..."
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:对于dependenciesdevDependencies等的部分中,注释的注释不能直接上述结构物体内部的单个包装体的依赖关系,因为加入npm期待的关键是NPM包的名称。因此@comment dependencies.

我喜欢向 JSON 添加注释的注释/标签样式方式,因为该@符号从普通声明中脱颖而出。

较早的推荐

以下是我之前的推荐。它内联了脚本的注释,但我开始意识到这些注释在某些工具中显示为“命令”(在 VS Code > Explorer > NPM 脚本部分)。最新推荐确实存在此问题,但脚本注释不再位于同一位置。

{
  "@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": "..."
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:在某些上下文中,例如在"scripts"对象中,一些编辑器/IDE 可能会抱怨数组。在脚本上下文中,VS Code 需要一个字符串作为值——而不是一个数组。


Tim*_*mmm 5

总结所有这些答案:

  1. 添加一个包含注释字符串的名为的顶级字段//。这有效,但它很糟糕,因为您不能在他们正在评论的东西附近添加评论。

  2. 添加多个以开头的顶级字段,例如包含注释字符串的字段。这更好,但它仍然只允许您进行顶级评论。您不能评论单个依赖项。 ////dependencies

  3. echo命令添加到您的scripts. 这有效,但很糟糕,因为您只能在scripts.

这些解决方案也都不是很可读。它们添加了大量的视觉噪音,IDE 不会将它们语法高亮为注释。

我认为唯一合理的解决方案是package.json从另一个文件生成。最简单的方法是将您的 JSON 编写为 JavaScript 并使用 Node.js 将其写入package.json. 将此文件另存为package.json.mjs, chmod +xit,然后您就可以运行它来生成您的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));
Run Code Online (Sandbox Code Playgroud)

它使用//密钥来警告人们不要编辑它。\x40generated是故意的。它变成@generatedinpackage.json并且意味着一些代码审查系统默认会折叠该文件。

这是构建系统中的一个额外步骤,但它击败了这里的所有其他黑客。

  • 我确实喜欢这种方法,但又出现了运行“npm i ...”并保持源文件中的依赖项最新的问题 (3认同)