Чи є спосіб отримати версію з пакета package.json у коді nodejs?


586

Чи є спосіб встановити версію, встановлену в package.jsonдодатку nodejs? Я хотів би щось подібне

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

Чи важливіше отримати версію Node або версію, оголошену в package.json? Якщо форма, це дасть вам запущену версію:console.log(process.version)
Адріан Лінч

Відповіді:


957

Я виявив, що наступний фрагмент коду найкраще працює для мене. Оскільки він використовується requireдля завантаження package.json, він працює незалежно від поточного робочого каталогу.

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

Попередження, ввічливість @Pathogen:

Якщо це зробити за допомогою Browrify, це може мати наслідки для безпеки.
Будьте обережні, щоб не виставляти package.jsonклієнту свою програму, оскільки це означає, що всі ваші номери версій залежності, команди побудови та тестування та інше надсилаються клієнту.
Якщо ви будуєте сервер і клієнта в одному проекті, ви також виставляєте номери версій на стороні сервера. Такі конкретні дані зловмисник може використовувати для кращого пристосування атаки на вашому сервері.


25
якщо ви продовжуєте горіти, намагаючись схопити це з різних місць (як я), ви можете зробитиrequire('root-require')('package.json').version
mikermcneil

5
Не працює над моїм сценарієм із встановленим в усьому світі шебангом. Error: Cannot find module 'package.json'.
exebook

14
коротше - вимагають ('./ пакет'). версія
Афанасій Куракін

60
Увага! Якщо це зробити за допомогою браузера, це має наслідки для безпеки: package.json у вашому пакеті означає, що всі ваші номери версій залежності, команди збірки та тестування та інше надсилаються клієнту. Якщо ви будуєте сервер і клієнта в одному проекті, ви також виставляєте номери версій на сервері.
Збудник

4
@Pathogen genversion вирішує проблему на стороні клієнта. Це інструмент, який читає версію з package.json і генерує з неї імпортний модуль. Відмова: Я обслуговуючий персонал.
Акселі Пален

348

Якщо ваша програма запускається з 'npm start', ви можете просто скористатися:

process.env.npm_package_version

Докладніші відомості див . У пакет.json vars .


6
це, мабуть, найкраща відповідь, оскільки більша частина інформації в package.json додається до змінної часу виконання процесу
Олександр Міллз

2
Так, я згоден. Це має бути правильна відповідь, використовуючи змінну процесу, вам не потрібно відкривати та читати ще раз файл package.json.
Хуанма

12
А за межами вузла (наприклад, скриптів оболонки, виконаних через npm run …), версія буде в змінній оточення $npm_package_version.
Квінн Комендант

12
При виклику зі скриптів іншого пакету це невірно повідомляє версію викликового пакета, а не пакет, що викликається .
jjrv

6
Він працює в електронному додатку, розпочатому з npm start, але не вбудованому додатку для електронів: для цього його можна знайти app.getVersion.
ChrisV

158

За допомогою модулів ES6 ви можете зробити наступне:

import {version} from './package.json';

2
Я думав, що вони не підтримуються у вузлі: github.com/nodejs/help/issues/53
ripper234

1
Жоден модуль es6 ще не підтримується безпосередньо, але все-таки зазвичай використовується, увімкнено за допомогою Babel
Patrick Lee Scott

4
@Sornii ні, весь package.json буде у клієнта. Я використовував definePlugin webpack для передачі лише вибраної інформації з середовища вузла до браузера.
doeke

2
Будь-які наслідки щодо безпеки, як зазначено в stackoverflow.com/a/10855054/540144 ?
itsazzad

1
Так, ті ж самі питання безпеки. Весь package.json буде включений у клієнтський пакет.
Нероманс

94

Або в звичайній старій оболонці:

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

Це можна скоротити до

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

Незважаючи на те, що це не зовсім те, що задається питанням, корисно, якщо ви хочете використовувати версію всередині package.jsonсебе, наприклад, для входу у версійний файл у 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",
  ...
}

Це не в самому додатку nodeJS, як вимагається.
Стів Беннетт

1
@SteveBennett Ні, але це допомогло 90 людям плюс мені.
Карл Моррісон

1
Напевно, набагато більше, ніж це.
Стів Беннетт

61

Існує два способи отримання версії:

  1. Потрібна package.jsonверсія та отримання її версії:
const { version } = require('./package.json');
  1. Використання змінних середовища:
const version = process.env.npm_package_version;

Будь ласка , не використовуйте JSON.parse, fs.readFile, fs.readFileSyncі не використовуйте інше npm modulesце не потрібно для цього питання.


2
Дякуємо за цей фрагмент коду, який може надати деяку обмежену, негайну допомогу. Належне пояснення було б значно поліпшити свою довгострокову цінність , показуючи , чому це хороше рішення проблеми, і зробить його більш корисним для читачів майбутніх з іншими подібними питаннями. Будь ласка , змініть свій відповідь , щоб додати деякі пояснення, в тому числі припущень , які ви зробили.
milo526

8
Тоді npm_*значення середовища доступні лише в тому випадку, якщо ваш скрипт був запущений NPM, наприклад npm start. Якщо ви робите node app.jsчи подібні, вони не будуть присутні.
Нейт

@Nate Отже, краще використовувати версію з package.json?
Філіп Ш

37

Ось як прочитати версію з пакета package.json:

fs = require('fs')
json = JSON.parse(fs.readFileSync('package.json', 'utf8'))
version = json.version

Я бачив цю купу, і мені це подобається - чи ви / хтось знаєте міркування, які require() introduces? (for instance, does вимагають () `не підтримувати читання utf8? як може запропонувати ваш фрагмент)
electblake

4
require()кешує файл, що в цьому випадку не повинно змінити значення.
jlee

@jlee Чи є причина, яку люди зазвичай роблять JSON.parse(fs.readFileSync('package.json', 'utf8'))замість того, delete require.cache[require.resolve('package.json')]; require('package.json')коли вони хочуть перезавантажуватись?
Михайло Малостанідіс

const {версія} = вимагати ('./ package.json');
alex dykyі

23

Існує ще один спосіб отримання певної інформації від вашого package.json файлу, а саме за допомогою модуля pkginfo .

Використання цього модуля дуже просте. Ви можете отримати всі змінні пакета, використовуючи:

require('pkginfo')(module);

Або лише певні деталі (version в даному випадку)

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

І змінні вашого пакета будуть встановлені на module.exports (тому номер версії буде доступний черезmodule.exports.version ).

Ви можете використовувати такий фрагмент коду:

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

Цей модуль має дуже гарну функцію - його можна використовувати у будь-якому файлі вашого проекту (наприклад, у підпапках), і він автоматично отримуватиме інформацію з вашого package.json . Тож не потрібно хвилюватися, де ти package.jsonє.

Я сподіваюся, що це допоможе.


1
що moduleтут?
chovy

@chovy, moduleце не конкретна прикладна змінна; це змінна, що представляє поточний модуль в node.js. Більше про модулі node.js ви можете прочитати тут: nodejs.org/api/modules.html#modules_the_module_object
Tom

2
Я намагаюся отримати версію інших модулів, необхідна моєму модулю ... і мені важко з'ясувати, чи pkginfo робить це можливим.
Майкл

23

Для тих, хто шукає безпечне рішення на стороні клієнта, яке також працює на сервері, існує генверсія . Це інструмент командного рядка, який зчитує версію з найближчого пакета.json та генерує файл, що імпортує модуль CommonJS, який експортує версію. Відмова: Я обслуговуючий персонал.

$ genversion lib/version.js

Я усвідомлюю, що безпека на стороні клієнта не була основною метою ОП, але, як обговорювали у відповідях Марк Уоллес та Ауг , це дуже актуально, а також причина, коли я знайшов це питання та відповіді.


4
Це відповідь, і для цього потрібно більше голосів, щоб вийти над глибоко проблемною відповіддю вгорі.
Джефф Аллен

1
Деяких людей може насторожити той факт, що це інструмент командного рядка. Не хвилюйся! Редміс інструмента описує, як (легко) інтегрувати виклик при складанні в package.json, щоб ви могли забути про існування інструменту і завжди матимете останній номер версії.
маламут

11

Просто додаю відповідь, тому що я прийшов до цього питання, щоб побачити найкращий спосіб включити версію від package.json у свій веб-додаток.

Я знаю, що це питання орієнтовано на Node.js, однак, якщо ви використовуєте Webpack для з’єднання свого додатка лише нагадування, рекомендованим способом є використання DefinePlugin для оголошення глобальної версії в конфігурації та посилання на це. Так ви могли зробити у своємуwebpack.config.json

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

...

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

А AppVersionтепер є глобальним, який доступний для використання. Також переконайтеся, що .eslintrcви ігноруєте це за допомогою глобальної опори


8

Варіант 1

Найкраща практика - це версія з пакету.json з використанням змінних середовища npm.

process.env.npm_package_version

докладнішу інформацію про: https://docs.npmjs.com/using-npm/config.html

Це буде працювати лише тоді, коли ви запускаєте службу за допомогою команди NPM.

Коротка інформація: ви можете прочитати будь-які значення в pacakge.json, використовуючи process.env.npm_package_ [keyname]

Варіант 2

Встановлення версії в змінній середовища, використовуючи https://www.npmjs.com/package/dotenv як .envфайл та відносно нього вprocess.env.version


7

Ви можете використовувати ES6 для імпорту пакета.json, щоб отримати номер версії та вивести версію на консоль.

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

console.log(`App ---- ${app_name}\nVersion ---- ${app_version}`);

3
Це працює до тих пір, як у tsconfig.json ви встановите на "true" значення "trueJsonModule" на "true".
Рассел Філліпс

6

Щоб визначити версію пакета в коді вузла, ви можете скористатися наступним:

  1. const version = require('./package.json').version; для версій <ES6

  2. import {version} from './package.json'; для версії ES6

  3. const version = process.env.npm_package_version; якщо програма була запущена npm start, всі змінні середовища npm_ * стають доступними.

  4. Ви також можете використовувати наступні пакети npm - root-Require, pkginfo, проект-версія.


4

Ви можете скористатися пакетом проекту-версії .

$ npm install --save project-version

Тоді

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

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

Він використовує, process.env.npm_package_versionале резервну версію, написану package.jsonв, якщо env var з якоїсь причини відсутній.


Наприклад, якщо файл js запускався не з npm?
Михайло Малостанідіс

1

Я роблю це з findup-sync:

var findup = require('findup-sync');
var packagejson = require(findup('package.json'));
console.log(packagejson.version); // => '0.0.1' 

findup починається з cwd, тому в більшості випадків він просто отримує верхній рівень package.json, подібний тому, що process.env.npm_package_versionне вимагає запуску через npm. Тому спроба отримати вашу бібліотечну версію фактично отримає версію абонента. Проста вимога ('./ package.json') цього уникне.
Михайло Малостанідіс

1

Я знаю, що це не мета ОП, але я просто повинен був це зробити, тому сподіваюся, що це допоможе наступній людині.

Якщо ви використовуєте докер-композицію для процесу CI / CD, ви можете отримати це таким чином!

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

для зображення можна використовувати будь-яке зображення вузла. Я використовую альпійську, тому що вона найменша.


1

Чому б не скористатись функцією вирішення вимог ...

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

При такому підході працюйте для всіх піддоріжок :)


0

Імпортуйте package.jsonфайл у свій server.jsабо, app.jsа потім отримайте доступ до властивостей package.json у файл сервера.

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

змінна пакунок містить усі дані в package.json.


0

Я зробив корисний код, щоб отримати батьківський модуль package.json

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
}

0

Якщо використовується зсув, то rollup-plugin-replaceплагін можна використовувати для додавання версії, не піддаючи пакет.json клієнтові.

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

Тоді у вихідному коді, де б ви не мали версії package.json, ви б використовували рядок "MY_PACKAGE_JSON_VERSION".

// src/index.js
export const packageVersion = 'MY_PACKAGE_JSON_VERSION' // replaced with actual version number in rollup.config.js
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.