wake-up-neo.com

Wie füge ich Kommentare zu package.json für npm install hinzu?

Ich habe eine einfache package.json-Datei und möchte einen Kommentar hinzufügen. Gibt es eine Möglichkeit, dies zu tun, oder gibt es irgendwelche Hacks, um dies zu erreichen?

{
  "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 */
  }
}

Der obige Beispielkommentar funktioniert nicht, da npm bricht. Ich habe auch // Stilkommentare ausprobiert.

318
Will Shaver

Dies wurde kürzlich in der Mailingliste node.js diskutiert.

Laut Isaac Schlueter, der npm erstellt hat:

Die "//" - Taste wird von npm niemals für irgendeinen Zweck verwendet und ist für Kommentare reserviert ... Wenn Sie einen mehrzeiligen Kommentar verwenden möchten, können Sie entweder ein Array oder mehrere "//" verwenden. Schlüssel.

Bei Verwendung Ihrer üblichen Werkzeuge (npm, Garn usw.) werden mehrere "//" - Schlüssel entfernt. Das überlebt:

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

Das wird nicht überleben:

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

Hier ist ein weiterer Hack zum Hinzufügen von Kommentaren in JSON. Schon seit:

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

Ist äquivalent zu 

{"a": 2}

Sie können so etwas tun:

{
  "devDependencies": "'mocha' not needed as should be globally installed",
  "devDependencies" :  {
    "should": "*"
  }
}
106
Jonathan Warden

Nachdem ich eine Stunde mit komplexen und hackigen Lösungen verschwendet hatte, fand ich eine ziemlich einfache, elegante und gültige Lösung zum Kommentieren meines umfangreichen Abhängigkeitsabschnitts in package.json. Genau wie dieser:

{
  "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"
  }
}

Wenn ich auf dieselbe Weise sortiert bin, kann ich diese Paare von Abhängigkeiten/Kommentaren entweder in git commit diffs oder im Editor während der Arbeit mit package.json leicht nachverfolgen.

Und es sind keine zusätzlichen Tools erforderlich, nur reines und gültiges JSON.

Hoffe, das hilft jedem.

58
gkond

Sie können immer die Tatsache missbrauchen, dass doppelte Schlüssel überschrieben werden. Das habe ich gerade geschrieben:

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

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

  "grunt-vows": "...",
  "vows": "..."
}

Es ist jedoch nicht klar, ob JSON doppelte Schlüssel zulässt (see Erlaubt JSON-Syntax doppelte Schlüssel in einem Objekt? . Es scheint mit npm zu funktionieren, daher gehe ich das Risiko ein.

Der empfohlene Hack ist die Verwendung von "//"-Schlüsseln (aus der nodejs-Mailingliste ). Als ich es getestet habe, funktionierte es jedoch nicht mit "Abhängigkeiten" -Abschnitten. Das Beispiel im Beitrag verwendet mehrere "//"-Schlüssel, was bedeutet, dass npm JSON-Dateien mit duplizierten Schlüsseln nicht ablehnt. Mit anderen Worten, der obige Hack sollte immer in Ordnung sein.

Update: Ein ärgerlicher Nachteil des duplizierten Schlüssel-Hacks besteht darin, dass npm install --save alle Duplikate automatisch entfernt. Leider ist es sehr leicht zu übersehen und Ihre gut gemeinten Kommentare sind weg.

Der "//"-Hack ist immer noch der sicherste, wie es scheint. Mehrzeilige Kommentare werden jedoch auch von npm install --save entfernt.

14
Philipp Claßen

NPS (Node Package Scripts) hat dieses Problem für mich gelöst. Sie können Ihre NPM-Skripts in einer separaten JS-Datei ablegen, in der Sie Kommentare und jede andere JS-Logik hinzufügen können, die Sie benötigen . https://www.npmjs.com/package/nps

Beispiel für den package-scripts.js aus einem meiner Projekte

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'
  }
}

Ich habe gerade eine lokale Installation npm install nps -save-dev durchgeführt und dies in meine package.json-Skripts eingefügt.

"scripts": {
    "start": "nps",
    "test": "nps test"
}
11
Jim Doyle

Ich habe eine lustige Hack-Idee.

Erstellen Sie einen geeigneten npm-Paketnamen als Kommentarteiler für dependencies- und devDependencies-Block in package.json, zum Beispiel 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: Muss die letzte Kommentarteilerzeile mit gültiger Version wie * im Block hinzufügen.

8
Liao San Kai

Hier sind meine Kommentare zu package.json/bower.json:

Ich habe package.json.js, das ein Skript enthält, das den tatsächlichen package.json exportiert. Beim Ausführen des Skripts wird der alte package.json überschrieben, und es wird angezeigt, welche Änderungen vorgenommen wurden. Dies ist perfekt, um die automatischen Änderungen npm verfolgen zu können. Auf diese Weise kann ich sogar programmatisch definieren, welche Pakete ich verwenden möchte. 

Die letzte Grunzaufgabe ist hier: https://Gist.github.com/MarZab/72fa6b85bc9e71de5991

5
MarZab

Bisher schlagen die meisten "Hacks" vor, JSON zu missbrauchen. Warum aber nicht die zugrunde liegende Skriptsprache missbrauchen?

Edit Die erste Antwort bestand darin, die Beschreibung auf der rechten Seite zu setzen und # add comments here zu verwenden, um sie einzuhüllen. Dies funktioniert jedoch nicht unter Windows, da Flags (z. B. npm myframework - --myframework-flags ausführen) ignoriert werden. Ich habe meine Antwort so geändert, dass sie auf allen Plattformen funktioniert und einige Einrückungen zur besseren Lesbarkeit hinzugefügt.

{
 "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"
  }
}

Dieser Wille:

  1. Brechen Sie die JSON-Kompatibilität nicht (oder zumindest ist es kein Hack), und Ihre IDE gibt Ihnen keine Warnungen, wenn Sie ungewöhnliche, gefährliche Dinge tun.
  2. Funktioniert plattformübergreifend (getestet unter MacOS und Windows, vorausgesetzt, es würde unter Linux gut funktionieren)
  3. Stört nicht beim Laufen npm run myframework -- --help 
  4. Gibt aussagekräftige Informationen aus, wenn npm run ausgeführt wird (der eigentliche Befehl, um Informationen zu verfügbaren Skripts abzurufen).
  5. Zeigt einen expliziteren Hilfebefehl an (falls einige Entwickler nicht wissen, dass npm run eine solche Ausgabe präsentiert).
  6. Zeigt sowohl die Befehle als auch ihre Beschreibung an, wenn der Befehl selbst ausgeführt wird
  7. Ist etwas lesbar, wenn Sie einfach package.json (mit less oder Ihrer Lieblings-IDE) öffnen
5
Marc Trudel

Viele interessante Ideen.

Was ich gemacht habe, ist folgendes:

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

Auf diese Weise kann ich sowohl die "Pseudo-Kommentare" im Skript selbst lesen, als auch Folgendes ausführen, um eine Art Hilfe in terminal zu sehen:

npm run about
npm run about:watch

Meine 2 Cent für diese Diskussion :)

4
Felipe N Moura

Da doppelte Kommentarschlüssel entfernt werden, die package.json-Tools ausführen (npm, garne usw.), kam ich zur Verwendung einer Hash-Version, die ein besseres Lesen als mehrere Zeilen und Tasten ermöglicht

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

dies ist gemäß meinem IDE als Stammschlüssel "gültig", aber innerhalb von dependencies beschwert es sich, einen Stringwert zu erwarten.

0
Clemens Tolboom

Inspiriert von diesem Thread, hier ist was wir verwenden :

{
  "//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"
  }
}
0
thisismydesign

Ein weiterer Hack. Ich habe ein Skript zum Lesen von package.json als Kontext für eine Lenkervorlage erstellt.

Code unten für den Fall, dass jemand diesen Ansatz nützlich findet:

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() {
  // first arg is object, 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;
  });
});

lenker-Vorlagendatei 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"

}}}
0
forforf

Ich endete mit einer scripts so:

  "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"
  },

Ich möchte hier nicht eine Zeile klarstellen, sondern nur eine Art Trennzeichen zwischen meinen Skripten für Backend, Frontend usw.

Ich bin kein großer Fan von 1a, 1b, 1c, 2a, ... aber die Tasten unterscheiden sich und ich habe überhaupt keine Probleme damit.

0
maxime1992

Wie diese Antwort erklärt, wurde die Taste // reserviert, sodass sie auf herkömmliche Weise für Kommentare verwendet werden kann. Das Problem mit dem Kommentar // ist, dass er in dependencies und devDependencies nicht als reguläre Abhängigkeit mit einer Zeichenfolge als Versionsbeschränkung verwendet werden kann:

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

löst einen Fehler aus,

npm ERR! Code EINVALIDPACKAGENAME

npm ERR! Ungültiger Paketname "//": Der Name darf nur URL-freundliche Zeichen enthalten

Obwohl Schlüssel mit Nicht-String-Werten als ungültige Abhängigkeiten betrachtet und effizient ignoriert werden:

"dependencies": {
  "//": ["comment"]
}

Eine Abhängigkeit selbst kann auf dieselbe Weise auskommentiert werden:

"dependencies": {
  "foo": ["*", "is not needed now"],
}

Da Abhängigkeiten sortiert werden, wenn package.json von NPM geändert wird, ist es unpraktisch, einen Kommentar über einer Abhängigkeit zu platzieren, auf die es verweist:

"dependencies": {
  "bar": "*",
  "//": ["should be removed in 1.x release"]
  "foo": "*",
}

Kommentarschlüssel sollten entsprechend benannt werden, wenn er sich auf eine bestimmte Zeile bezieht, damit er nicht verschoben wird:

"dependencies": {
  "bar": "*",
  "foo": "*",
  "foo //": ["should be removed in 1.x release"]
}

Ein Kommentar, der auf bestimmte Abhängigkeiten anwendbar ist, kann als Teil von semver hinzugefügt werden:

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

Beachten Sie, dass ein Kommentar analysiert werden kann, wenn der erste Teil vor OR nicht übereinstimmt, z. 1.x.

Diese Problemumgehungen sind mit allen aktuellen NPM-Versionen (6 und niedriger) kompatibel.

0
Estus Flask