¿Hay alguna manera de obtener la versión de package.json en el código de nodejs?

586

¿Hay alguna manera de configurar la versión package.jsonen una aplicación de nodejs? Quisiera algo como esto

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
fuente
¿Es más importante obtener la versión de Node o la versión declarada en package.json? Si el formulario, esto le dará la versión en ejecución:console.log(process.version)
Adrian Lynch

Respuestas:

957

Descubrí que el siguiente fragmento de código funcionó mejor para mí. Como se usa requirepara cargar package.json, funciona independientemente del directorio de trabajo actual.

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

Una advertencia, cortesía de @Pathogen:

Hacer esto con Browserify tiene implicaciones de seguridad.
Tenga cuidado de no exponer su package.jsonal cliente, ya que significa que todos sus números de versión de dependencia, comandos de compilación y prueba y más se envían al cliente.
Si está compilando servidor y cliente en el mismo proyecto, también expone sus números de versión del lado del servidor. Un atacante puede utilizar dichos datos específicos para adaptarse mejor al ataque en su servidor.

Mark Wallace
fuente
25
si sigues quemándote tratando de agarrar esto desde diferentes lugares (como yo), puedes hacerlorequire('root-require')('package.json').version
mikermcneil
55
No funciona para mi script con shebang instalado globalmente. Error: Cannot find module 'package.json'.
exebook
14
versión más corta - require ('./ package').
Afanasii Kurakin
6060
¡Advertencia! Hacer esto con browserify tiene implicaciones de seguridad: package.json en su paquete significa que todos sus números de versión de dependencia, comandos de compilación y prueba y más se envían al cliente. Si está compilando servidor y cliente en el mismo proyecto, también expone sus números de versión del lado del servidor.
Patógeno
44
@Pathogen genversion resuelve el problema en el lado del cliente. Es una herramienta que lee la versión de package.json y genera un módulo importable a partir de ella. Descargo de responsabilidad: soy un mantenedor.
Akseli Palén
349

Si su aplicación se inicia con 'npm start', simplemente puede usar:

process.env.npm_package_version

Ver package.json vars para más detalles.

Julien Christin
fuente
66
Esta es probablemente la mejor respuesta ya que la mayor parte de la información en package.json se adjunta a la variable de tiempo de ejecución del proceso
Alexander Mills
2
Yeap, estoy de acuerdo. Esta debería ser la respuesta correcta, utilizando la variable de proceso que no necesita abrir y leer nuevamente el archivo package.json.
Juanma
12
Y fuera del nodo (por ejemplo, scripts de shell ejecutados mediante npm run …) la versión estará en la variable de entorno $npm_package_version.
Quinn Commandado el
12
Cuando se llama desde scripts de otro paquete, esto informa incorrectamente la versión del paquete de llamada y no el paquete llamado .
jjrv
66
Funciona dentro de una aplicación electrónica comenzada con npm start, pero no dentro de una aplicación electrónica integrada: para eso, puede encontrarla en app.getVersion.
ChrisV
158

Con los módulos ES6 puede hacer lo siguiente:

import {version} from './package.json';
Patrick Lee Scott
fuente
2
Pensé que estos no eran compatibles con el nodo: github.com/nodejs/help/issues/53
ripper234
1
No hay módulos ES6 aún no son compatibles directamente, sino que comúnmente se utilizan todos modos, ha permitido el uso de Babel
Patrick Lee Scott
44
@Sornii no, todo el paquete.json estará en el cliente. Utilicé definePlugin de webpack para pasar solo la información seleccionada del entorno del nodo al navegador.
Doeke
2
¿Alguna implicación de seguridad como la especificada en stackoverflow.com/a/10855054/540144 ?
itsazzad
1
Sí, los mismos problemas de seguridad. Todo el package.json se incluirá en el paquete del cliente.
Neromancer
95

O en la vieja cáscara simple:

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

Esto se puede acortar a

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

A pesar de que esto no es exactamente lo que hizo la pregunta, es útil si desea utilizar la versión dentro de package.jsonsí misma, por ejemplo, para iniciar sesión en un archivo versionado en 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
fuente
Sin embargo, eso no está dentro de la aplicación nodeJS, como se solicitó.
Steve Bennett
1
@SteveBennett No, pero ayudó a 90 personas más a mí.
K - La toxicidad en SO está creciendo.
1
Probablemente mucho más que eso.
Steve Bennett
61

Hay dos formas de recuperar la versión:

  1. Requerir package.jsony obtener la versión:
const { version } = require('./package.json');
  1. Usando las variables de entorno:
const version = process.env.npm_package_version;

Por favor, no use JSON.parse, fs.readFile, fs.readFileSyncy no utilice otra npm modulesque no es necesario para esta pregunta.

Alex dykyі
fuente
2
Gracias por este fragmento de código, que puede proporcionar una ayuda limitada e inmediata. Una explicación adecuada mejoraría en gran medida su valor a largo plazo al mostrar por qué esta es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Por favor, editar su respuesta a añadir un poco de explicación, incluyendo los supuestos realizados.
milo526
8
Entonces, npm_*los valores del entorno solo están disponibles si NPM inició su script, por ejemplo npm start. Si lo estás haciendo node app.jso similar, no estarán presentes.
Nate
@Nate ¿Entonces es mejor usar la versión de package.json?
Filip Š
38

Aquí se explica cómo leer la versión de package.json:

fs = require('fs')
json = JSON.parse(fs.readFileSync('package.json', 'utf8'))
version = json.version
Evan Moran
fuente
He visto esto un montón, y me gusta, ¿sabe usted / alguien las consideraciones que require() introduces? (for instance, does requieren () `no admitir la lectura utf8? como su fragmento puede sugerir)
electblake
44
require()almacena en caché el archivo, que en este caso no debería hacer la diferencia.
jlee
@jlee, ¿hay alguna razón por la que las personas suelen hacerlo en JSON.parse(fs.readFileSync('package.json', 'utf8'))lugar de delete require.cache[require.resolve('package.json')]; require('package.json')cuando quieren recargar?
Mihail Malostanidis
const {versión} = require ('./ package.json');
alex dykyі
23

Hay otra forma de obtener cierta información de su package.jsonarchivo, es decir, utilizando el módulo pkginfo .

El uso de este módulo es muy simple. Puede obtener todas las variables del paquete usando:

require('pkginfo')(module);

O solo ciertos detalles ( versionen este caso)

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

Y las variables de su paquete se establecerán en module.exports(para que se pueda acceder al número de versión a través de module.exports.version).

Puede usar el siguiente fragmento 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 tiene una característica muy buena: se puede usar en cualquier archivo de su proyecto (por ejemplo, en subcarpetas) y obtendrá información automáticamente de su archivo package.json. Para que no tenga que preocuparse de dónde package.jsonestá.

Espero que le ayudará.

Tom
fuente
1
que hay moduleaqui
chovy
@chovy, moduleno es esta variable de ejemplo específica; Es una variable que representa el módulo actual en node.js. Puede leer más sobre los módulos node.js aquí: nodejs.org/api/modules.html#modules_the_module_object
Tom
2
Estoy tratando de obtener la versión de otros módulos requeridos por mi módulo ... y estoy teniendo dificultades para descubrir si pkginfo lo hace posible.
Michael
23

Para aquellos que buscan una solución segura del lado del cliente que también funcione en el lado del servidor, existe la genversion . Es una herramienta de línea de comandos que lee la versión desde el package.json más cercano y genera un archivo de módulo CommonJS importable que exporta la versión. Descargo de responsabilidad: soy un mantenedor.

$ genversion lib/version.js

Reconozco que la seguridad del lado del cliente no era la intención principal de OP, pero como se discutió en las respuestas de Mark Wallace y aug , es muy relevante y también la razón por la que encontré estas preguntas y respuestas.

Akseli Palén
fuente
44
Esta es LA respuesta, y necesita más votos para superar la respuesta profundamente problemática en este momento.
Jeff Allen
1
Algunas personas pueden alarmarse por el hecho de que esta es una herramienta de línea de comandos. ¡No te preocupes! El archivo Léame de la herramienta describe cómo (fácilmente) integrar la llamada en build en package.json, para que pueda olvidarse de la existencia de la herramienta y siempre tenga el número de versión más reciente.
malamut
11

Solo agregué una respuesta porque llegué a esta pregunta para ver la mejor manera de incluir la versión de package.json en mi aplicación web.

Sé que esta pregunta está dirigida a Node.js, sin embargo, si está utilizando Webpack para agrupar su aplicación, solo un recordatorio, la forma recomendada es usar DefinePlugin para declarar una versión global en la configuración y hacer referencia a eso. Entonces podrías hacer en tuwebpack.config.json

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

...

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

Y AppVersionahora es un global que está disponible para su uso. También asegúrese de .eslintrcignorar esto a través del accesorio global

ago
fuente
8

Opción 1

La mejor práctica es versionar desde package.json usando variables de entorno npm.

process.env.npm_package_version

Más información sobre: https://docs.npmjs.com/using-npm/config.html

Esto funcionará solo cuando inicie su servicio utilizando el comando NPM.

Información rápida: puede leer cualquier valor en pacakge.json usando process.env.npm_package_ [keyname]

opcion 2

Configuración de la versión en la variable de entorno usando https://www.npmjs.com/package/dotenv como .envarchivo y considérelo enprocess.env.version

Aravin
fuente
7

Puede usar ES6 para importar package.json para recuperar el número de versión y generar la versión en la consola.

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

console.log(`App ---- ${app_name}\nVersion ---- ${app_version}`);
ÁngelBlanco
fuente
3
Esto funciona siempre que establezca "resolveJsonModule" en "verdadero" en tsconfig.json.
Russell Phillips
6

Para determinar la versión del paquete en el código de nodo, puede usar lo siguiente:

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

  2. import {version} from './package.json'; para la versión ES6

  3. const version = process.env.npm_package_version; Si la aplicación se ha comenzado a utilizar npm start, todas las variables de entorno npm_ * estarán disponibles.

  4. También puede usar los siguientes paquetes npm: root-require, pkginfo, project-version.

Rohit Jaiswal
fuente
4

Puede usar el paquete de versión del proyecto .

$ npm install --save project-version

Entonces

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

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

Utiliza process.env.npm_package_versionpero retrocede en la versión escrita en el package.jsoncaso de que la var env desaparezca por alguna razón.

simonepri
fuente
Por ejemplo, si el archivo js no se inició desde npm?
Mihail Malostanidis
2

¿Por qué no utilizar la resolución requerida?

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

Con este enfoque, trabaje para todas las rutas secundarias :)

Gianluca Cirone
fuente
1

Hago esto con findup-sync:

var findup = require('findup-sync');
var packagejson = require(findup('package.json'));
console.log(packagejson.version); // => '0.0.1' 
Luca Bonavita
fuente
findup comienza con cwd, por lo que en la mayoría de los casos solo obtendría el nivel superior package.json, similar a process.env.npm_package_versionademás de no requerir que se inicie a través de npm. Por lo tanto, tratar de obtener la versión de su biblioteca realmente obtendría la versión de la persona que llama. Un simple requerimiento ('./ package.json') evitaría esto.
Mihail Malostanidis
1

Sé que esta no es la intención del OP, pero solo tenía que hacer esto, así que espero que ayude a la siguiente persona.

Si está utilizando docker-compose para su proceso de CI / CD, ¡puede obtenerlo de esta manera!

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 la imagen, puede usar cualquier imagen de nodo. Yo uso alpino porque es el más pequeño.

Patrick Lee Scott
fuente
0

Importe su package.jsonarchivo en su server.jso app.jsy luego acceda a las propiedades de package.json en el archivo del servidor.

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

La variable del paquete contiene todos los datos en package.json.

Patharraj
fuente
0

Hice un código útil para obtener el paquete del módulo principal.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
fuente
0

Si usa el paquete acumulativo, el rollup-plugin-replacecomplemento se puede usar para agregar la versión sin exponer package.json al 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
    }),
  ]
};

Luego, en el código fuente, en cualquier lugar donde desee tener la versión package.json, usaría la cadena 'MY_PACKAGE_JSON_VERSION'.

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