Node.js 代码中如何读取 package.json 的版本号?

代码里读版本号最直接的方式是 require('./package.json').version;ES Module 使用支持的 import attributes 语法,或读文件解析。注意打包与部署时 package.json 的路径问题。本文给出 CJS/ESM 两种写法。

最佳实践
文件、模块与依赖组织示意

CommonJS 一行搞定:

const packageInfo = require('./package.json');
console.log(packageInfo.version);   // 1.0.0

Node 的 require 原生支持 JSON 文件,路径按调用文件的位置写相对路径。

ES Module 写法

// with 属性语法起于 Node 18.20/20.10/21;JSON 模块在 20.18.3/22.12/23.1 等版本线退出实验
import pkg from './package.json' with { type: 'json' };
console.log(pkg.version);

// 方式二:手动读文件(兼容性最好)
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import path from 'path';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const pkg2 = JSON.parse(readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
console.log(pkg2.version);

常见坑

  1. 路径是相对当前文件的:src/utils/version.js 里要 require('../../package.json');
  2. 打包后路径漂移:esbuild/webpack 打包后目录结构变了,硬编码相对路径会找不到。方案:构建时把版本注入为常量(如 esbuild 的 define),或把 package.json 一并复制到产物目录;
  3. Docker 镜像里没有 package.json:多阶段构建只拷 dist 时记得 COPY package.json;
  4. TypeScript:类型检查/编译通常需要 resolveJsonModule;这不保证输出代码在所用 Node 模块模式/版本中可执行,仍需核对运行时 JSON import 属性。

更优雅的方案:构建时注入

版本号是构建期就已知的常量,注入比运行时读文件更稳:

// esbuild 示例:--define:APP_VERSION='"1.0.0"'
console.log(APP_VERSION);

POSIX shell 的 npm script 可写 APP_VERSION=$npm_package_version node app.js,代码读 process.env.APP_VERSION;该 npm 变量由 npm script 环境提供,直接 node 启动不保证有,Windows cmd 的赋值语法也不同。

常见问题(FAQ)

Q:读自己包的版本和读依赖包的版本一样吗?
读依赖包版本:require('lodash/package.json').version——前提是该包没有把 package.json 排除在 exports 之外。

Q:只想在 --version 参数时输出版本?
CLI 工具用 commander/yargs 自带版本功能;手写就是 if (process.argv.includes('--version')) console.log(version)。

Q:require JSON 会不会每次读磁盘?
不会,require 有缓存,只在首次读取。

参考资料

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台