ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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
获取Node的版本还是package.json中声明的版本更重要?如果是表单,这将为您提供正在运行的版本:console.log(process.version)

A
Audwin Oyong

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

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

警告,由 @Pathogen 提供:

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


如果您试图从不同的地方(就像我一样)抓取它而不断被烧毁,您可以这样做require('root-require')('package.json').version
在全局安装 shebang 的情况下不适用于我的脚本。 Error: Cannot find module 'package.json'
更短 - require('./package').version
警告!使用 browserify 执行此操作具有安全隐患:您的包中的 package.json 意味着您的所有依赖项版本号、构建和测试命令等都将发送到客户端。如果你在同一个项目中构建服务器和客户端,你也会暴露你的服务器端版本号。
@Pathogen genversion 解决了客户端的问题。它是一个从 package.json 读取版本并从中生成可导入模块的工具。免责声明:我是维护者。
P
Paolo

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

process.env.npm_package_version

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


这可能是最好的答案,因为 package.json 中的大部分信息都附加到流程运行时变量
是的,我同意。这应该是正确的答案,使用您不需要打开并再次读取 package.json 文件的流程变量。
在节点之外(例如,通过 npm run … 执行的 shell 脚本),版本将在环境变量 $npm_package_version 中。
当从另一个包的脚本调用时,这会错误地报告调用包的版本,而不是被调用包的版本。
它适用于以 npm start 开头的 electron 应用程序,但不适用于构建的电子应用程序:为此,您可以在 app.getVersion 中找到它。
P
Patrick Lee Scott

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

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

我认为节点不支持这些:github.com/nodejs/help/issues/53
没有 es6 模块尚未直接支持,但无论如何都是常用的,使用 Babel 启用
@Sornii 不,整个 package.json 将在客户端中。我使用 webpack 的 definePlugin 仅将选定的信息从节点环境传递到浏览器。
stackoverflow.com/a/10855054/540144 中指定的任何安全隐患?
是的,同样的安全问题。整个 package.json 将包含在客户端包中。
a
abernier

或者在普通的旧外壳中:

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

这可以缩短为

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

不过,根据要求,这不在 nodeJS 应用程序本身内。
我使用了这个,但它停止工作,节点 16 告诉我 SyntaxError: Unexpected token '.' - 有什么想法吗?
A
Arian Acosta

有两种检索版本的方法:

需要 package.json 并获取版本:

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

使用环境变量:

const version = process.env.npm_package_version;

请不要使用 JSON.parsefs.readFilefs.readFileSync,也不要使用另一个 npm modules,这不是这个问题的必要条件。


感谢您提供此代码片段,它可能会提供一些有限的即时帮助。 proper explanation would greatly improve its long-term value 通过显示为什么这是解决问题的好方法,并且会使其对有其他类似问题的未来读者更有用。请edit您的回答以添加一些解释,包括您所做的假设。
然后 npm_* 环境值仅在您的脚本由 NPM 启动时可用,例如 npm start。如果您正在执行 node app.js 或类似操作,它们将不会出现。
@Nate 所以最好使用 package.json 的版本?
您还可以将脚本 "start": "node app.js" 添加到您的 package.json 并使用 npm start 启动您的应用程序 - 这将为您提供 npm env vars
E
Evan Moran

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

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

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

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

我看过很多,我很喜欢 - 你/任何人都知道 require() introduces? (for instance, does require()`不支持 utf8 读取的注意事项吗?正如你的片段可能暗示的那样)
require() 缓存文件,在这种情况下不应该有所作为。
@jlee 人们在想要重新加载时通常使用 JSON.parse(fs.readFileSync('package.json', 'utf8')) 而不是 delete require.cache[require.resolve('package.json')]; require('package.json') 是否有原因?
const { 版本 } = require('./package.json');
A
Akseli Palén

对于那些希望在服务器端也能工作的安全客户端解决方案的人,有genversion。它是一个命令行工具,可以从最近的 package.json 中读取版本,并生成一个可导入的 CommonJS 模块文件来导出版本。免责声明:我是维护者。

$ genversion lib/version.js

我承认客户端安全不是 OP 的主要意图,但正如 Mark Wallaceaug 的回答中所讨论的,它高度相关,也是我找到此问答的原因。


这就是答案,它需要更多的选票才能超越现在最有问题的答案。
有些人可能会对这是一个命令行工具这一事实感到震惊。不用担心!该工具的自述文件描述了如何(轻松)将 build 调用集成到 package.json 中,这样您就可以忘记该工具的存在,并且始终拥有最新的版本号。
这应该是正确的答案。谢谢@Akseli。
是的!!!这是正确的答案。没有人应该将他们的 package.json 文件与他们的应用程序一起发送。
@EricJorgensen 非常棒,谢谢:) 我可以引用您对 genversion 存储库 README.md 的评论吗?
T
Tom

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

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

require('pkginfo')(module);

或仅某些详细信息(在本例中为 version

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

我希望这会有所帮助。


这里的 module 是什么?
@chovy,module 不是这个特定的示例变量;它是一个代表 node.js 中当前模块的变量。您可以在此处阅读有关 node.js 模块的更多信息:nodejs.org/api/modules.html#modules_the_module_object
我正在尝试获取我的模块所需的其他模块的版本......而且我很难弄清楚 pkginfo 是否使这成为可能。
A
Aravin

选项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


干净整洁。谢谢!
对我来说是 undefined
@Boris - 您正在尝试选项 1 或 2?
节点 14 上的选项 1,使用 ES 模块。也许是因为我正在使用 node index.js 运行我的代码。如何通过 npm 运行 "bin": "my-bin.js"
M
Mbrevda

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


a
aug

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

我知道这个问题是针对 Node.js 的,但是,如果您使用 Webpack 捆绑您的应用程序,建议您使用 DefinePlugin 在配置中声明一个全局版本并引用它。所以你可以在你的 webpack.config.json

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

...

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

然后 AppVersion 现在是一个可供您使用的全局变量。还要确保在您的 .eslintrc you ignore this via the globals prop


Á
ÁngelBlanco

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

只要您在 tsconfig.json 中将“resolveJsonModule”设置为“true”,它就可以工作。
L
Laurenz Albe

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

常量版本 = 要求('./package.json').version;对于 < ES6 版本 import {version} from './package.json';对于 ES6 版本 const version = process.env.npm_package_version;如果应用程序已使用 npm start 启动,则所有 npm_* 环境变量都可用。您也可以使用以下 npm 包 - root-require、pkginfo、project-version。


e
eljefedelrodeodeljefe

如果您正在寻找 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)

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

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

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

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


C
Carter

一个安全的选择是添加一个生成单独版本文件的 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" }

s
simonepri

您可以使用 project-version 包。

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


例如,如果 js 文件不是从 npm 启动的?
G
Gianluca Cirone

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

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

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


L
Long Nguyen

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

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

例子:

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

P
Patrick Lee Scott

我知道这不是 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', '')\""

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


m
mindrones

我使用 findup-sync 执行此操作:

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

findup 以 cwd 开头,因此在大多数情况下,它只会获得顶级 package.json,类似于 process.env.npm_package_version,除了不需要通过 npm 启动它。因此,尝试获取您的库版本实际上会获取调用者的版本。一个简单的 require('./package.json') 可以避免这种情况。
v
vinyll

我发现的最精简的方式:

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

J
Johnty

const { 版本 } = require("./package.json");控制台.log(版本); const v = require("./package.json").version;控制台.log(v);


r
relief.melone

我正在使用 gitlab ci 并希望自动使用不同的版本来标记我的 docker 图像并推送它们。现在他们的默认泊坞窗图像不包括节点所以我的版本只在 shell 中执行此操作是这个

脚本/getCurrentVersion.sh

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

现在这样做是

打印你的包 json 搜索带有“版本”的行只取第一个结果替换“和,

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

或者,如果您希望能够获得主要、次要和补丁版本,我使用这个

脚本/getCurrentVersion.sh

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

if [ $VERSION_TYPE = "major" ]; then
  echo $(echo $VERSION | awk -F "." '{print $1}' )
elif [ $VERSION_TYPE = "minor" ]; then
  echo $(echo $VERSION | awk -F "." '{print $1"."$2}' )
else
  echo $VERSION
fi

如果您的版本是 1.2.3,请采用这种方式。你的输出看起来像这样

$ > sh ./getCurrentVersion.sh major
1

$> sh ./getCurrentVersion.sh minor
1.2

$> sh ./getCurrentVersion.sh
1.2.3

现在您唯一需要确保的是您的包版本将是 package.json 中第一次使用该密钥,否则您将得到错误的版本


A
Appurist - Paul W

我实际上已经通过了这里的大多数解决方案,它们要么不能在 Windows 和 Linux/OSX 上工作,要么根本不能工作,或者依赖于 Unix shell 工具,如 grep/awk/sed。

接受的答案在技术上是有效的,但它会将你的整个 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);

并向 package.json 添加了 version 命令:

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 文件中输出不同的语法和常量名称等。


g
g00dnatur3

我做了一个有用的代码来获取父模块的 package.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
}

s
spwisner

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

A
Aravind S

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

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

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


n
no_igor

用于像这样对 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)
  }
}