Apakah ada cara untuk mendapatkan versi dari package.json dalam kode nodejs?

586

Apakah ada cara untuk mendapatkan versi yang ditetapkan di package.jsonaplikasi nodejs? Saya ingin sesuatu seperti ini

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
sumber
Apakah lebih penting untuk mendapatkan versi Node atau versi yang dideklarasikan di package.json? Jika formulir, ini akan memberikan Anda versi yang sedang berjalan:console.log(process.version)
Adrian Lynch

Jawaban:

957

Saya menemukan bahwa fragmen kode berikut bekerja paling baik untuk saya. Karena digunakan requireuntuk memuat package.json, ia berfungsi terlepas dari direktori kerja saat ini.

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

Peringatan, milik @ Patogen:

Melakukan ini dengan Browserify memiliki implikasi keamanan.
Berhati-hatilah untuk tidak mengekspos Anda package.jsonke klien, karena itu berarti bahwa semua nomor versi ketergantungan Anda, buat dan uji perintah dan banyak lagi yang dikirim ke klien.
Jika Anda membangun server dan klien dalam proyek yang sama, Anda juga mengekspos nomor versi sisi server Anda. Data spesifik tersebut dapat digunakan oleh penyerang agar lebih sesuai dengan serangan di server Anda.

Mark Wallace
sumber
25
jika Anda terus terbakar dengan mencoba mengambil ini dari tempat yang berbeda (seperti saya), Anda dapat melakukannyarequire('root-require')('package.json').version
mikermcneil
5
Tidak berfungsi untuk skrip saya dengan shebang diinstal secara global. Error: Cannot find module 'package.json'.
exebook
14
lebih pendek - membutuhkan ('./ paket') versi
Afanasii Kurakin
60
Peringatan! Melakukan hal ini dengan browserify memiliki implikasi keamanan: package.json dalam bundel Anda berarti bahwa semua nomor versi ketergantungan Anda, membangun dan menguji perintah dan banyak lagi yang dikirim ke klien. Jika Anda membangun server dan klien dalam proyek yang sama, Anda juga mengekspos nomor versi sisi server Anda.
Patogen
4
Genogenion @Pathogen memecahkan masalah di sisi klien. Ini adalah alat yang membaca versi dari package.json dan menghasilkan modul yang dapat diimpor dari itu. Penafian: Saya seorang pengelola.
Akseli Palén
349

Jika aplikasi Anda diluncurkan dengan 'npm start', Anda cukup menggunakan:

process.env.npm_package_version

Lihat package.json vars untuk lebih jelasnya.

Julien Christin
sumber
6
ini mungkin jawaban terbaik karena sebagian besar informasi dalam package.json dilampirkan ke variabel proses runtime
Alexander Mills
2
Ya, saya setuju. Ini seharusnya jawaban yang benar, menggunakan variabel proses yang tidak perlu Anda buka dan baca lagi file package.json.
Juanma 3-15
12
Dan di luar node (misalnya, skrip shell dieksekusi melalui npm run …) versi akan berada dalam variabel lingkungan $npm_package_version.
Quinn Comendant
12
Ketika dipanggil dari skrip paket lain, ini salah melaporkan versi paket panggilan dan bukan paket yang dipanggil .
jjrv
6
Ini berfungsi di dalam aplikasi elektron yang dimulai dengan npm start, tetapi tidak di dalam aplikasi elektron yang dibangun: untuk itu, Anda dapat menemukannya di app.getVersion.
ChrisV
158

Menggunakan modul ES6 Anda dapat melakukan hal berikut:

import {version} from './package.json';
Patrick Lee Scott
sumber
2
Saya pikir ini tidak didukung dalam simpul: github.com/nodejs/help/issues/53
ripper234
1
Tidak ada modul ES6 yang belum didukung secara langsung tetapi tetap digunakan, diaktifkan menggunakan Babel
Patrick Lee Scott
4
@Sornii no, seluruh package.json akan berada di klien. Saya menggunakan definePlugin webpack untuk meneruskan hanya info yang dipilih dari lingkungan node ke browser.
doeke
2
Adakah implikasi keamanan seperti yang ditentukan dalam stackoverflow.com/a/10855054/540144 ?
itsazzad
1
Ya, masalah keamanan yang sama. Seluruh package.json akan disertakan dalam bundel klien.
Neromancer
95

Atau di shell tua polos:

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

Ini dapat disingkat menjadi

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

Meskipun ini bukan pertanyaan yang diajukan, ada baiknya jika Anda ingin menggunakan versi package.jsonitu sendiri, misalnya untuk masuk ke file versi di 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",
  ...
}
lebih baik
sumber
Itu tidak ada dalam aplikasi nodeJS itu sendiri, seperti yang diminta.
Steve Bennett
1
@SteveBennett Tidak, tapi itu membantu 90 orang plus saya.
K - Keracunan dalam SO tumbuh.
1
Mungkin lebih dari itu.
Steve Bennett
61

Ada dua cara untuk mengambil versi:

  1. Membutuhkan package.jsondan mendapatkan versi:
const { version } = require('./package.json');
  1. Menggunakan variabel lingkungan:
const version = process.env.npm_package_version;

Jangan gunakan JSON.parse, fs.readFile, fs.readFileSyncdan jangan gunakan lagi npm modulesitu tidak perlu untuk pertanyaan ini.

aflex dykyі
sumber
2
Terima kasih atas cuplikan kode ini, yang mungkin memberikan bantuan terbatas dan segera. Sebuah penjelasan yang tepat akan sangat meningkatkan nilai jangka panjang dengan menunjukkan mengapa ini adalah solusi yang baik untuk masalah ini, dan akan membuatnya lebih bermanfaat untuk pembaca masa depan dengan lainnya, pertanyaan-pertanyaan serupa. Harap edit jawaban Anda untuk menambahkan beberapa penjelasan, termasuk asumsi yang Anda buat.
milo526
8
Maka npm_*nilai lingkungan hanya tersedia jika skrip Anda dimulai oleh NPM, mis npm start. Jika Anda melakukan node app.jsatau serupa, mereka tidak akan hadir.
Nate
@Nate Jadi lebih baik menggunakan versi dari package.json?
Filip Š
38

Berikut ini cara membaca versi out dari package.json:

fs = require('fs')
json = JSON.parse(fs.readFileSync('package.json', 'utf8'))
version = json.version
Evan Moran
sumber
Saya telah melihat banyak ini, dan saya menyukainya - apakah Anda / siapa pun tahu pertimbangan yang require() introduces? (for instance, does mengharuskan () `tidak mendukung bacaan utf8? seperti yang mungkin disarankan cuplikan Anda)
electblake
4
require()cache file, yang dalam hal ini seharusnya tidak membuat perbedaan.
jlee
@ jlee apakah ada alasan yang biasanya dilakukan orang JSON.parse(fs.readFileSync('package.json', 'utf8'))alih - alih delete require.cache[require.resolve('package.json')]; require('package.json')ketika mereka ingin memuat ulang?
Mihail Malostanidis
const {version} = membutuhkan ('./ package.json');
Axx dyky
23

Ada cara lain untuk mengambil informasi tertentu dari package.jsonfile Anda yaitu menggunakan modul pkginfo .

Penggunaan modul ini sangat sederhana. Anda bisa mendapatkan semua variabel paket menggunakan:

require('pkginfo')(module);

Atau hanya detail tertentu ( versiondalam hal ini)

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

Dan variabel paket Anda akan diatur ke module.exports(sehingga nomor versi akan dapat diakses melalui module.exports.version).

Anda dapat menggunakan potongan kode berikut:

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

Modul ini memiliki fitur yang sangat bagus - dapat digunakan dalam file apa pun di proyek Anda (misalnya dalam subfolder) dan secara otomatis akan mengambil informasi dari Anda package.json. Jadi Anda tidak perlu khawatir di mana Anda package.jsonberada.

Saya harap itu akan membantu.

Tom
sumber
1
ada apa moduledisini
chovy
@ chovy, modulebukan variabel contoh spesifik ini; itu adalah variabel yang mewakili modul saat ini di node.js. Anda dapat membaca lebih lanjut tentang modul node.js di sini: nodejs.org/api/modules.html#modules_the_module_object
Tom
2
Saya mencoba mendapatkan versi modul lain yang diperlukan oleh modul saya ... dan saya mengalami kesulitan mencari tahu apakah pkginfo memungkinkan ini terjadi.
Michael
23

Bagi mereka yang mencari solusi sisi-klien yang aman yang juga berfungsi di sisi-server, ada genversi . Ini adalah alat baris perintah yang membaca versi dari package.json terdekat dan menghasilkan file modul CommonJS yang dapat diimpor yang mengekspor versi. Penafian: Saya seorang pengelola.

$ genversion lib/version.js

Saya mengakui keselamatan sisi klien bukan tujuan utama OP, tetapi seperti yang dibahas dalam jawaban oleh Mark Wallace dan Agustus , itu sangat relevan dan juga alasan saya menemukan T&J ini.

Akseli Palén
sumber
4
Ini adalah jawaban, dan butuh lebih banyak suara untuk mendapatkan jawaban yang sangat bermasalah di atas sekarang.
Jeff Allen
1
Beberapa orang mungkin khawatir dengan kenyataan bahwa ini adalah alat baris perintah. Jangan khawatir! Readme alat ini menjelaskan cara (dengan mudah) mengintegrasikan panggilan pada build ke package.json, sehingga Anda bisa melupakan keberadaan alat dan selalu memiliki nomor versi terbaru.
malamut
11

Hanya menambahkan jawaban karena saya datang ke pertanyaan ini untuk melihat cara terbaik untuk memasukkan versi dari package.json dalam aplikasi web saya.

Saya tahu pertanyaan ini ditujukan untuk Node.js, namun, jika Anda menggunakan Webpack untuk menggabungkan aplikasi Anda hanya pengingat cara yang disarankan adalah dengan menggunakan DefinePlugin untuk mendeklarasikan versi global dalam konfigurasi dan referensi itu. Jadi Anda bisa melakukannya diwebpack.config.json

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

...

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

Dan AppVersionsekarang ada global yang tersedia untuk Anda gunakan. Pastikan juga .eslintrcAnda mengabaikannya melalui global prop

agustus
sumber
8

Pilihan 1

Praktik terbaik adalah versi dari package.json menggunakan variabel lingkungan npm.

process.env.npm_package_version

informasi lebih lanjut tentang: https://docs.npmjs.com/using-npm/config.html

Ini akan berfungsi hanya ketika Anda memulai layanan Anda menggunakan perintah NPM.

Info Cepat: Anda dapat membaca nilai apa pun di pacakge.json menggunakan process.env.npm_package_ [keyname]

pilihan 2

Mengatur versi dalam variabel lingkungan menggunakan https://www.npmjs.com/package/dotenv sebagai .envfile dan mengikutinya dalamprocess.env.version

Aravin
sumber
7

Anda dapat menggunakan ES6 untuk mengimpor package.json untuk mengambil nomor versi dan mengeluarkan versi pada konsol.

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

console.log(`App ---- ${app_name}\nVersion ---- ${app_version}`);
ÁngelBlanco
sumber
3
Ini berfungsi selama Anda mengatur "resolJsonModule" menjadi "true" di tsconfig.json.
Russell Phillips
6

Untuk menentukan versi paket dalam kode simpul, Anda dapat menggunakan yang berikut ini:

  1. const version = require('./package.json').version; untuk versi <ES6

  2. import {version} from './package.json'; untuk versi ES6

  3. const version = process.env.npm_package_version; jika aplikasi telah mulai digunakan npm start, semua variabel lingkungan npm_ * menjadi tersedia.

  4. Anda dapat menggunakan paket npm berikut juga - root-need, pkginfo, versi proyek.

Rohit Jaiswal
sumber
4

Anda dapat menggunakan paket versi proyek .

$ npm install --save project-version

Kemudian

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

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

Ia menggunakan process.env.npm_package_versiontetapi mundur pada versi yang ditulis package.jsondalam jika env var hilang karena beberapa alasan.

simonepri
sumber
Misalnya jika file js dimulai bukan dari npm?
Mihail Malostanidis
2

Mengapa tidak menggunakan yang memerlukan tekad ...

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

Dengan pendekatan ini bekerja untuk semua sub jalur :)

Gianluca Cirone
sumber
1

Saya melakukan ini dengan findup-sync:

var findup = require('findup-sync');
var packagejson = require(findup('package.json'));
console.log(packagejson.version); // => '0.0.1' 
Luca Bonavita
sumber
findup dimulai dengan cwd, jadi dalam kebanyakan kasus hanya akan mendapatkan level atas package.json, mirip dengan process.env.npm_package_versionselain tidak memerlukannya untuk dimulai melalui npm. Jadi mencoba mendapatkan versi perpustakaan Anda sebenarnya akan mendapatkan versi pemanggil. Persyaratan sederhana ('./ package.json') akan menghindari ini.
Mihail Malostanidis
1

Saya tahu ini bukan maksud OP, tapi saya hanya harus melakukan ini, jadi harap itu membantu orang berikutnya.

Jika Anda menggunakan docker-compose untuk proses CI / CD Anda, Anda bisa mendapatkannya dengan cara ini!

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', '')\""

untuk gambar, Anda dapat menggunakan gambar simpul apa pun. Saya menggunakan alpine karena itu adalah yang terkecil.

Patrick Lee Scott
sumber
0

Impor Anda package.jsonfile ke Anda server.jsatau app.jsdan kemudian akses properti package.json ke dalam file server yang.

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

variabel paket berisi semua data di package.json.

Patharraj
sumber
0

Saya membuat kode yang berguna untuk mendapatkan package.json modul induk

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
sumber
0

Jika menggunakan rollup, rollup-plugin-replaceplugin dapat digunakan untuk menambahkan versi tanpa mengekspos package.json ke klien.

// 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
    }),
  ]
};

Kemudian, dalam kode sumber, di mana pun Anda ingin memiliki versi package.json, Anda akan menggunakan string 'MY_PACKAGE_JSON_VERSION'.

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