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 写法
// 方式一:JSON import(使用支持 import attributes 的 Node.js 版本)
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);
常见坑
- 路径是相对当前文件的:
src/utils/version.js里要require('../../package.json'); - 打包后路径漂移:esbuild/webpack 打包后目录结构变了,硬编码相对路径会找不到。方案:构建时把版本注入为常量(如 esbuild 的
define),或把 package.json 一并复制到产物目录; - Docker 镜像里没有 package.json:多阶段构建只拷 dist 时记得
COPY package.json; - TypeScript:需要
resolveJsonModule: true才能 import JSON。
更优雅的方案:构建时注入
版本号是构建期就已知的常量,注入比运行时读文件更稳:
// esbuild 示例:--define:APP_VERSION='"1.0.0"'
console.log(APP_VERSION);
或 npm scripts 里 APP_VERSION=$npm_package_version node app.js,代码读 process.env.APP_VERSION。
常见问题(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 有缓存,只在首次读取。