有没有办法从nodejs代码中的package.json获取版本?

有没有办法在nodejs应用程序中设置package.json的版本?我想要这样的东西

var port = process.env.PORT || 3000app.listen portconsole.log "Express server listening on port %d in %s mode %s", app.address().port, app.settings.env, app.VERSION
452094 次浏览

以下是如何从package.json中读取版本:

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

编辑:哇,这个答案最初来自2012年!现在有几个更好的答案。可能最干净的是:

const { version } = require('./package.json');

我发现以下代码片段最适合我。由于它使用require加载package.json,因此无论当前工作目录如何,它都可以工作。

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

一个警告,礼貌的@病原体

这样做有安全隐患。
注意不要将package.json暴露给客户端,因为这意味着您的所有依赖版本号、构建和测试命令等都将发送到客户端。
如果您在同一个项目中构建服务器和客户端,您也会公开您的服务器端版本号。攻击者可以使用这些特定数据来更好地适应对您服务器的攻击。

还有另一种从package.json文件中获取某些信息的方法,即使用pkginfo模块。

此模块的使用非常简单。您可以使用以下命令获取所有包变量:

require('pkginfo')(module);

或者只有某些细节(在这种情况下为0)

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在哪里。

我希望这会有帮助。

如果您的应用程序使用npm start启动,您可以简单地使用:

process.env.npm_package_version

查看package.jsonvars了解更多详情。

我这样做findup-sync

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

或者在普通的shell中:

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

这可以缩短为

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

使用ES6模块,您可以执行以下操作:

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

我知道这不是OP的意图,但我必须这样做,所以希望它能帮助下一个人。

如果您在CI/CD进程中使用docker-compose,您可以通过这种方式获得它!

version:image: node:7-alpinevolumes:- .:/usr/src/service/working_dir: /usr/src/service/command: ash -c "node -p \"require('./package.json').version.replace('\n', '')\""

对于图像,您可以使用任何节点图像。我使用高山,因为它是最小的。

您可以使用项目版本包。

$ 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由于某种原因丢失。

只是添加一个答案,因为我来到这个问题是为了了解在我的Web应用程序中包含package.json版本的最佳方式。

我知道这个问题是针对Node.js但是,如果您使用Webpack捆绑您的应用程序只是提醒一下,推荐的方法是使用定义插件在配置中声明一个全局版本并引用它。所以你可以在你的webpack.config.json

const pkg = require('../../package.json');
...
plugins : [new webpack.DefinePlugin({AppVersion: JSON.stringify(pkg.version),...

然后AppVersion现在是一个可供您使用的全局。还要确保在您的#1你通过全局道具忽略这个

对于那些寻找同样适用于服务器端的安全客户端解决方案的人来说,有性别。它是一个命令行工具,可以从最近的package.json读取版本并生成可导入的Common JS模块文件以导出版本。免责声明:我是一名维护者。

$ genversion lib/version.js

我承认客户端安全不是OP的主要意图,但正如马克华莱士aug的回答中所讨论的,这是高度相关的,也是我发现这个问答的原因。

有两种方法可以检索版本:

  1. 需要package.json并获取版本:
const { version } = require('./package.json');
  1. 使用环境变量:
const version = process.env.npm_package_version;

请不要使用JSON.parsefs.readFilefs.readFileSync,也不要使用另一个npm modules,这个问题没有必要。

package.json文件导入到server.jsapp.js中,然后将package.json属性访问到服务器文件中。

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

包变量包含package.json.中的所有数据

我做了一个有用的代码来获取父模块的package.json

function loadParentPackageJson() {if (!module.parent || !module.parent.filename) return nulllet dir = path.dirname(module.parent.filename)let maxDepth = 5let packageJson = nullwhile (maxDepth > 0) {const packageJsonPath = `${dir}/package.json`const exists = existsSync(packageJsonPath)if (exists) {packageJson = require(packageJsonPath)break}dir = path.resolve(dir, '../')maxDepth--}return packageJson}

您可以使用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}`);

要确定节点代码中的包版本,您可以使用以下命令:

  1. const version = require('./package.json').version;对于

  2. import {version} from './package.json'; ES6版本

  3. const version = process.env.npm_package_version;如果应用程序已使用npm start启动,则所有npm_*环境变量都可用。

  4. 你也可以使用下面的npm包——root-需求、pkginfo、项目版本。

为什么不使用需要解决…

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

使用这种方法适用于所有子路径:)

如果使用汇总,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.jsexport const packageVersion = 'MY_PACKAGE_JSON_VERSION' // replaced with actual version number in rollup.config.js

备选案文1

最佳做法是使用npm环境变量从package.json版本。

process.env.npm_package_version

更多信息:https://docs.npmjs.com/using-npm/config.html

只有当您使用NPM命令启动服务时,这才会起作用。

快速信息:您可以使用process.env.npm_package_[keyname]读取pacakge.json中的任何值

备选案文2

使用https://www.npmjs.com/package/dotenv作为.env文件设置环境变量中的版本并将其读取为process.env.version

我找到的最简单的方法:

const { version } = JSON.parse(fs.readFileSync('./package.json'))

const { version } = require("./package.json");console.log(version);
const v = require("./package.json").version;console.log(v);

我正在使用gitlab ci,并希望自动使用不同的版本来标记我的docker映像并推送它们。现在他们的默认docker映像不包含节点,所以我仅在shell中执行此操作的版本是这样的

脚本/getCurrentVersion.sh

BASEDIR=$(dirname $0)cat $BASEDIR/../package.json | grep '"version"' | head -n 1 | awk '{print $2}' | sed 's/"//g; s/,//g'

现在这个的作用是

  1. 打印您的包json
  2. 搜索带有“版本”的行
  3. 只接受第一个结果
  4. 替换"和,

请不要说我的脚本在我的存储库中的子文件夹中具有相应的名称。因此,如果您不将$BASEDIR/…/package.json更改为$BASEDIR/package.json

或者,如果你想能够获得主要,次要和补丁版本,我使用这个

脚本/getCurrentVersion.sh

VERSION_TYPE=$1BASEDIR=$(dirname $0)VERSION=$(cat $BASEDIR/../package.json | grep '"version"' | head -n 1 | awk '{print $2}' | sed 's/"//g; s/,//g')
if [ $VERSION_TYPE = "major" ]; thenecho $(echo $VERSION | awk -F "." '{print $1}' )elif [ $VERSION_TYPE = "minor" ]; thenecho $(echo $VERSION | awk -F "." '{print $1"."$2}' )elseecho $VERSIONfi

如果您的版本是1.2.3,您的输出将如下所示

$ > sh ./getCurrentVersion.sh major1
$> sh ./getCurrentVersion.sh minor1.2
$> sh ./getCurrentVersion.sh1.2.3

现在唯一的事情你将不得不确保的是您的软件包版本将是第一次在package.json关键是使用否则你最终会与错误的版本

NPM单行:

npm v7.20.0项目名称

npm pkg get version

在npm v7.20.0之前:

npm -s run env echo '$npm_package_version'

注意,这两种方法的输出略有不同:前者输出由引号包围的版本号(即"1.0.0"),后者没有(即1.0.0)。

在Unix中删除引号的一种解决方案是使用xargs

npm pkg get version | xargs echo

以防您想要获取目标包的版本。

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

示例:

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

用于版本Web组件,如下所示:

const { version } = require('../package.json')
class Widget extends HTMLElement {
constructor() {super()this.attachShadow({ mode: 'open' })}
public connectedCallback(): void {this.renderWidget()}
public renderWidget = (): void => {this.shadowRoot?.appendChild(this.setPageTemplate())this.setAttribute('version', version)}}

如果你正在寻找module (package.json: "type": "module")(ES6导入)的支持,例如来自于重构通用JS,你应该(在写这篇文章的时候)这样做:

import { readFile } from 'fs/promises';
const pkg = JSON.parse(await readFile(new URL('./package.json', import.meta.url)));
console.log(pkg.version)

或者,使用node --experimental-json-modules index.js运行节点进程:

import pkg from './package.json'console.log(pkg.version)

但是,在json模块变得普遍可用之前,您将收到警告。

如果出现语法或(顶级)异步错误,则可能是在较旧的节点版本中。请至少更新node@14。

一个安全的选择是添加一个生成单独版本文件的npm脚本:

"scripts": {"build": "yarn version:output && blitz build","version:output": "echo 'export const Version = { version: \"'$npm_package_version.$(date +%s)'\" }' > version.js"}

这将输出version.js,内容为:

export const Version = { version: "1.0.1.1622225484" }

我实际上已经看过这里的大多数解决方案,它们要么不适用于Windows和Linux /OSX,要么根本不起作用,或者依赖于grep/awk/ses等Unix shell工具。

接受的答案在技术上是可行的,但它会把你的整个package.json吸进你的构建中,这就是一件坏事,只有绝望的人才应该暂时使用它来解封,通常应该避免,至少对于生产代码来说是这样。另一种方法是只使用该方法将版本写入一个可以代替整个文件使用的常量。

因此,对于其他寻找跨平台解决方案(不依赖于Unix shell命令)和本地解决方案(没有外部依赖项)的人来说:

由于可以假设安装了Node.js,并且它已经是跨平台的,我刚刚创建了一个make_version.js文件:

const PACKAGE_VERSION = require("./package.json").version;console.log(`export const PACKAGE_VERSION = "${PACKAGE_VERSION}";`);console.error("package.json version:", PACKAGE_VERSION);

并将version命令添加到package.json

scripts: {"version": "node make_version.js > src/version.js",

然后补充说:

    "prebuild": "npm run version","prestart": "npm run version",

它在每个startbuild上创建一个新的src/versions.js。当然,这可以很容易地在version脚本中调整为不同的位置,或者在make_version.js文件中输出不同的语法和常量名称等。

我们可以通过两种方式从package.json读取版本或其他键

1-使用require并导入所需的密钥,例如:

const version = require('./package.json')

2-使用文档中提到的package_vars

process.env.npm_package_version

我正在使用create-react-app,并且在执行我的React-app时没有process.env.npm_package_version可用。

我不想在我的客户端代码中引用package.json(因为将危险信息暴露给客户端,例如包版本),我也不想安装另一个依赖项(genversion)。

我发现我可以在package.json中引用version,通过在我的package.json中使用$npm_package_version

"scripts": {"my_build_script": "REACT_APP_VERSION=$npm_package_version react-scripts start"}

现在版本总是跟随package.json中的版本。