Có cách nào để lấy phiên bản từ pack.json trong mã nodejs không?


586

Có cách nào để cài đặt phiên bản trong package.jsonứng dụng nodejs không? Tôi muốn một cái gì đó như thế này

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

Điều quan trọng hơn là lấy phiên bản của Node hoặc phiên bản được khai báo trong pack.json? Nếu là mẫu, điều này sẽ cung cấp cho bạn phiên bản đang chạy:console.log(process.version)
Adrian Lynch

Câu trả lời:


957

Tôi thấy rằng đoạn mã sau đây làm việc tốt nhất cho tôi. Vì nó sử dụng requiređể tải package.json, nó hoạt động bất kể thư mục làm việc hiện tại.

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

Một cảnh báo, lịch sự của @Pathogen:

Làm điều này với Browserify có ý nghĩa bảo mật.
Cẩn thận không để lộ của bạn package.jsoncho khách hàng, vì điều đó có nghĩa là tất cả các số phiên bản phụ thuộc của bạn, các lệnh xây dựng và kiểm tra và nhiều hơn nữa được gửi đến máy khách.
Nếu bạn đang xây dựng máy chủ và máy khách trong cùng một dự án, bạn cũng sẽ hiển thị số phiên bản phía máy chủ của mình. Dữ liệu cụ thể như vậy có thể được sử dụng bởi kẻ tấn công để phù hợp hơn với cuộc tấn công vào máy chủ của bạn.


25
nếu bạn tiếp tục bị bỏng bằng cách cố lấy thứ này từ những nơi khác nhau (như tôi), bạn có thể làmrequire('root-require')('package.json').version
mikermcneil

5
Không hoạt động cho tập lệnh của tôi với shebang được cài đặt trên toàn cầu. Error: Cannot find module 'package.json'.
exebook

14
ngắn hơn - yêu cầu ('./ gói'). phiên bản
Afanasii Kurakin

60
Cảnh báo! Làm điều này với browserify có ý nghĩa bảo mật: pack.json trong gói của bạn có nghĩa là tất cả các số phiên bản phụ thuộc, các lệnh xây dựng và kiểm tra và nhiều thứ khác được gửi đến máy khách. Nếu bạn đang xây dựng máy chủ và máy khách trong cùng một dự án, bạn cũng sẽ hiển thị số phiên bản máy chủ của mình.
Tác nhân gây bệnh

4
Chuyển đổi @Pathogen giải quyết vấn đề về phía khách hàng. Đây là một công cụ đọc phiên bản từ pack.json và tạo ra một mô-đun có thể nhập từ nó. Tuyên bố miễn trừ trách nhiệm: Tôi là người bảo trì.
Akseli Palén

349

Nếu ứng dụng của bạn được khởi chạy với 'npm start', bạn chỉ cần sử dụng:

process.env.npm_package_version

Xem vars pack.json để biết thêm chi tiết.


6
đây có lẽ là câu trả lời tốt nhất vì hầu hết các thông tin trong gói.json được đính kèm với biến thời gian chạy quy trình
Alexander Mills

2
Yeap, tôi đồng ý. Đây phải là câu trả lời đúng, sử dụng biến quy trình bạn không cần mở và đọc lại tệp pack.json.
Juanma

12
Và bên ngoài nút (ví dụ: shell script được thực thi thông qua npm run …) phiên bản sẽ nằm trong biến môi trường $npm_package_version.
Quinn Comendant

12
Khi được gọi từ các tập lệnh của gói khác, điều này báo cáo không chính xác phiên bản của gói gọi và không phải gói được gọi .
jjrv

6
Nó hoạt động trong một ứng dụng điện tử bắt đầu bằng npm start, nhưng không phải trong ứng dụng điện tử được xây dựng: vì điều đó, bạn có thể tìm thấy nó trong app.getVersion.
ChrisV

158

Sử dụng các mô-đun ES6, bạn có thể làm như sau:

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

2
Tôi nghĩ rằng những thứ này không được hỗ trợ trong nút: github.com/nodejs/help/issues/53
ripper234

1
Không có mô-đun es6 nào chưa được hỗ trợ trực tiếp nhưng thường được sử dụng, được bật bằng Babel
Patrick Lee Scott

4
@Sornii không, toàn bộ gói.json sẽ ở trong máy khách. Tôi đã từng definePlugin webpack để vượt qua thông tin chỉ được lựa chọn từ môi trường nút để trình duyệt.
doeke

2
Bất kỳ hàm ý bảo mật nào như được chỉ định trong stackoverflow.com/a/10855054/540144 ?
itazzad

1
Vâng, cùng một vấn đề bảo mật. Toàn bộ gói.json sẽ được bao gồm trong gói ứng dụng khách.
Neromancer

94

Hoặc trong vỏ cũ đơn giản:

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

Điều này có thể được rút ngắn để

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

Mặc dù đây không phải là chính xác những gì câu hỏi được hỏi, nhưng nó hữu ích nếu bạn muốn sử dụng phiên bản trong package.jsonchính nó, ví dụ để đăng nhập vào một tệp được phiên bản trong 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",
  ...
}

Điều đó không nằm trong chính ứng dụng nodeJS, như được yêu cầu.
Steve Bennett

1
@SteveBennett Không, nhưng nó đã giúp 90 người cộng với tôi.
K - Độc tính trong SO đang tăng lên.

1
Có lẽ nhiều hơn thế.
Steve Bennett

61

Có hai cách để lấy phiên bản:

  1. Yêu cầu package.jsonvà nhận phiên bản:
const { version } = require('./package.json');
  1. Sử dụng các biến môi trường:
const version = process.env.npm_package_version;

Xin đừng sử dụng JSON.parse, fs.readFile, fs.readFileSyncvà không sử dụng khác npm modulesđó là không cần thiết cho câu hỏi này.


2
Cảm ơn bạn vì đoạn mã này, có thể cung cấp một số trợ giúp hạn chế, ngay lập tức. Một lời giải thích phù hợp sẽ cải thiện đáng kể giá trị lâu dài của nó bằng cách chỉ ra lý do tại sao đây là một giải pháp tốt cho vấn đề và sẽ giúp nó hữu ích hơn cho những người đọc tương lai với những câu hỏi tương tự khác. Vui lòng chỉnh sửa câu trả lời của bạn để thêm một số giải thích, bao gồm các giả định bạn đã thực hiện.
milo526

8
Sau đó, npm_*giá trị môi trường chỉ khả dụng nếu tập lệnh của bạn được NPM khởi động, vd npm start. Nếu bạn đang làm node app.jshoặc tương tự, họ sẽ không có mặt.
Nate

@Nate Vì vậy, tốt hơn là sử dụng phiên bản từ package.json?
Filip

38

Đây là cách đọc phiên bản trong gói.json:

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

Tôi đã thấy điều này rất nhiều, và tôi rất thích nó - bạn / có ai biết những cân nhắc require() introduces? (for instance, does yêu cầu () `không hỗ trợ việc đọc utf8 không? như đoạn trích của bạn có thể đề xuất)
electblake

4
require()lưu trữ tập tin, trong trường hợp này sẽ không tạo ra sự khác biệt.
jlee

@jlee có lý do gì mọi người thường làm JSON.parse(fs.readFileSync('package.json', 'utf8'))thay vì delete require.cache[require.resolve('package.json')]; require('package.json')khi họ muốn tải lại?
Mihail Malostanidis

const {phiên bản} = Yêu cầu ('./ pack.json');
аlex dyky giác

23

Có một cách khác để tìm nạp thông tin nhất định từ package.jsontệp của bạn, đó là sử dụng mô-đun pkginfo .

Cách sử dụng mô-đun này rất đơn giản. Bạn có thể nhận được tất cả các biến gói bằng cách sử dụng:

require('pkginfo')(module);

Hoặc chỉ một số chi tiết nhất định ( versiontrong trường hợp này)

require('pkginfo')(module, 'version');

Và các biến gói của bạn sẽ được đặt thành module.exports(vì vậy số phiên bản sẽ có thể truy cập qua module.exports.version).

Bạn có thể sử dụng đoạn mã sau:

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

Mô-đun này có tính năng rất hay - nó có thể được sử dụng trong bất kỳ tệp nào trong dự án của bạn (ví dụ: trong các thư mục con) và nó sẽ tự động lấy thông tin từ bạn package.json. Vì vậy, bạn không phải lo lắng bạn package.jsonđang ở đâu .

Tôi hy vọng điều đó sẽ giúp.


1
cái gì moduleđây
nghẹn ngào

@chovy, moduleđây không phải là biến ví dụ cụ thể này; nó là một biến đại diện cho mô-đun hiện tại trong node.js. Bạn có thể đọc thêm về các mô-đun node.js tại đây: nodejs.org/api/modules.html#modules_the_module_object
Tom

2
Tôi đang cố gắng để có được phiên bản của các mô-đun khác theo yêu cầu của mô-đun của mình ... và tôi đang gặp khó khăn để tìm hiểu xem pkginfo có thể thực hiện được điều này không.
Michael

23

Đối với những người tìm kiếm một giải pháp phía khách hàng an toàn cũng hoạt động ở phía máy chủ, có sự chuyển đổi . Nó là một công cụ dòng lệnh đọc phiên bản từ gói.json gần nhất và tạo tệp mô-đun CommonJS có thể nhập được để xuất phiên bản. Tuyên bố miễn trừ trách nhiệm: Tôi là người bảo trì.

$ genversion lib/version.js

Tôi thừa nhận sự an toàn của phía khách hàng không phải là mục đích chính của OP, nhưng như được thảo luận trong câu trả lời của Mark Wallaceaug , nó rất phù hợp và cũng là lý do tôi tìm thấy câu hỏi và trả lời này.


4
Đây là câu trả lời, và nó cần nhiều phiếu hơn để vượt lên trên câu trả lời có vấn đề sâu sắc ngay từ đầu.
Jeff Allen

1
Một số người có thể bị báo động bởi thực tế rằng đây là một công cụ dòng lệnh. Đừng lo! Readme của công cụ mô tả cách (dễ dàng) tích hợp lệnh gọi xây dựng vào pack.json, để bạn có thể quên đi sự tồn tại của công cụ và luôn có số phiên bản gần đây nhất.
malamut

11

Chỉ cần thêm một câu trả lời vì tôi đã đến câu hỏi này để xem cách tốt nhất để đưa phiên bản từ gói.json vào ứng dụng web của tôi.

Tôi biết câu hỏi này được nhắm mục tiêu cho Node.js, tuy nhiên, nếu bạn đang sử dụng Webpack để đóng gói ứng dụng của mình, chỉ cần một lời nhắc là cách sử dụng DefinePlugin để khai báo phiên bản toàn cầu trong cấu hình và tham chiếu. Vì vậy, bạn có thể làm trongwebpack.config.json

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

...

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

AppVersionbây giờ là một toàn cầu có sẵn cho bạn sử dụng. Ngoài ra, hãy chắc chắn rằng .eslintrcbạn bỏ qua điều này thông qua prop toàn cầu


8

lựa chọn 1

Thực hành tốt nhất là phiên bản từ gói.json sử dụng các biến môi trường npm.

process.env.npm_package_version

thêm thông tin về: https://docs.npmjs.com/USE-npm/config.html

Điều này sẽ chỉ hoạt động khi bạn bắt đầu dịch vụ của mình bằng lệnh NPM.

Thông tin nhanh: bạn có thể đọc bất kỳ giá trị nào trong pacakge.json bằng process.env.npm_package_ [keyname]

Lựa chọn 2

Đặt phiên bản trong biến môi trường bằng cách sử dụng https://www.npmjs.com/package/dotenv dưới dạng .envtệp và liên quan đến nó trongprocess.env.version


7

Bạn có thể sử dụng ES6 để nhập gói.json để lấy số phiên bản và xuất phiên bản trên bảng điều khiển.

import {name as app_name, version as app_version}  from './path/to/package.json';

console.log(`App ---- ${app_name}\nVersion ---- ${app_version}`);

3
Điều này hoạt động miễn là bạn đặt "giải quyếtJsonModule" thành "true" trong tsconfig.json.
Russell Phillips

6

Để xác định phiên bản gói trong mã nút, bạn có thể sử dụng như sau:

  1. const version = require('./package.json').version; cho các phiên bản <ES6

  2. import {version} from './package.json'; cho phiên bản ES6

  3. const version = process.env.npm_package_version; nếu ứng dụng đã được bắt đầu sử dụng npm start, tất cả các biến môi trường npm_ * sẽ khả dụng.

  4. Bạn cũng có thể sử dụng các gói npm sau - root-request, pkginfo, dự án phiên bản.


4

Bạn có thể sử dụng gói phiên bản dự án .

$ npm install --save project-version

Sau đó

const version = require('project-version');

console.log(version);
//=>  '1.0.0'

Nó sử dụng process.env.npm_package_versionnhưng dự phòng trên phiên bản được viết package.jsontrong trường hợp var env bị thiếu vì một số lý do.


Ví dụ: nếu tệp js được bắt đầu không phải từ npm?
Mihail Malostanidis

2

Tại sao không sử dụng yêu cầu giải quyết ...

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

Với phương pháp này hoạt động cho tất cả các đường dẫn phụ :)


1

Tôi làm điều này với findup-sync:

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

Tìm kiếm bắt đầu với cwd, vì vậy trong hầu hết các trường hợp, nó sẽ chỉ đạt được cấp cao nhất package.json, tương tự như process.env.npm_package_versionbên cạnh việc không yêu cầu bắt đầu qua npm. Vì vậy, cố gắng để có được phiên bản thư viện của bạn sẽ thực sự có được phiên bản của người gọi. Một yêu cầu đơn giản ('./ pack.json') sẽ tránh điều này.
Mihail Malostanidis

1

Tôi biết đây không phải là ý định của OP, nhưng tôi chỉ phải làm điều này, vì vậy hy vọng nó sẽ giúp người tiếp theo.

Nếu bạn đang sử dụng docker-compose cho quy trình CI / CD của mình, bạn có thể lấy nó theo cách này!

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

Đối với hình ảnh, bạn có thể sử dụng bất kỳ hình ảnh nút. Tôi sử dụng alpine vì nó là nhỏ nhất.


0

Nhập package.jsontệp của bạn vào server.jshoặc app.jssau đó truy cập các thuộc tính của gói.json vào tệp máy chủ.

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

biến gói chứa tất cả dữ liệu trong pack.json.


0

Tôi đã tạo một mã hữu ích để lấy gói.j.j của mô đun mẹ

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

Nếu sử dụng rollup, rollup-plugin-replaceplugin có thể được sử dụng để thêm phiên bản mà không để lộ gói.json cho máy khách.

// 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
    }),
  ]
};

Sau đó, trong mã nguồn, bất cứ nơi nào bạn muốn có phiên bản pack.json, bạn sẽ sử dụng chuỗi 'MY_PACKAGE_JSON_VERSION'.

// src/index.js
export const packageVersion = 'MY_PACKAGE_JSON_VERSION' // replaced with actual version number in rollup.config.js
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.