Есть ли способ получить версию из 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:

Выполнение этого с Browserify имеет последствия для безопасности.
Будьте осторожны, чтобы не показывать свою package.jsonинформацию клиенту, поскольку это означает, что все номера версий зависимостей, команды построения и тестирования и многое другое отправляются клиенту.
Если вы строите сервер и клиент в одном проекте, вы также предоставляете номера версий на стороне сервера. Такие специфические данные могут быть использованы злоумышленником для лучшего соответствия атаке на вашем сервере.

Марк Уоллес
источник
25
если вы продолжаете обжигаться, пытаясь захватить это из разных мест (как я), вы можете это сделатьrequire('root-require')('package.json').version
mikermcneil
5
Не работает для моего сценария с установленным глобально. Error: Cannot find module 'package.json',
exebook
14
короче - требуется ('./ package'). версия
Афанасий Куракин
60
Предупреждение! Выполнение этого с browserify имеет последствия для безопасности: package.json в вашем комплекте означает, что все ваши номера версий зависимостей, команды сборки и тестирования и многое другое отправляются клиенту. Если вы строите сервер и клиент в одном проекте, вы также предоставляете номера версий своих серверов.
Патоген
4
@Pathogen genversion решает проблему на стороне клиента. Это инструмент, который читает версию из package.json и генерирует из нее импортируемый модуль. Отказ от ответственности: я сопровождающий.
Аксели Пален,
349

Если ваше приложение запускается с «npm start», вы можете просто использовать:

process.env.npm_package_version

Смотрите package.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
Патрик Ли Скотт
4
@ Sornii нет, весь package.json будет в клиенте. Я использовал definePlugin webpack для передачи только выбранной информации из среды узла в браузер.
Doeke
2
Любые последствия для безопасности, как указано в stackoverflow.com/a/10855054/540144 ?
itazzad
1
Да, те же проблемы безопасности. Весь package.json будет включен в клиентский пакет.
Неромант
95

Или в простой старой оболочке:

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",
  ...
}
abernier
источник
Это не в самом приложении 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
@Nate Так что лучше использовать версию с package.json?
Филип Ш
38

Вот как читать версию из package.json:

fs = require('fs')
json = JSON.parse(fs.readFileSync('package.json', 'utf8'))
version = json.version
Эван Моран
источник
Я видел эту кучу, и мне это нравится - знаете ли вы / кто-нибудь соображения, которые require() introduces? (for instance, does требуют () `не поддерживает чтение utf8? как подсказывает ваш фрагмент
кода
4
require()кэширует файл, который в этом случае не должен иметь значения.
1914 года
@jlee есть ли причина, по которой люди обычно делают это JSON.parse(fs.readFileSync('package.json', 'utf8'))вместо того, delete require.cache[require.resolve('package.json')]; require('package.json')когда хотят перезагрузить компьютер?
Михаил Малостанидис
const {version} = require ('./ package.json');
Алекс Дикіі
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, moduleэто не конкретный пример переменной; это переменная, представляющая текущий модуль в node.js. Вы можете прочитать больше о модулях node.js здесь: nodejs.org/api/modules.html#modules_the_module_object
Том
2
Я пытаюсь получить версию других модулей, необходимую для моего модуля ... и мне трудно понять, делает ли это возможным pkginfo.
Майкл,
23

Для тех, кто ищет безопасное решение на стороне клиента, которое также работает на стороне сервера, есть genversion . Это инструмент командной строки, который читает версию из ближайшего package.json и генерирует импортируемый файл модуля CommonJS, который экспортирует версию. Отказ от ответственности: я сопровождающий.

$ genversion lib/version.js

Я признаю, что безопасность на стороне клиента не была основной целью OP, но, как обсуждалось в ответах Марка Уоллеса и Ауга , это очень важно, а также причина, по которой я нашел этот вопрос и ответ .

Аксели Пален
источник
4
Это ответ, и ему нужно больше голосов, чтобы подняться над проблемным ответом сверху прямо сейчас.
Джефф Аллен
1
Некоторые люди могут быть встревожены тем фактом, что это инструмент командной строки. Не волнуйтесь! В readme инструмента описано, как (легко) интегрировать вызов build в 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

Рекомендуется использовать версию из package.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 для импорта package.json для получения номера версии и вывода версии на консоль.

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

console.log(`App ---- ${app_name}\nVersion ---- ${app_version}`);
ÁngelBlanco
источник
3
Это работает до тех пор, пока вы установите для «resolJsonModule» значение «true» в файле tsconfig.json.
Рассел Филлипс
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, project-version.

Рохит Джайсвал
источник
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 по какой-то причине отсутствует.

simonepri
источник
Например, если файл js был запущен не из npm?
Михаил Малостанидис
2

Почему бы не использовать требуемое разрешение ...

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

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

Джанлука Сироне
источник
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

Я знаю, что это не цель ОП, но я просто должен был сделать это, поэтому надеюсь, что это поможет следующему человеку.

Если вы используете docker-compose для процесса 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', '')\""

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

Патрик Ли Скотт
источник
0

Импорт package.jsonфайла в server.jsили app.jsи затем package.json доступ к свойствам в файл сервера.

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

Переменная package содержит все данные в package.json.

Patharraj
источник
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
}
g00dnatur3
источник
0

Если используется накопительный пакет, rollup-plugin-replaceплагин можно использовать для добавления версии без предоставления package.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
spwisner
источник