Existe uma maneira de obter a versão do package.json no código nodejs?

586

Existe uma maneira de obter a versão definida package.jsonem um aplicativo nodejs? Eu gostaria de algo assim

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
fonte
É mais importante obter a versão do Node ou a versão declarada no package.json? Se o formulário, isso lhe dará a versão em execução:console.log(process.version)
Adrian Lynch

Respostas:

957

Eu descobri que o seguinte fragmento de código funcionou melhor para mim. Como ele usa requirepara carregar o package.json, ele funciona independentemente do diretório de trabalho atual.

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

Um aviso, cortesia de @Pathogen:

Fazer isso com o Browserify tem implicações de segurança.
Cuidado para não expor o seu package.jsonao cliente, pois isso significa que todos os números de versão da sua dependência, comandos de compilação e teste e muito mais são enviados ao cliente.
Se você estiver criando servidor e cliente no mesmo projeto, também expõe seus números de versão do servidor. Esses dados específicos podem ser usados ​​por um invasor para melhor se adequar ao ataque ao seu servidor.

Mark Wallace
fonte
25
se você continuar se queimar ao tentar agarrar esta de diferentes lugares (como eu estava), você pode fazerrequire('root-require')('package.json').version
mikermcneil
5
Não está funcionando para o meu script com o shebang instalado globalmente. Error: Cannot find module 'package.json'.
exebook
14
mais curto - exigir ('./ pacote'). versão
Afanasii Kurakin
60
Atenção! Fazer isso com o browserify tem implicações de segurança: package.json no seu pacote significa que todos os seus números de versão de dependência, comandos de construção e teste e muito mais são enviados ao cliente. Se você estiver criando servidor e cliente no mesmo projeto, também expõe os números de versão do servidor.
Pathogen
4
A genversion do @Pathogen resolve o problema no lado do cliente. É uma ferramenta que lê a versão do package.json e gera um módulo importável a partir dela. Disclaimer: Eu sou um mantenedor.
Akseli Palén
349

Se seu aplicativo for iniciado com 'npm start', você pode simplesmente usar:

process.env.npm_package_version

Veja package.json vars para mais detalhes.

Julien Christin
fonte
6
esta é provavelmente a melhor resposta já que a maioria das informações em package.json está ligado à variável de processo de execução
Alexander Mills
2
Sim, eu concordo. Essa deve ser a resposta certa, usando a variável de processo que você não precisa abrir e ler novamente o arquivo package.json.
Juanma
12
E fora do nó (por exemplo, scripts de shell executados via npm run …) a versão estará na variável de ambiente $npm_package_version.
Quinn Comendant
12
Quando chamado de scripts de outro pacote, isso informa incorretamente a versão do pacote de chamada e não o pacote chamado .
jjrv
6
Ele funciona em um aplicativo de elétrons iniciado com npm start, mas não em um aplicativo de elétrons incorporado: para isso, você pode encontrá-lo app.getVersion.
ChrisV
158

Usando os módulos ES6, você pode fazer o seguinte:

import {version} from './package.json';
Patrick Lee Scott
fonte
2
Eu pensei que estes não foram apoiadas no nó: github.com/nodejs/help/issues/53
ripper234
1
Nenhum módulo ES6 ainda não são suportados diretamente, mas comumente usado de qualquer maneira, ativado por Babel
Patrick Lee Scott
4
@Sornii não, todo o package.json estará no cliente. Usei o definePlugin do webpack para passar apenas as informações selecionadas do ambiente do nó para o navegador.
Doeke 13/10
2
Alguma implicação de segurança como a especificada em stackoverflow.com/a/10855054/540144 ?
itsazzad
1
Sim, os mesmos problemas de segurança. Todo o package.json será incluído no pacote do cliente.
Neromancer
95

Ou em concha velha lisa:

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

Isso pode ser reduzido para

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

Mesmo que essa não seja exatamente a pergunta, é útil se você quiser usar a versão em package.jsonsi mesma, por exemplo, para fazer logon em um arquivo com versão em 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
fonte
Isso não está no próprio aplicativo nodeJS, conforme solicitado.
21416 Steve Bennett
1
@SteveBennett Não, mas ajudou 90 pessoas além de mim.
K - A toxicidade no SO está crescendo.
1
Provavelmente muito mais que isso.
Steve Bennett
61

Existem duas maneiras de recuperar a versão:

  1. Exigindo package.jsone obtendo a versão:
const { version } = require('./package.json');
  1. Usando as variáveis ​​de ambiente:
const version = process.env.npm_package_version;

Por favor, não use JSON.parse, fs.readFile, fs.readFileSynce não use outra npm modulesque não é necessário para esta pergunta.

Alex Dykyі
fonte
2
Obrigado por este trecho de código, que pode fornecer ajuda imediata e limitada. Uma explicação adequada melhoraria bastante seu valor a longo prazo , mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras perguntas semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
milo526
8
Os npm_*valores do ambiente estarão disponíveis apenas se o seu script tiver sido iniciado pelo NPM, por exemplo npm start. Se você estiver fazendo node app.jsou algo parecido, eles não estarão presentes.
Nate
@ Nate Por isso, é melhor usar a versão package.json?
precisa
38

Aqui está como ler a versão do package.json:

fs = require('fs')
json = JSON.parse(fs.readFileSync('package.json', 'utf8'))
version = json.version
Evan Moran
fonte
Eu já vi isso muito, e eu gosto - você / alguém conhece as considerações que require() introduces? (for instance, does requerem () `não suportam a leitura utf8? como seu snippet pode sugerir)
electblake
4
require()armazena em cache o arquivo, o que, neste caso, não deve fazer diferença.
perfil completo de Jlee
@lee há uma razão que as pessoas costumam fazer em JSON.parse(fs.readFileSync('package.json', 'utf8'))vez de delete require.cache[require.resolve('package.json')]; require('package.json')quando querem recarregar?
Mihail Malostanidis
const {version} = require ('./ package.json');
dykyі аlex
23

Existe outra maneira de buscar certas informações do seu package.jsonarquivo, usando o módulo pkginfo .

O uso deste módulo é muito simples. Você pode obter todas as variáveis ​​de pacote usando:

require('pkginfo')(module);

Ou apenas alguns detalhes ( versionneste caso)

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

E suas variáveis ​​de pacote serão definidas como module.exports(para que o número da versão seja acessível viamodule.exports.version ).

Você pode usar o seguinte trecho de código:

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

Este módulo possui um recurso muito interessante - ele pode ser usado em qualquer arquivo do seu projeto (por exemplo, em subpastas) e buscará automaticamente as informações do seu projeto. package.json . Então você não precisa se preocupar onde package.jsonestá.

Espero que ajude.

Tom
fonte
1
o que tem moduleaqui?
Chovy
@chovy, modulenão é essa variável de exemplo específica; é uma variável que representa o módulo atual em node.js. Você pode ler mais sobre os módulos node.js. aqui: nodejs.org/api/modules.html#modules_the_module_object
Tom
2
Estou tentando obter a versão de outros módulos exigidos pelo meu módulo ... e estou tendo dificuldades para descobrir se o pkginfo torna isso possível.
Michael
23

Para aqueles que procuram uma solução segura do lado do cliente que também funcione no lado do servidor, existe uma genversão . É uma ferramenta de linha de comando que lê a versão do package.json mais próximo e gera um arquivo de módulo CommonJS importável que exporta a versão. Disclaimer: Eu sou um mantenedor.

$ genversion lib/version.js

Reconheço que a segurança do cliente não era a intenção principal do OP, mas, como discutido nas respostas de Mark Wallace e agosto , é altamente relevante e também o motivo pelo qual encontrei essas perguntas e respostas.

Akseli Palén
fonte
4
Esta é a resposta e precisa de mais votos para superar a resposta profundamente problemática no topo agora.
Jeff Allen
1
Algumas pessoas podem ficar alarmadas pelo fato de ser uma ferramenta de linha de comando. Não se preocupe! O leia-me da ferramenta descreve como (facilmente) integrar a chamada no build no package.json, para que você possa esquecer a existência da ferramenta e sempre terá o número da versão mais recente.
malamut
11

Apenas adicionando uma resposta porque cheguei a esta pergunta para ver a melhor maneira de incluir a versão do package.json no meu aplicativo da web.

Sei que esta pergunta é direcionada para o Node.js, no entanto, se você estiver usando o Webpack para agrupar seu aplicativo, apenas um lembrete, a maneira recomendada é usar o DefinePlugin para declarar uma versão global na configuração e fazer referência a isso. Então você poderia fazer no seuwebpack.config.json

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

...

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

E AppVersionagora é um global que está disponível para você usar. Também certifique-se de que .eslintrcvocê ignora isso através do suporte global

agosto
fonte
8

Opção 1

A melhor prática é fazer a versão do package.json usando variáveis ​​de ambiente npm.

process.env.npm_package_version

mais informações em: https://docs.npmjs.com/using-npm/config.html

Isso funcionará apenas quando você iniciar o serviço usando o comando NPM.

Informações rápidas: você pode ler quaisquer valores no pacakge.json usando process.env.npm_package_ [keyname]

opção 2

Configurando a versão na variável de ambiente usando https://www.npmjs.com/package/dotenv como .envarquivo e em relação aprocess.env.version

Aravin
fonte
7

Você pode usar o ES6 para importar o package.json para recuperar o número da versão e gerar a versão no console.

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

console.log(`App ---- ${app_name}\nVersion ---- ${app_version}`);
ÁngelBlanco
fonte
3
Isso funciona desde que você configure "resolveJsonModule" para "true" no tsconfig.json.
Russell Phillips
6

Para determinar a versão do pacote no código do nó, você pode usar o seguinte:

  1. const version = require('./package.json').version; para <versões ES6

  2. import {version} from './package.json'; para versão ES6

  3. const version = process.env.npm_package_version; se o aplicativo foi iniciado npm start, todas as variáveis ​​de ambiente npm_ * ficam disponíveis.

  4. Você também pode usar os seguintes pacotes npm - root-require, pkginfo, project-version.

Rohit Jaiswal
fonte
4

Você pode usar o pacote de versão do projeto .

$ npm install --save project-version

Então

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

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

Ele usa process.env.npm_package_versionmas fallback na versão escrita package.jsonno caso do env var estar ausente por algum motivo.

simonepri
fonte
Por exemplo, se o arquivo js foi iniciado, não a partir do npm?
Mihail Malostanidis
2

Por que não usar a resolução requerida ...

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

Com essa abordagem, trabalhe para todos os subcaminhos :)

Gianluca Cirone
fonte
1

Eu faço isso com findup-sync:

var findup = require('findup-sync');
var packagejson = require(findup('package.json'));
console.log(packagejson.version); // => '0.0.1' 
Luca Bonavita
fonte
findup começa com cwd, portanto, na maioria dos casos, ele apenas alcançaria o nível superior package.json, semelhante a process.env.npm_package_versionalém de não exigir que fosse iniciado via npm. Portanto, tentar obter a versão da sua biblioteca realmente obteria a versão do chamador. Um simples requerimento ('./ package.json') evitaria isso.
Mihail Malostanidis
1

Sei que essa não é a intenção do OP, mas eu apenas precisei fazer isso, por isso espero que ajude a próxima pessoa.

Se você estiver usando o docker-composite para o seu processo de CI / CD, poderá obtê-lo dessa maneira!

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

para a imagem, você pode usar qualquer imagem de nó. Eu uso alpino porque é o menor.

Patrick Lee Scott
fonte
0

Importar seu package.jsonarquivo em seu server.jsou app.jse, em seguida, propriedades de acesso package.json em arquivos do servidor.

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

A variável package contém todos os dados em package.json.

Patharraj
fonte
0

Criei um código útil para obter o package.json do módulo pai

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

Se estiver usando rollup, o rollup-plugin-replaceplug - in pode ser usado para adicionar a versão sem expor package.json ao cliente.

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

Em seguida, no código-fonte, em qualquer lugar onde você deseja ter a versão package.json, você usaria a 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
fonte