有没有办法在 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
console.log(process.version)
我发现以下代码片段最适合我。由于它使用 require
加载 package.json
,因此无论当前工作目录如何,它都能正常工作。
var pjson = require('./package.json');
console.log(pjson.version);
警告,由 @Pathogen 提供:
使用 Browserify 执行此操作具有安全隐患。注意不要将你的 package.json 暴露给客户端,因为这意味着你所有的依赖版本号、构建和测试命令等等都会发送给客户端。如果你在同一个项目中构建服务器和客户端,你也会暴露你的服务器端版本号。攻击者可以使用此类特定数据来更好地适应对您服务器的攻击。
如果您的应用程序是使用 npm start
启动的,您可以简单地使用:
process.env.npm_package_version
有关详细信息,请参阅 package.json vars。
npm run …
执行的 shell 脚本),版本将在环境变量 $npm_package_version
中。
使用 ES6 模块,您可以执行以下操作:
import {version} from './package.json';
或者在普通的旧外壳中:
$ node -e "console.log(require('./package.json').version);"
这可以缩短为
$ node -p "require('./package.json').version"
SyntaxError: Unexpected token '.'
- 有什么想法吗?
有两种检索版本的方法:
需要 package.json 并获取版本:
const { version } = require('./package.json');
使用环境变量:
const version = process.env.npm_package_version;
请不要使用 JSON.parse
、fs.readFile
、fs.readFileSync
,也不要使用另一个 npm modules
,这不是这个问题的必要条件。
npm_*
环境值仅在您的脚本由 NPM 启动时可用,例如 npm start
。如果您正在执行 node app.js
或类似操作,它们将不会出现。
package.json
的版本?
"start": "node app.js"
添加到您的 package.json 并使用 npm start
启动您的应用程序 - 这将为您提供 npm env vars
以下是如何从 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()
缓存文件,在这种情况下不应该有所作为。
JSON.parse(fs.readFileSync('package.json', 'utf8'))
而不是 delete require.cache[require.resolve('package.json')]; require('package.json')
是否有原因?
对于那些希望在服务器端也能工作的安全客户端解决方案的人,有genversion。它是一个命令行工具,可以从最近的 package.json 中读取版本,并生成一个可导入的 CommonJS 模块文件来导出版本。免责声明:我是维护者。
$ genversion lib/version.js
我承认客户端安全不是 OP 的主要意图,但正如 Mark Wallace 和 aug 的回答中所讨论的,它高度相关,也是我找到此问答的原因。
还有另一种从 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
是什么?
module
不是这个特定的示例变量;它是一个代表 node.js 中当前模块的变量。您可以在此处阅读有关 node.js 模块的更多信息:nodejs.org/api/modules.html#modules_the_module_object
选项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
。
node index.js
运行我的代码。如何通过 npm 运行 "bin": "my-bin.js"
?
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
)。
只是添加一个答案,因为我来这个问题是为了查看将 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
您可以使用 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}`);
要确定节点代码中的包版本,可以使用以下命令:
常量版本 = 要求('./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。
如果您正在寻找 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。
一个安全的选择是添加一个生成单独版本文件的 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" }
您可以使用 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 由于某种原因丢失。
为什么不使用 require 解析...
const packageJson = path.dirname(require.resolve('package-name')) + '/package.json';
const { version } = require(packageJson);
console.log('version', version)
使用这种方法适用于所有子路径:)
如果您想获取目标包的版本。
import { version } from 'TARGET_PACKAGE/package.json';
例子:
import { version } from 'react/package.json';
我知道这不是 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 因为它是最小的。
我使用 findup-sync
执行此操作:
var findup = require('findup-sync');
var packagejson = require(findup('package.json'));
console.log(packagejson.version); // => '0.0.1'
package.json
,类似于 process.env.npm_package_version
,除了不需要通过 npm 启动它。因此,尝试获取您的库版本实际上会获取调用者的版本。一个简单的 require('./package.json') 可以避免这种情况。
我发现的最精简的方式:
const { version } = JSON.parse(fs.readFileSync('./package.json'))
const { 版本 } = require("./package.json");控制台.log(版本); const v = require("./package.json").version;控制台.log(v);
我正在使用 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 中第一次使用该密钥,否则您将得到错误的版本
我实际上已经通过了这里的大多数解决方案,它们要么不能在 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",
它会在每个 start
或 build
上创建一个新的 src/versions.js
。当然,这可以很容易地在 version
脚本中调整为不同的位置,或者在 make_version.js
文件中输出不同的语法和常量名称等。
我做了一个有用的代码来获取父模块的 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
}
如果使用汇总,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
将您的 package.json
文件导入您的 server.js
或 app.js
,然后将 package.json 属性访问到服务器文件中。
var package = require('./package.json');
package 变量包含 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)
}
}
require('root-require')('package.json').version
Error: Cannot find module 'package.json'
。