มีวิธีรับเวอร์ชันจาก package.json ในรหัส nodejs หรือไม่


586

มีวิธีรับเวอร์ชันที่ติดตั้งใน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

จำเป็นหรือไม่ที่จะต้องรับเวอร์ชันของ Node หรือรุ่นที่ประกาศใน package.json หากแบบฟอร์มนี้จะให้รุ่นที่ใช้งานอยู่:console.log(process.version)
Adrian Lynch

คำตอบ:


957

ฉันพบว่าส่วนรหัสต่อไปนี้ทำงานได้ดีที่สุดสำหรับฉัน เนื่องจากมันใช้requireในการโหลดpackage.jsonมันทำงานโดยไม่คำนึงถึงไดเรกทอรีการทำงานปัจจุบัน

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

คำเตือนความอนุเคราะห์จาก @Pathogen:

การทำสิ่งนี้กับ Browserify มีผลกระทบด้านความปลอดภัย
ระวังอย่าให้package.jsonลูกค้าของคุณเปิดเผยเพราะหมายถึงว่าหมายเลขเวอร์ชันการพึ่งพาทั้งหมดคำสั่ง build และทดสอบและอื่น ๆ ของคุณจะถูกส่งไปยังไคลเอนต์
หากคุณกำลังสร้างเซิร์ฟเวอร์และไคลเอนต์ในโครงการเดียวกันคุณจะเปิดเผยหมายเลขเวอร์ชั่นฝั่งเซิร์ฟเวอร์ด้วย ผู้โจมตีสามารถใช้ข้อมูลเฉพาะดังกล่าวเพื่อให้เหมาะกับการโจมตีบนเซิร์ฟเวอร์ของคุณ


25
หากคุณยังคงถูกไฟไหม้โดยพยายามที่จะคว้าสิ่งนี้จากสถานที่ต่าง ๆ (เหมือนเดิม) คุณสามารถทำได้require('root-require')('package.json').version
mikermcneil

5
ไม่ทำงานกับสคริปต์ของฉันเมื่อติดตั้ง shebang ทั่วโลก Error: Cannot find module 'package.json'.
exebook

14
สั้นกว่า - ต้องใช้ ('./ แพ็คเกจ') เวอร์ชัน
Afanasii Kurakin

60
คำเตือน! การทำสิ่งนี้กับเบราว์เซอร์มีผลกระทบด้านความปลอดภัย: package.json ในบันเดิลของคุณหมายความว่าหมายเลขเวอร์ชันการพึ่งพาทั้งหมดของคุณคำสั่งการสร้างและทดสอบและอื่น ๆ จะถูกส่งไปยังไคลเอนต์ หากคุณกำลังสร้างเซิร์ฟเวอร์และไคลเอนต์ในโครงการเดียวกันคุณจะเปิดเผยหมายเลขเวอร์ชันเซิร์ฟเวอร์ของคุณด้วย
Pathogen

4
@Pathogen genversionแก้ปัญหาด้านลูกค้า เป็นเครื่องมือที่อ่านเวอร์ชันจาก package.json และสร้างโมดูลที่สามารถอิมพอร์ตได้ ข้อจำกัดความรับผิดชอบ: ฉันเป็นผู้ดูแล
Akseli Palén

348

หากแอปพลิเคชันของคุณเปิดใช้งานด้วย 'เริ่มต้น npm' คุณสามารถใช้:

process.env.npm_package_version

ดูpackage.json varsสำหรับรายละเอียดเพิ่มเติม


6
นี่อาจเป็นคำตอบที่ดีที่สุดเนื่องจากข้อมูลส่วนใหญ่ใน package.json เชื่อมต่อกับตัวแปรรันไทม์ของกระบวนการ
Alexander Mills

2
ใช่ฉันเห็นด้วย นี่ควรเป็นคำตอบที่ถูกต้องโดยใช้ตัวแปรกระบวนการที่คุณไม่จำเป็นต้องเปิดและอ่านไฟล์ package.json อีกครั้ง
Juanma

12
และภายนอกของโหนด (เช่นเชลล์สคริปต์ดำเนินการผ่านทางnpm run …) $npm_package_versionเวอร์ชั่นจะอยู่ในตัวแปรสภาพแวดล้อม
Quinn Comendant

12
เมื่อเรียกจากสคริปต์ของแพ็คเกจอื่นสิ่งนี้จะรายงานเวอร์ชันของแพคเกจการโทรที่ไม่ถูกต้องและไม่ใช่แพ็คเกจที่เรียกใช้
jjrv

6
มันทำงานได้ภายในอิเล็กตรอนแอปเริ่มต้นด้วยnpm startแต่ไม่ได้อยู่ในแอพพลิเคอิเล็กตรอนที่สร้าง: app.getVersionการที่คุณสามารถหาได้ใน
ChrisV

158

การใช้โมดูล ES6 คุณสามารถทำสิ่งต่อไปนี้:

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

2
ฉันคิดว่าสิ่งเหล่านี้ไม่ได้รับการสนับสนุนในโหนด: github.com/nodejs/help/issues/53
ripper234

1
ยังไม่มีโมดูล es6 ที่ยังไม่ได้รับการสนับสนุนโดยตรง แต่ใช้กันโดยทั่วไปเปิดใช้งานโดยใช้ Babel
Patrick Lee Scott

4
@Sornii ไม่ package.json ทั้งหมดจะอยู่ในไคลเอนต์ ฉันใช้ definePlugin ของ webpack เพื่อส่งผ่านเฉพาะข้อมูลที่เลือกจากสภาวะแวดล้อมโหนดไปยังเบราว์เซอร์
doeke

2
ความเกี่ยวข้องด้านความปลอดภัยเช่นเดียวกับที่ระบุไว้ในstackoverflow.com/a/10855054/540144 ?
itsazzad

1
ใช่ปัญหาความปลอดภัยเดียวกัน package.json ทั้งหมดจะรวมอยู่ในชุดไคลเอนต์
Neromancer

94

หรือในเปลือกเก่าธรรมดา:

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

สิ่งนี้สามารถย่อให้เล็กลงได้

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

แม้ว่านี่จะไม่ใช่คำถามที่ถามมา แต่ก็มีประโยชน์หากคุณต้องการใช้เวอร์ชันภายใน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",
  ...
}

แต่นั่นไม่ได้อยู่ในแอพ nodeJS เองตามที่ร้องขอ
Steve Bennett

1
@SteveBennett ไม่ แต่มันก็ช่วย 90 คนบวกกับฉัน
K - ความเป็นพิษใน SO กำลังเพิ่มขึ้น

1
อาจจะมากไปกว่านั้น
Steve Bennett

61

มีสองวิธีในการดึงข้อมูลเวอร์ชัน:

  1. ต้องการpackage.jsonและรับรุ่น:
const { version } = require('./package.json');
  1. การใช้ตัวแปรสภาพแวดล้อม:
const version = process.env.npm_package_version;

กรุณาอย่าใช้JSON.parse, fs.readFile, fs.readFileSyncและไม่ได้ใช้อีกnpm modulesก็ไม่จำเป็นสำหรับคำถามนี้


2
ขอขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือแบบ จำกัด และทันที คำอธิบายที่เหมาะสมมากจะเพิ่มมูลค่าในระยะยาวด้วยการแสดงเหตุผลนี้เป็นทางออกที่ดีในการแก้ไขปัญหาและจะทำให้มันมีประโยชน์มากขึ้นให้กับผู้อ่านในอนาคตกับอื่น ๆ คำถามที่คล้ายกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายรวมถึงข้อสมมติฐานที่คุณทำ
milo526

8
แล้วnpm_*ค่าสภาพแวดล้อมที่มีอยู่เฉพาะในกรณีที่สคริปต์ของคุณเริ่มต้นจาก NPM npm startเช่น หากคุณกำลังทำnode app.jsหรือคล้ายกันพวกเขาจะไม่ปรากฏ
เนท

@Nate ดังนั้นจึงเป็นการดีที่จะใช้รุ่นจากpackage.json?
ฟิลิปŠ

37

นี่คือวิธีอ่านเวอร์ชันจาก package.json:

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

ฉันเคยเห็นสิ่งนี้เป็นพวงและฉันชอบมัน - คุณ / ใครรู้การพิจารณาที่require() introduces? (for instance, does ต้องใช้ () `ไม่สนับสนุนการอ่าน utf8? ตามที่ตัวอย่างของคุณอาจแนะนำ)
electblake

4
require()แคชไฟล์ซึ่งในกรณีนี้ไม่ควรสร้างความแตกต่าง
jlee

@jlee มีเหตุผลที่คนทั่วไปทำJSON.parse(fs.readFileSync('package.json', 'utf8'))แทนdelete require.cache[require.resolve('package.json')]; require('package.json')เมื่อพวกเขาต้องการที่จะโหลด?
Mihail Malostanidis

const {version} = ต้องการ ('./ package.json');
dykyіаlex

23

มีวิธีการดึงข้อมูลบางอย่างจาก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จะอยู่ที่ไหน

ฉันหวังว่าจะช่วย


1
ที่moduleนี่คืออะไร
chovy

@chovy moduleไม่ใช่ตัวแปรตัวอย่างนี้โดยเฉพาะ มันเป็นตัวแปรที่แสดงถึงโมดูลปัจจุบันใน node.js คุณสามารถอ่านเพิ่มเติมเกี่ยวกับโมดูล node.js ได้ที่นี่: nodejs.org/api/modules.html#modules_the_module_object
Tom

2
ฉันกำลังพยายามรับรุ่นของโมดูลอื่นที่โมดูลของฉันต้องการ ... และฉันก็พบว่ายากหาก pkginfo ทำให้สิ่งนี้เป็นไปได้
ไมเคิล

23

สำหรับผู้ที่มองหาที่ปลอดภัยฝั่งไคลเอ็นต์การแก้ปัญหาที่ยังทำงานบนฝั่งเซิร์ฟเวอร์มีgenversion เป็นเครื่องมือบรรทัดคำสั่งที่อ่านเวอร์ชันจาก package.json ที่ใกล้ที่สุดและสร้างไฟล์โมดูล CommonJS ที่สามารถอิมพอร์ตได้ซึ่งส่งออกเวอร์ชัน ข้อจำกัดความรับผิดชอบ: ฉันเป็นผู้ดูแล

$ genversion lib/version.js

ฉันรับทราบความปลอดภัยของลูกค้าไม่ใช่ความตั้งใจหลักของ OP แต่ตามที่กล่าวไว้ในคำตอบโดยMark Wallaceและaugมันมีความเกี่ยวข้องสูงและเป็นเหตุผลที่ฉันพบคำถามและคำตอบนี้


4
นี่คือคำตอบและมันต้องการคะแนนเสียงมากกว่าเพื่อที่จะได้คำตอบที่เป็นปัญหาอย่างยิ่งในตอนนี้
เจฟฟ์อัลเลน

1
บางคนอาจตกใจเมื่อเห็นว่านี่เป็นเครื่องมือบรรทัดคำสั่ง ไม่ต้องกังวล! readme ของเครื่องมืออธิบายวิธีการ (อย่างง่ายดาย) รวมการเรียกใช้ build on เข้ากับ package.json เพื่อให้คุณสามารถลืมเกี่ยวกับการมีอยู่ของเครื่องมือและจะมีหมายเลขเวอร์ชันล่าสุดเสมอ
malamut

11

เพียงเพิ่มคำตอบเพราะฉันมาที่คำถามนี้เพื่อดูวิธีที่ดีที่สุดในการรวมเวอร์ชันจาก package.json ในเว็บแอปพลิเคชันของฉัน

ฉันรู้ว่าคำถามนี้ถูกตั้งเป้าหมายไว้สำหรับ Node.js แต่ถ้าคุณใช้ Webpack เพื่อรวมแอปของคุณเพียงแค่เตือนความจำวิธีที่แนะนำคือการใช้ DefinePluginเพื่อประกาศเวอร์ชันทั่วโลกในการกำหนดค่าและการอ้างอิงว่า ดังนั้นคุณสามารถทำในของคุณwebpack.config.json

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

...

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

และAppVersionตอนนี้ก็คือโกลบอลที่คุณสามารถใช้ได้ ตรวจสอบให้แน่ใจในตัวคุณ.eslintrcว่าคุณไม่สนใจสิ่งนี้ผ่านทางเสากลม


8

ตัวเลือกที่ 1

แนวปฏิบัติที่เหมาะสมที่สุดคือเวอร์ชันจาก package.json โดยใช้ตัวแปรสภาวะแวดล้อม npm

process.env.npm_package_version

ข้อมูลเพิ่มเติมเกี่ยวกับ: https://docs.npmjs.com/using-npm/config.html

สิ่งนี้จะทำงานเมื่อคุณเริ่มบริการของคุณโดยใช้คำสั่ง NPM

ข้อมูลด่วน: คุณสามารถอ่านค่าใด ๆ ใน pacakge.json โดยใช้ process.env.npm_package_ [keyname]

ตัวเลือก 2

การตั้งค่าเวอร์ชันในตัวแปรสภาพแวดล้อมโดยใช้https://www.npmjs.com/package/dotenvเป็น.envไฟล์และเกี่ยวข้องกับมันprocess.env.version


7

คุณสามารถใช้ 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}`);

3
สิ่งนี้ทำงานได้ตราบใดที่คุณตั้งค่า "resolJsonModule" เป็น "true" ใน tsconfig.json
รัสเซลฟิลลิปส์

6

หากต้องการพิจารณาเวอร์ชันแพ็กเกจในโค้ดโหนดคุณสามารถใช้สิ่งต่อไปนี้:

  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-need, pkginfo, project-version


4

คุณสามารถใช้แพ็คเกจรุ่นโครงการได้

$ 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
Mihail Malostanidis

1

ฉันทำสิ่งนี้กับfindup-sync:

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

การค้นหาเริ่มต้นด้วย cwd ดังนั้นในกรณีส่วนใหญ่มันจะได้รับระดับสูงสุดpackage.jsonคล้ายกับprocess.env.npm_package_versionนอกเหนือจากที่ไม่ต้องการให้เริ่มต้นผ่านทาง npm ดังนั้นการลองเอารุ่นไลบรารี่ของคุณจะได้เวอร์ชั่นของผู้โทร ความต้องการอย่างง่าย ('./ package.json') จะหลีกเลี่ยงปัญหานี้
Mihail Malostanidis

1

ฉันรู้ว่านี่ไม่ใช่เจตนาของ OP แต่ฉันต้องทำเช่นนี้ดังนั้นหวังว่าจะช่วยคนต่อไป

หากคุณใช้นักเทียบท่าสำหรับกระบวนการ CI / CD ของคุณคุณจะได้รับสิ่งนี้!

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', '')\""

สำหรับอิมเมจคุณสามารถใช้อิมเมจโหนดใดก็ได้ ฉันใช้อัลไพน์เพราะมันเล็กที่สุด


1

ทำไมไม่ใช้การแก้ไขที่ต้องการ ...

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

ด้วยวิธีการนี้จะทำงานสำหรับเส้นทางย่อยทั้งหมด :)


0

อิมพอร์ตpackage.jsonไฟล์ของคุณไปยังserver.jsหรือapp.jsจากนั้นเข้าถึงคุณสมบัติ package.json ไปยังไฟล์เซิร์ฟเวอร์

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

ตัวแปรแพคเกจประกอบด้วยข้อมูลทั้งหมดใน package.json


0

ฉันสร้างโค้ดที่มีประโยชน์เพื่อรับ 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
}

0

หากใช้การยกเลิก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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.