Gibt es eine Möglichkeit, die Version von package.json in nodejs Code abzurufen?

586

Gibt es eine Möglichkeit, die package.jsonin einer NodeJS-App festgelegte Version zu erhalten ? Ich würde so etwas wollen

var port = process.env.PORT || 3000
app.listen port
console.log "Express server listening on port %d in %s mode %s", app.address().port, app.settings.env, app.VERSION
Abhik Bose Pramanik
quelle
Ist es wichtiger, die Version von Node oder die in package.json deklarierte Version zu erhalten? Wenn das Formular, wird dies Ihnen die laufende Version geben:console.log(process.version)
Adrian Lynch

Antworten:

957

Ich fand, dass das folgende Codefragment für mich am besten funktioniert. Da es requirezum Laden von verwendet wird package.json, funktioniert es unabhängig vom aktuellen Arbeitsverzeichnis.

var pjson = require('./package.json');
console.log(pjson.version);

Eine Warnung mit freundlicher Genehmigung von @Pathogen:

Dies mit Browserify zu tun, hat Auswirkungen auf die Sicherheit.
Achten Sie darauf, dass Sie nicht package.jsondem Client ausgesetzt werden, da alle Versionsnummern, Build- und Testbefehle und mehr für Abhängigkeiten an den Client gesendet werden.
Wenn Sie Server und Client im selben Projekt erstellen, legen Sie auch Ihre serverseitigen Versionsnummern offen. Solche spezifischen Daten können von einem Angreifer verwendet werden, um den Angriff auf Ihren Server besser anzupassen.

Mark Wallace
quelle
25
Wenn Sie sich immer wieder verbrennen, indem Sie versuchen, dies von verschiedenen Orten aus zu require('root-require')('package.json').version
erfassen
5
Funktioniert nicht für mein Skript mit global installiertem shebang. Error: Cannot find module 'package.json'.
Exebook
14
kürzer - erfordern ('./ Paket'). Version
Afanasii Kurakin
60
Warnung! Dies mit browserify zu tun hat Auswirkungen auf die Sicherheit: package.json in Ihrem Bundle bedeutet, dass alle Ihre Abhängigkeitsversionsnummern, Build- und Testbefehle und mehr an den Client gesendet werden. Wenn Sie Server und Client im selben Projekt erstellen, legen Sie auch die Versionsnummern auf Ihrer Serverseite offen.
Pathogen
4
@ Pathogen Genversion löst das Problem auf der Client-Seite. Es ist ein Tool, das die Version aus package.json liest und daraus ein importierbares Modul generiert. Haftungsausschluss: Ich bin ein Betreuer.
Akseli Palén
348

Wenn Ihre Anwendung mit 'npm start' gestartet wird, können Sie einfach Folgendes verwenden:

process.env.npm_package_version

Weitere Informationen finden Sie unter package.json vars .

Julien Christin
quelle
6
Dies ist wahrscheinlich die beste Antwort, da die meisten Informationen in package.json an die Prozesslaufzeitvariable angehängt sind
Alexander Mills
2
Ja, ich stimme zu. Dies sollte die richtige Antwort sein. Verwenden Sie die Prozessvariable, die Sie nicht benötigen, um die Datei package.json zu öffnen und erneut zu lesen.
Juanma
12
Außerhalb des Knotens (z. B. Shell-Skripte, die über ausgeführt werden npm run …) befindet sich die Version in der Umgebungsvariablen $npm_package_version.
Quinn Comendant
12
Beim Aufruf aus Skripten eines anderen Pakets wird fälschlicherweise die Version des aufrufenden Pakets und nicht das aufgerufene Paket gemeldet.
jjrv
6
Es funktioniert in einer Elektronen- App, die mit gestartet wurde npm start, aber nicht in einer gebauten Elektronen-App: Dafür finden Sie es in app.getVersion.
ChrisV
158

Mit ES6-Modulen können Sie Folgendes tun:

import {version} from './package.json';
Patrick Lee Scott
quelle
2
Ich dachte, dass diese in Knoten nicht unterstützt wurden: github.com/nodejs/help/issues/53
ripper234
1
Es werden noch keine es6-Module direkt unterstützt, aber dennoch häufig verwendet, aktiviert mit Babel
Patrick Lee Scott
4
@Sornii nein, die gesamte package.json befindet sich im Client. Ich habe das definePlugin des Webpacks verwendet, um nur ausgewählte Informationen aus der Knotenumgebung an den Browser zu übergeben.
Doeke
2
Gibt es Sicherheitsaspekte wie unter stackoverflow.com/a/10855054/540144 angegeben ?
Itsazzad
1
Ja, dieselben Sicherheitsprobleme. Die gesamte package.json wird in das Client-Bundle aufgenommen.
Neromancer
94

Oder in einfacher alter Schale:

node -e "console.log(require('./package.json').version);"

Dies kann auf verkürzt werden

node -p "require('./package.json').version"

Auch wenn dies nicht genau das ist, was die Frage gestellt hat, ist es nützlich, wenn Sie die Version in sich package.jsonselbst verwenden möchten , z. B. um sich bei einer versionierten Datei in einem Protokoll anzumelden script:

{
  "name": "myapp",
  "version": "0.1.2",
  "scripts": {
    "run": "node index.js 2>&1 | tee -a myapp_v$(node -p \"require('./package.json').version\").log",
  ...
}
abernier
quelle
Dies ist jedoch nicht in der nodeJS-App selbst enthalten, wie angefordert.
Steve Bennett
1
@SteveBennett Nein, aber es hat 90 Menschen und mir geholfen.
K - Die Toxizität in SO nimmt zu.
1
Wahrscheinlich viel mehr als das.
Steve Bennett
61

Es gibt zwei Möglichkeiten, die Version abzurufen:

  1. package.jsonVersion anfordern und abrufen :
const { version } = require('./package.json');
  1. Verwenden der Umgebungsvariablen:
const version = process.env.npm_package_version;

Bitte verwenden Sie nicht JSON.parse, fs.readFile, fs.readFileSyncund das andere tun nicht verwenden npm moduleses für diese Frage nicht notwendig ist.

alex dykyі
quelle
2
Vielen Dank für dieses Code-Snippet, das möglicherweise nur begrenzte, sofortige Hilfe bietet. Eine richtige Erklärung würde ihren langfristigen Wert erheblich verbessern, indem sie zeigt, warum dies eine gute Lösung für das Problem ist, und es für zukünftige Leser mit anderen, ähnlichen Fragen nützlicher machen. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, einschließlich der von Ihnen getroffenen Annahmen.
Milo526
8
Dann sind npm_*Umgebungswerte nur verfügbar, wenn Ihr Skript von NPM gestartet wurde, z npm start. Wenn Sie dies tun node app.jsoder ähnliches, sind sie nicht vorhanden.
Nate
@Nate Es ist also besser, die Version von zu verwenden package.json ?
Filip Š
38

So lesen Sie die Version aus package.json:

fs = require('fs')
json = JSON.parse(fs.readFileSync('package.json', 'utf8'))
version = json.version
Evan Moran
quelle
Ich habe das schon gesehen und es gefällt mir - kennen Sie / jemand die Überlegungen, die require() introduces? (for instance, does erfordern , dass () das Lesen von utf8 nicht unterstützt? wie Ihr Ausschnitt vermuten lässt)
electblake
4
require()speichert die Datei zwischen, was in diesem Fall keinen Unterschied machen sollte.
Jlee
@jlee Gibt es einen Grund, warum Leute dies normalerweise tun, JSON.parse(fs.readFileSync('package.json', 'utf8'))anstatt delete require.cache[require.resolve('package.json')]; require('package.json')wann sie neu laden möchten?
Mihail Malostanidis
const {version} = require ('./ package.json');
Alex Dyky
23

Es gibt eine andere Möglichkeit, bestimmte Informationen von Ihrem abzurufen package.json Datei abzurufen, nämlich das pkginfo- Modul.

Die Verwendung dieses Moduls ist sehr einfach. Sie können alle Paketvariablen abrufen mit:

require('pkginfo')(module);

Oder nur bestimmte Details (version in diesem Fall)

require('pkginfo')(module, 'version');

Und Ihre Paketvariablen werden auf gesetzt module.exports (so dass die Versionsnummer über zugänglich istmodule.exports.version ).

Sie können das folgende Codefragment verwenden:

require('pkginfo')(module, 'version');
console.log "Express server listening on port %d in %s mode %s", app.address().port, app.settings.env, module.exports.version

Dieses Modul hat eine sehr schöne Funktion - es kann in jeder Datei in Ihrem Projekt verwendet werden (z. B. in Unterordnern) und ruft automatisch Informationen von Ihrem ab package.json . Sie müssen sich also keine Sorgen machen, wo Sie package.jsonsind.

Ich hoffe das wird helfen.

Tom
quelle
1
was ist modulehier
Chovy
@chovy, moduleist nicht diese spezifische Beispielvariable; Es ist eine Variable, die das aktuelle Modul in node.js darstellt. Weitere Informationen zu
Tom
2
Ich versuche, die Version anderer Module zu erhalten, die von meinem Modul benötigt werden ... und es fällt mir schwer herauszufinden, ob pkginfo dies ermöglicht.
Michael
23

Für diejenigen, die nach einer sicheren clientseitigen Lösung suchen , die auch serverseitig funktioniert, gibt es eine Genversion . Es ist ein Befehlszeilentool, das die Version aus der nächsten package.json liest und eine importierbare CommonJS-Moduldatei generiert, die die Version exportiert. Haftungsausschluss: Ich bin ein Betreuer.

$ genversion lib/version.js

Ich erkenne an, dass die clientseitige Sicherheit nicht die primäre Absicht von OP war, aber wie in den Antworten von Mark Wallace und aug erörtert , ist sie von hoher Relevanz und auch der Grund, warum ich diese Fragen und Antworten gefunden habe.

Akseli Palén
quelle
4
Dies ist DIE Antwort, und es braucht mehr Stimmen, um die derzeit äußerst problematische Antwort zu übertreffen.
Jeff Allen
1
Einige Leute könnten durch die Tatsache alarmiert sein, dass dies ein Befehlszeilen-Tool ist. Keine Sorge! In der Readme-Datei des Tools wird beschrieben, wie Sie den Aufruf beim Erstellen (einfach) in package.json integrieren, damit Sie die Existenz des Tools vergessen und immer die neueste Versionsnummer haben.
Malamut
11

Ich habe nur eine Antwort hinzugefügt, weil ich auf diese Frage gekommen bin, um herauszufinden, wie ich die Version von package.json am besten in meine Webanwendung aufnehmen kann.

Ich weiß, dass diese Frage für Node.js bestimmt ist. Wenn Sie jedoch Webpack verwenden, um Ihre App zu bündeln, wird nur empfohlen, das DefinePlugin zu verwenden, um eine globale Version in der Konfiguration zu deklarieren und darauf zu verweisen. So könnten Sie in Ihrem tunwebpack.config.json

const pkg = require('../../package.json');

...

plugins : [
    new webpack.DefinePlugin({
      AppVersion: JSON.stringify(pkg.version),
...

Und dann AppVersionsteht Ihnen jetzt ein Global zur Verfügung. Stellen Sie außerdem sicher, dass .eslintrcSie dies über die globale Requisite ignorieren

aug
quelle
8

Option 1

Die beste Vorgehensweise ist die Versionierung von package.json unter Verwendung von npm-Umgebungsvariablen.

process.env.npm_package_version

Weitere Informationen unter: https://docs.npmjs.com/using-npm/config.html

Dies funktioniert nur, wenn Sie Ihren Dienst mit dem NPM-Befehl starten.

Kurzinfo: Sie können alle Werte in pacakge.json mit process.env.npm_package_ [keyname] lesen.

Option 2

Festlegen der Version in der Umgebungsvariablen mithilfe von https://www.npmjs.com/package/dotenv als .envDatei und in Bezug auf inprocess.env.version

Aravin
quelle
7

Mit ES6 können Sie package.json importieren, um die Versionsnummer abzurufen und die Version auf der Konsole auszugeben.

import {name as app_name, version as app_version}  from './path/to/package.json';

console.log(`App ---- ${app_name}\nVersion ---- ${app_version}`);
ÁngelBlanco
quelle
3
Dies funktioniert so lange, wie Sie "resolveJsonModule" in tsconfig.json auf "true" setzen.
Russell Phillips
6

Um die Paketversion im Knotencode zu bestimmen, können Sie Folgendes verwenden:

  1. const version = require('./package.json').version; für <ES6-Versionen

  2. import {version} from './package.json'; für ES6-Version

  3. const version = process.env.npm_package_version; Wenn die Anwendung mit gestartet wurde npm start, werden alle Umgebungsvariablen npm_ * verfügbar.

  4. Sie können auch die folgenden npm-Pakete verwenden - root-require, pkginfo, project-version.

Rohit Jaiswal
quelle
4

Sie können das Projektversionspaket verwenden .

$ npm install --save project-version

Dann

const version = require('project-version');

console.log(version);
//=>  '1.0.0'

Es verwendet process.env.npm_package_versionaber einen Fallback auf die Version, die in dem package.jsonFall geschrieben wurde, falls die env var aus irgendeinem Grund fehlt.

simonepri
quelle
Zum Beispiel, wenn die js-Datei nicht von npm gestartet wurde?
Mihail Malostanidis
1

Ich mache das mit findup-sync:

var findup = require('findup-sync');
var packagejson = require(findup('package.json'));
console.log(packagejson.version); // => '0.0.1' 
Luca Bonavita
quelle
findup beginnt mit cwd, so dass es in den meisten Fällen nur die oberste Ebene erreicht package.json, ähnlich wie process.env.npm_package_versionaußerdem, dass es nicht über npm gestartet werden muss. Wenn Sie also versuchen, Ihre Bibliotheksversion zu erhalten, erhalten Sie tatsächlich die Version des Anrufers. Eine einfache Anforderung ('./ package.json') würde dies vermeiden.
Mihail Malostanidis
1

Ich weiß, dass dies nicht die Absicht des OP ist, aber ich musste dies nur tun, also hoffe, es hilft der nächsten Person.

Wenn Sie Docker-Compose für Ihren CI / CD-Prozess verwenden, können Sie dies auf diese Weise erreichen!

version:
  image: node:7-alpine
  volumes:
    - .:/usr/src/service/
  working_dir: /usr/src/service/
  command: ash -c "node -p \"require('./package.json').version.replace('\n', '')\""

Für das Bild können Sie ein beliebiges Knotenbild verwenden. Ich benutze alpine, weil es das kleinste ist.

Patrick Lee Scott
quelle
1

Warum nicht die erforderliche Auflösung verwenden ...

const packageJson = path.dirname(require.resolve('package-name')) + '/package.json';
const { version } = require(packageJson);
console.log('version', version)

Mit diesem Ansatz arbeiten für alle Unterpfade :)

Gianluca Cirone
quelle
0

Importieren Sie Ihre package.jsonDatei in Ihre server.jsoder app.jsund greifen Sie dann auf die Eigenschaften package.json in die Serverdatei zu.

var package = require('./package.json');

Die Paketvariable enthält alle Daten in package.json.

Patharraj
quelle
0

Ich habe einen nützlichen Code erstellt, um die package.json des übergeordneten Moduls abzurufen

function loadParentPackageJson() {
    if (!module.parent || !module.parent.filename) return null
    let dir = path.dirname(module.parent.filename)
    let maxDepth = 5
    let packageJson = null
    while (maxDepth > 0) {
        const packageJsonPath = `${dir}/package.json`
        const exists = existsSync(packageJsonPath)
        if (exists) {
            packageJson = require(packageJsonPath)
            break
        }
        dir = path.resolve(dir, '../')
        maxDepth--
    }
    return packageJson
}
g00dnatur3
quelle
0

Wenn Sie Rollup verwenden, kann das rollup-plugin-replacePlugin verwendet werden, um die Version hinzuzufügen, ohne package.json für den Client verfügbar zu machen.

// rollup.config.js

import pkg from './package.json';
import { terser } from "rollup-plugin-terser";
import resolve from 'rollup-plugin-node-resolve';
import commonJS from 'rollup-plugin-commonjs'
import replace from 'rollup-plugin-replace';

export default {
  plugins: [
    replace({
      exclude: 'node_modules/**',
      'MY_PACKAGE_JSON_VERSION': pkg.version, // will replace 'MY_PACKAGE_JSON_VERSION' with package.json version throughout source code
    }),
  ]
};

Dann würden Sie im Quellcode überall dort, wo Sie die package.json-Version haben möchten, die Zeichenfolge 'MY_PACKAGE_JSON_VERSION' verwenden.

// src/index.js
export const packageVersion = 'MY_PACKAGE_JSON_VERSION' // replaced with actual version number in rollup.config.js
spwisner
quelle