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

Abh*_*nik 519 versioning version node.js npm

有没有办法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
Run Code Online (Sandbox Code Playgroud)

小智 894

我发现以下代码片段对我来说效果最好.由于它使用'require'来加载package.json,因此无论当前工作目录如何,它都能正常工作.

var pjson = require('./package.json');
console.log(pjson.version);
Run Code Online (Sandbox Code Playgroud)

由@Pathogen提供的警告:

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

  • 警告!使用browserify执行此操作会带来安全隐患:bundle中的package.json意味着所有依赖版本号,构建和测试命令等都会发送到客户端.如果您在同一个项目中构建服务器和客户端,则也会公开服务器端版本号. (53认同)
  • 如果你不断尝试从不同的地方抓住它(就像我一样),你可以做`require('root-require')('package.json').版本` (24认同)
  • 更短 - 要求('./ package').版本 (11认同)
  • 在全球安装shebang的情况下,我的脚本无效.`错误:无法找到模块'package.json'. (5认同)
  • `var pjson = require('package.json')` 可能会暴露你的整个 `package.json`,这是你很可能不想要的。更好的选择是 Julien Christin 的回答,它正在使用:`process.env.npm_package_version` (4认同)
  • @Pathogen [genversion](https://www.npmjs.com/package/genversion)在客户端解决了这个问题.它是一个从package.json读取版本并从中生成可导入模块的工具.免责声明:我是维护者. (3认同)
  • 将在此处担保 [genversion](https://www.npmjs.com/package/genversion)。作为 TS 用户,在构建步骤中添加确实很容易。另外,我不必担心某些依赖包会以某种公开 package.json 的方式构建我的代码。我更愿意将版本号复制出来(自动)并以这种方式导出到代码的其余部分。 (2认同)

Jul*_*tin 296

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

process.env.npm_package_version
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅package.json vars.

  • 这对我来说是一个[电子](http://electron.atom.io/)应用程序. (11认同)
  • 从另一个包的脚本调用时,这会错误地报告_calling_包的版本而不是_called_包. (11认同)
  • 在节点之外(例如,通过`npm run ...`执行的shell脚本),版本将在环境变量`$ npm_package_version`中. (10认同)
  • 对我来说未定义 (7认同)
  • 它适用于以'npm start`开头的[电子](http://electron.atom.io)应用程序,但不在内置的电子应用程序中:为此,你可以在[`app.getVersion`]中找到它( http://electron.atom.io/docs/api/app/#appgetversion). (6认同)
  • 这可能是最好的答案,因为package.json中的大多数信息都附加到进程运行时变量 (5认同)
  • 是的,我同意。使用不需要打开并重新读取package.json文件的过程变量,这应该是正确的答案。 (2认同)
  • 仅供参考:electron,ʻapp.getVersion()`可以在内置电子应用程序中使用,但是(至少在我的开发环境中),它_only_可以在内置应用程序中使用-dev env返回电子版本,因此在渲染器中它将是某种东西像`process.env.npm_package_version || require('electron')。remote.app.getVersion()` (2认同)

Pat*_*ott 131

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

import {version} from './package.json';
Run Code Online (Sandbox Code Playgroud)

  • 是的,同样的安全问题。整个 package.json 将包含在客户端包中。 (6认同)
  • 任何安全隐患,如 /sf/answers/759853811/ 中指定的那样? (4认同)
  • 我认为节点不支持这些:https://github.com/nodejs/help/issues/53 (3认同)
  • @Sornii不,整个package.json将在客户端.我使用webpack的definePlugin只将选定的信息从节点环境传递给浏览器. (3认同)
  • 还没有直接支持 es6 模块,但无论如何都常用,使用 Babel 启用 (2认同)
  • 在节点 14.17.6 上,我收到 `TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".json" for /my/project/package.json` (2认同)
  • @BorisVerkhovskiy(我知道这已经很旧了)如果您使用“原始”Node 程序(例如命令行工具),Node 目前不知道如何通过 ES6 导入来导入 JSON 文件。答案和其他评论基于某些构建工具所做的工作。当没有构建步骤时,并且您基本上正在执行“node mycode.js”,似乎没有办法获取“package.json”而不读取它,这本身就是有问题的,因为代码必须*找到它。 (2认同)

abe*_*ier 79

或者在普通的旧壳中:

node -e "console.log(require('./package.json').version);"
Run Code Online (Sandbox Code Playgroud)

这可以缩短为

node -p "require('./package.json').version"
Run Code Online (Sandbox Code Playgroud)

即使这不是问题所针对的问题,但如果您想在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",
  ...
}
Run Code Online (Sandbox Code Playgroud)

  • 但是,根据要求,这不在 nodeJS 应用程序本身中。 (3认同)

аle*_*kyі 44

正确的答案将在这里举例:

  1. 回答(此代码包含package.json文件并获取版本)

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


  1. 回答

    const version = process.env.npm_package_version


请不要使用JSON.parse,fs.readFile,fs.readFileSync并且不使用另一种npm modules,没有必要为这个问题.

  • 然后`npm_*`环境值仅在你的脚本由NPM启动时才可用,例如`npm start`.如果你正在做`node app.js`或类似的,它们将不存在. (5认同)
  • 感谢您提供此代码段,它可能会提供一些有限的即时帮助。通过显示_why_这是解决该问题的好方法,[适当的解释将大大提高其长期价值](// meta.stackexchange.com/q/114762/206345),并将使其对以后的读者更加有用。其他类似的问题。请[编辑]您的答案以添加一些解释,包括您所做的假设。 (2认同)

Eva*_*ran 35

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

fs = require('fs')
json = JSON.parse(fs.readFileSync('package.json', 'utf8'))
version = json.version
Run Code Online (Sandbox Code Playgroud)

  • `require()`缓存文件,在这种情况下不应该有所作为. (3认同)
  • const { 版本 } = require('./package.json'); (2认同)

Tom*_*Tom 21

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

使用这个模块非常简单.您可以使用以下方法获取所有包变量

require('pkginfo')(module);
Run Code Online (Sandbox Code Playgroud)

或者只是某些细节(version在这种情况下)

require('pkginfo')(module, 'version');
Run Code Online (Sandbox Code Playgroud)

并且您的包变量将设置为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
Run Code Online (Sandbox Code Playgroud)

这个模块有很好的功能 - 它可以在项目的任何文件中使用(例如在子文件夹中),它会自动从你的文件中获取信息package.json.所以你不必担心你在哪里package.json.

我希望这会有所帮助.

  • 这里的“模块”是什么? (2认同)
  • 我正在尝试获取我的模块所需的其他模块的版本...并且我很难弄清楚 pkginfo 是否使这成为可能。 (2认同)

Aks*_*lén 21

对于那些寻求在服务器端也能运行的安全客户端解决方案的人来说,存在异步.它是一个命令行工具,它从最近的package.json读取版本,并生成一个可导入的CommonJS模块文件,用于导出该版本.免责声明:我是维护者.

$ genversion lib/version.js
Run Code Online (Sandbox Code Playgroud)

我承认客户端安全不是OP的主要目的,但正如Mark WallaceAug的回答中所讨论的那样,这是非常重要的,也是我发现这个问答的原因.

  • 这就是答案,它需要更多的选票才能超越目前最棘手的问题。 (4认同)
  • 这应该是正确的答案。谢谢@Akseli。 (3认同)
  • 有些人可能会因为这是一个命令行工具而感到震惊。不用担心!该工具的自述文件描述了如何(轻松)将构建调用集成到 package.json 中,以便您可以忘记该工具的存在,并始终拥有最新的版本号。 (2认同)

Ara*_*vin 21

选项1

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

process.env.npm_package_version
Run Code Online (Sandbox Code Playgroud)

更多信息: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


Taw*_*hat 18

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

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

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

Run Code Online (Sandbox Code Playgroud)

2 - 使用文档中提到的package_vars

process.env.npm_package_version
Run Code Online (Sandbox Code Playgroud)


小智 14

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

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

输出version.js内容为:

export const Version = { version: "1.0.1.1622225484" }
Run Code Online (Sandbox Code Playgroud)


elj*_*efe 12

如果您正在寻找module (package.json: "type": "module")(ES6 导入)支持,例如来自重构 commonJS,您应该(在撰写本文时)执行以下操作之一:

import { readFile } from 'fs/promises';

const pkg = JSON.parse(await readFile(new URL('./package.json', import.meta.url)));

console.log(pkg.version)
Run Code Online (Sandbox Code Playgroud)

或者,运行节点进程以node --experimental-json-modules index.js执行以下操作:

import pkg from './package.json'
console.log(pkg.version)
Run Code Online (Sandbox Code Playgroud)

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

如果您收到语法或(顶级)异步错误,则您可能使用的是较旧的节点版本。至少更新到node@14。


aug*_*aug 10

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

我知道这个问题是针对Node.js的,但是,如果你使用Webpack捆绑你的app只是一个提醒,推荐的方法是使用DefinePlugin在config中声明一个全局版本并引用它.所以你可以做你的webpack.config.json

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

...

plugins : [
    new webpack.DefinePlugin({
      AppVersion: JSON.stringify(pkg.version),
...
Run Code Online (Sandbox Code Playgroud)

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


Mbr*_*vda 9

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


Áng*_*nco 8

您可以使用 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}`);
Run Code Online (Sandbox Code Playgroud)

  • 只要您在 tsconfig.json 中将“resolveJsonModule”设置为“true”,这就会起作用。 (3认同)

小智 7

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

  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。


小智 7

为什么不使用 require 解析...

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

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


Ilm*_*ula 7

我正在使用,但在执行我的 React 应用程序时create-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"
}
Run Code Online (Sandbox Code Playgroud)

现在版本始终遵循package.json.


Pat*_*ott 5

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

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

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', '')\""
Run Code Online (Sandbox Code Playgroud)

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


小智 5

您可以使用project-version包。

$ npm install --save project-version
Run Code Online (Sandbox Code Playgroud)

然后

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

console.log(version);
//=>  '1.0.0'
Run Code Online (Sandbox Code Playgroud)

它使用process.env.npm_package_version但回退在package.jsonenv var 由于某种原因丢失的情况下编写的版本。


vin*_*yll 5

我发现的最精简的方法:

const { version } = JSON.parse(fs.readFileSync('./package.json'))
Run Code Online (Sandbox Code Playgroud)


Lon*_*yen 5

如果您想获取目标包的版本。

import { version } from 'TARGET_PACKAGE/package.json';
Run Code Online (Sandbox Code Playgroud)

例子:

import { version } from 'react/package.json';
Run Code Online (Sandbox Code Playgroud)


App*_*l W 5

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

接受的答案在技术上是有效的,但它将你的整个 package.json 吸进你的构建中,这是一件坏事,只有绝望的人才应该使用,暂​​时解锁,并且通常应该避免,至少对于生产代码。一种替代方法是使用该方法仅将版本写入可用作构建源文件的单个常量,而不是整个文件。

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

由于可以假设已安装 Node.js,并且它已经是跨平台的,因此我刚刚创建了一个make_version.js文件(或make_version.cjs在更新的环境中):

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

并添加了一个version命令package.json

scripts: {
    "version": "node make_version.js > src/version.js",
Run Code Online (Sandbox Code Playgroud)

或者

scripts: {
    "version": "node make_version.cjs > src/version.js",
Run Code Online (Sandbox Code Playgroud)

(对于 CommonJS 文件)然后添加:

    "prebuild": "npm run version",
    "prestart": "npm run version",
Run Code Online (Sandbox Code Playgroud)

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

另请注意,pnpm 包管理器不会自动运行“预”脚本,因此如果使用该 PM,您可能需要针对两个命令调整它。