¿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

¿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.


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.


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';

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",
  ...
}

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.


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

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á.


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.


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


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


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}`);

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.


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.


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 :)


1

Hago esto con findup-sync:

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

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.


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.


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
}

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.