Cách đặt các biến môi trường từ trong gói.json


313

Làm cách nào để đặt một số biến môi trường từ bên trong package.jsonđược sử dụng với npm startcác lệnh like?

Đây là những gì tôi hiện có trong package.json:

{
  ...
  "scripts": {
    "help": "tagove help",
    "start": "tagove start"
  }
  ...
}

Tôi muốn đặt các biến môi trường (như NODE_ENV) trong tập lệnh bắt đầu trong khi vẫn có thể khởi động ứng dụng chỉ bằng một lệnh , npm start.


Bạn có thể đọc câu trả lời này stackoverflow.com/a/57509175/11127383
Daniel Danielecki

Câu trả lời:


434

Đặt biến môi trường trong lệnh script:

...
"scripts": {
  "start": "node app.js",
  "test": "env NODE_ENV=test mocha --reporter spec"
},
...

Sau đó sử dụng process.env.NODE_ENVtrong ứng dụng của bạn.

Lưu ý: envđảm bảo rằng nó hoạt động trên các nền tảng. Bạn có thể bỏ qua nó nếu bạn chỉ quan tâm đến Mac / Linux.


65
Có ai đó đã tìm ra một sự thay thế cho các cửa sổ ..?
vô cùng

65
@infinity sử dụng cross-env và rất dễ sử dụng.
mikekidder

106
@infinity sử dụng set NODE_ENV=test&& mocha --reporter spec- không có khoảng cách giữa thử nghiệm và && về mục đích.
Jamie Penney

18
"test": "NODE_ENV=test mocha --reporter spec"sẽ không hoạt động trên các hệ thống Windows.
Benny Neugebauer

7
@infinity @ jamie-penney env NODE_ENV=test mocha --reporter specsẽ sử dụng biến môi trường được khai báo theo kiểu đa nền tảng, nhưng điều quan trọng là nó được sử dụng bởi npm theo kiểu ad hoc và một lần, chỉ để thực thi tập lệnh npm. (Nó không được đặt hoặc xuất để tham khảo trong tương lai.) Miễn là bạn đang chạy lệnh của mình từ tập lệnh npm, không có vấn đề gì. Ngoài ra, "&&" phải được xóa khi thực hiện theo cách này.
estaples

219

Chỉ cần sử dụng gói NPM chéo-env . Siêu dễ. Hoạt động trên Windows, Linux và tất cả các môi trường. Lưu ý rằng bạn không sử dụng && để chuyển sang tác vụ tiếp theo. Bạn chỉ cần đặt env và sau đó bắt đầu nhiệm vụ tiếp theo. Tín dụng cho @mikekidder cho đề xuất trong một trong những ý kiến ở đây.

Từ tài liệu:

{
  "scripts": {
    "build": "cross-env NODE_ENV=production OTHERFLAG=myValue webpack --config build/webpack.config.js"
  }
}

Lưu ý rằng nếu bạn muốn thiết lập nhiều vars toàn cầu, bạn chỉ cần nêu chúng liên tiếp, theo sau là lệnh của bạn sẽ được thực thi.

Cuối cùng, lệnh được thực thi (sử dụng sinh sản) là:

webpack --config build/webpack.config.js

Biến NODE_ENVmôi trường sẽ được đặt bởi cross-env


Ba dấu gạch chéo ngược có thể được sử dụng để thoát các trích dẫn cần thiết:"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' mocha"
bvj

1
Giải pháp tốt nhất vì đa nền tảng.
bernardn

Ai đó cuối cùng có thể giúp tôi quyết định nếu tôi nên sử dụng envhay cross-env? Một mặt, env không yêu cầu tôi cài đặt bất cứ thứ gì và mặt khác cross-envlà phổ biến hơn. Ai đó có thể vui lòng xác nhận nếu envhoạt động trên tất cả các nền tảng?
Rishav

2
@Rishav envkhông hoạt động như trên tất cả các nền tảng, do đó lý do cross-envtồn tại. Chỉ cần sử dụng cross-envvà được thực hiện với nó.
TetraDev

38

Bởi vì tôi thường thấy mình làm việc với nhiều biến môi trường, tôi thấy hữu ích khi giữ chúng trong một .envtệp riêng biệt (đảm bảo bỏ qua điều này khỏi kiểm soát nguồn của bạn).

VAR_A=Hello World
VAR_B=format the .env file like this with new vars separated by a line break

Sau đó, chuẩn bị export $(cat .env | xargs) &&trước lệnh script của bạn.

Thí dụ:

{
  ...
  "scripts": {
    ...
    "start": "export $(cat .env | xargs) && echo do your thing here",
    "env": "export $(cat .env | xargs) && env",
    "env-windows": "export $(cat .env | xargs) && set"
  }
  ...
}

Để kiểm tra, bạn có thể xem các biến env bằng cách chạy npm run env(linux) hoặc npm run env-windows(windows).


1
Rất tốt, nó gần như đã làm công việc cho tôi! Tôi muốn thêm một vài nhận xét: - Bạn không thể có dòng trống trong tệp .env của mình - Nhận xét trong tệp .env của bạn sẽ phá vỡ tập lệnh của bạn - Nếu nhiều tập lệnh sử dụng cùng một tệp .env, bạn sẽ phải lặp lại điều đó - Tôi đã phải xóa dung lượng trước &&để nó hoạt động - Nếu bạn có nhiều tệp .env, có thể khó hơn một chút để duy trì câu trả lời của bạn đã truyền cảm hứng cho tôi để chuẩn bị đề xuất này: stackoverflow.com/questions/25112510/
Felipe N Moura

37

Tôi chỉ muốn thêm hai xu của mình ở đây cho các nhà thám hiểm Node trong tương lai. Trên Ubuntu 14.04 của tôi NODE_ENV=testkhông hoạt động, tôi đã phải sử dụng export NODE_ENV=testsau đó NODE_ENV=testbắt đầu hoạt động quá kỳ lạ.

Trên Windows như đã nói bạn phải sử dụng set NODE_ENV=testnhưng đối với giải pháp đa nền tảng, thư viện cross-env dường như không thực hiện được mánh khóe và bạn có thực sự cần một thư viện để làm việc này không:

export NODE_ENV=test || set NODE_ENV=test&& yadda yadda

Các thanh dọc là cần thiết vì nếu không Windows sẽ gặp sự cố với export NODE_ENVlệnh không được nhận dạng : D. Dunno về không gian dấu nhưng chỉ để chắc chắn tôi cũng loại bỏ chúng.


6
Bạn đã sử dụng &&? NODE_ENV=test yaddacó nghĩa là "chạy yadda, thiết lập NODE_ENVtrong yaddacác biến môi trường. NODE_ENV=test && yaddacó nghĩa là" được đặt NODE_ENVtrong môi trường cục bộ, nhưng không xuất nó, sau đó chạy yadda. " NODE_ENV=test yaddalà cách tiếp cận ưa thích.
Josh Kelley

Xin lỗi đã không kiểm tra tài khoản stackoverflow của tôi trong một thời gian. Nhưng về cơ bản, Windows ngớ ngẩn không hoạt động bằng cách sử dụng NODE_ENV=test && npm run testhoặc một cái gì đó tương tự. Tôi đã thực hiện một giải pháp tốt hơn bằng cách sử dụng process.env["NODE_ENV"] = "testing";bên trong tệp testrcper.js của mình.
TeemuK

5
@TeemuK chỉ để thêm hai xu của tôi, khi bạn chạy lệnh với &&bạn bị mất các biến môi trường, thiết lập các biến môi trường mà không xuất chỉ hoạt động trên lệnh hiện tại (không có gì). để chạy lệnh với biến env mà không xuất u làm : NODE_ENV=test npm run test. Cuối cùng, lý do nó hoạt động sau khi bạn xuất, là vì biến ur hiện có sẵn (đã xuất) trong phiên, NODE_ENV của bạn mà không xuất không làm gì cả.
Tarek

19

Hãy thử điều này trên Windows bằng cách thay thế YOURENV :

  {
    ...
     "scripts": {
       "help": "set NODE_ENV=YOURENV && tagove help",
       "start": "set NODE_ENV=YOURENV && tagove start"
     }
    ...
  }

1
Đúng! Cảm ơn bạn! Đây là câu trả lời tôi đang tìm kiếm! : D
Daniel Tonon

6
Tôi đã phải xóa khoảng trắng trước &&.
Kenneth Solberg

Nhận xét của @ KennethSolberg là liên lạc cuối cùng giúp nó hoạt động với tôi (chỉ dành cho Windows)
ulu

Tôi cũng có vấn đề không gian. Khi đăng nhập chiều dài chuỗi tôi có thể nói không gian được thêm vào. Tôi đã thử thoát dấu ngoặc kép - và chúng thực sự được lưu trữ trong envar. Tôi đã thử các dấu phân cách khác nhưng không có kết quả. Xóa bỏ không gian hoặc cắt xén giá trị, điều mà tôi cảm thấy sai, là cách duy nhất xoay quanh vấn đề này.
Neil Guy Lindberg

8

đột nhiên tôi thấy rằng Actionhero đang sử dụng đoạn mã sau, điều đó đã giải quyết vấn đề của tôi bằng cách chuyển qua --NODE_ENV=productiontùy chọn lệnh start script.

if(argv['NODE_ENV'] != null){
  api.env = argv['NODE_ENV'];
} else if(process.env.NODE_ENV != null){
  api.env = process.env.NODE_ENV;
}

Tôi thực sự đánh giá cao việc chấp nhận câu trả lời của người khác, người biết cách tốt hơn để đặt các biến môi trường trong gói.j.j hoặc init script hoặc đại loại như, nơi ứng dụng được người khác khởi động.


4

Đối với một tập hợp các biến môi trường lớn hơn hoặc khi bạn muốn sử dụng lại chúng, bạn có thể sử dụng env-cmd .

./.env tập tin:

# This is a comment
ENV1=THANKS
ENV2=FOR ALL
ENV3=THE FISH

./package.json:

{
  "scripts": {
    "test": "env-cmd mocha -R spec"
  }
}

Làm thế nào để bạn sử dụng ENV1 trong kịch bản?
ValRob

Thông thườngprocess.env.ENV1
KARASZI István

nhưng, bên trong gói.json? tôi đã đọc được điều đó là không thể (?)
ValRob 16/12/19

Tôi không hiểu Tại sao bạn lại làm vậy?
KARASZI István

có thể là một aproach ngớ ngẩn, nhưng tôi đã cập nhật macOs Catalina và bây giờ lệnh mongodb không hoạt động, vì vậy tôi cần chỉ định dữ liệu / thư mục mongod --dbpath ~/data/db . Tôi muốn chạy một cái gì đó như thế npm mongodbvà điều đó sẽ có được dbpath biến môi trường và chạy mondodb như mọi khi ... và .. tôi muốn chia sẻ nó với các thành viên khác.
ValRob

2

Mặc dù không trả lời trực tiếp câu hỏi tôi nhưng tôi muốn chia sẻ một ý tưởng trên đầu các câu trả lời khác. Từ những gì tôi nhận được, mỗi thứ này sẽ cung cấp một số mức độ phức tạp để đạt được sự độc lập đa nền tảng.

Trên kịch bản của tôi, tất cả những gì tôi muốn, ban đầu, để đặt một biến để kiểm soát việc có bảo mật máy chủ bằng xác thực JWT hay không (cho mục đích phát triển)

Sau khi đọc câu trả lời, tôi quyết định chỉ cần tạo 2 tệp khác nhau, với xác thực được bật và tắt tương ứng.

  "scripts": {
    "dev": "nodemon --debug  index_auth.js",
    "devna": "nodemon --debug  index_no_auth.js",
  }

Các tệp chỉ đơn giản là các trình bao bọc gọi tệp index.js gốc (mà tôi đã đổi tên thành appbootstrapper.js):

//index_no_auth.js authentication turned off
const bootstrapper = require('./appbootstrapper');
bootstrapper(false);

//index_auth.js authentication turned on
const bootstrapper = require('./appbootstrapper');
bootstrapper(true);

class AppBootStrapper {

    init(useauth) {
        //real initialization
    }
}

Có lẽ điều này có thể giúp đỡ người khác


2
{
  ...
  "scripts": {
    "start": "ENV NODE_ENV=production someapp --options"
  }
  ...
}

2

Điều này sẽ hoạt động trong bảng điều khiển Windows :

"scripts": {
  "aaa": "set TMP=test && npm run bbb",
  "bbb": "echo %TMP%"
}

npm run aaa

đầu ra: test

Xem câu trả lời này để biết chi tiết.


5
Nên set TMP=test&& npm run bbb. Không gian trước &&đó cũng sẽ là một phần của NODE_ENVchuỗi sau đó
FisNaN

@FisNaN Không nên là trường hợp nếu bạn bao quanh nó với dấu ngoặc kép ".
kaiser

1

Bạn không nên đặt biến ENV trong package.json. Actionhero sử dụng NODE_ENVđể cho phép bạn thay đổi các tùy chọn cấu hình được tải từ các tệp trong ./config. Kiểm tra tập tin cấu hình redis và xem NODE_ENV được sử dụng như thế nào để thay đổi các tùy chọn cơ sở dữ liệu trongNODE_ENV=test

Nếu bạn muốn sử dụng các biến ENV khác để đặt mọi thứ (có lẽ là cổng HTTP), bạn vẫn không cần thay đổi bất cứ điều gì package.json. Ví dụ: nếu bạn đặt PORT=1234trong ENV và muốn sử dụng cổng đó làm cổng HTTP NODE_ENV=production, chỉ cần tham chiếu trong tệp cấu hình có liên quan, IE:

# in config/servers/web.js
exports.production = { 
  servers: {
    web: function(api){
      return {
       port: process.env.PORT
      }
    }
  }
}

tuyệt quá. Tôi nghĩ rằng bạn đã không đọc câu hỏi của tôi .. vấn đề của tôi là làm thế nào để đặt NODE_ENV chứ không phải sử dụng nó.
dev.meghraj

1
Nếu bạn muốn đặt nhiều thuộc tính môi trường, bạn không thực hiện trong npm startlệnh. Sử dụng đoạn mã ở trên, nếu bạn muốn chạy máy chủ của mình bằng cổng ENV thì đó sẽ là : export PORT=1234; npm start. Bạn có thể nối thêm nhiều khai báo ENV khi bạn cần, nhưng chúng không thuộc về tệp pack.json. Nếu bạn lo lắng về việc đảm bảo chúng tồn tại, bạn nên sử dụng mặc định trong tệp cấu hình của mình : port: process.env.PORT || 8080.
Tony

1
Có lẽ một cách khác để giải thích điều này sẽ là NODE_ENV (và các biến môi trường khác) là một phần của môi trường (do đó là tên). Chúng thường là thuộc tính của máy chủ mà bạn đang chạy ứng dụng chứ không phải ứng dụng của bạn. Bạn có thể đặt chúng theo cách thủ công thông qua lệnh bạn thực thi, tức là: NODE_ENV=test npm starthoặc đặt chúng bằng shell
Evan

3
Tôi không đồng ý. sử dụng ./config cho mọi môi trường hạn chế bạn sử dụng các môi trường tĩnh khi bạn triển khai ứng dụng của mình. Đây là một triết lý lỗi thời sẽ không cho phép bạn tạo ra các loại môi trường mới khi cần thiết. IE cho mọi môi trường mới mà bạn muốn, bạn sẽ phải thêm .config. Đặt các biến môi trường trong thời gian chạy có thể là một lựa chọn ưu việt khi ngăn xếp công nghệ của bạn đòi hỏi sự linh hoạt hơn. Tôi nghĩ ./config của bạn sẽ tốt cho việc thiết lập "loại" môi trường, nhưng ứng dụng của bạn sẽ linh hoạt hơn nếu bạn có thể xác định những thứ như chuỗi DSn và điểm cuối api khi chạy.
Jesse Greathouse

@JesseGreathouse - Tôi có một ứng dụng node.js và tôi cần đặt các biến môi trường trong thời gian chạy - tôi sẽ đặt chúng vào tập tin nào?
Roger Dodger

1

npm (và sợi) chuyển rất nhiều dữ liệu từ pack.json vào các tập lệnh dưới dạng các biến môi trường. Sử dụng npm run envđể xem tất cả. Điều này được ghi lại trong https://docs.npmjs.com/misc/scripts#en môi trường và không chỉ dành cho các tập lệnh "vòng đời" như prepublishmà còn bất kỳ tập lệnh nào được thực thi bởinpm run .

Bạn có thể truy cập các mã bên trong này (ví dụ như process.env.npm_package_config_porttrong JS) nhưng chúng đã có sẵn cho trình bao chạy các tập lệnh để bạn cũng có thể truy cập chúng dưới dạng$npm_... mở rộng trong "tập lệnh" (cú pháp unix, có thể không hoạt động trên windows?).

Phần "cấu hình" dường như dành cho việc sử dụng này:

  "name": "myproject",
  ...
  "config": {
    "port": "8010"
  },
  "scripts": {
    "start": "node server.js $npm_package_config_port",
    "test": "wait-on http://localhost:$npm_package_config_port/ && node test.js http://localhost:$npm_package_config_port/"
  } 

Một chất lượng quan trọng của các trường "cấu hình" này là người dùng có thể ghi đè chúng mà không cần sửa đổi gói.json !

$ npm run start

> myproject@0.0.0 start /home/cben/mydir
> node server.js $npm_package_config_port

Serving on localhost:8010

$ npm config set myproject:port 8020
$ git diff package.json  # no change!
$ cat ~/.npmrc
myproject:port=8020

$ npm run start

> myproject@0.0.0 start /home/cben/mydir
> node server.js $npm_package_config_port

Serving on localhost:8020

Xem tài liệu cấu hình npmcấu hình sợi .
Nó xuất hiện sợi rằng nội dung đã ~/.npmrcđể npm config setảnh hưởng đến cả hai, nhưng yarn config setghi vào ~/.yarnrc, vì vậy chỉ sợi sẽ thấy nó :-(


1

Câu trả lời của @ luke gần như là câu tôi cần! Cảm ơn.

Vì câu trả lời được chọn rất đơn giản (và chính xác), nhưng cũ, tôi muốn đưa ra một cách thay thế để nhập biến từ tệp riêng biệt .env khi chạy tập lệnh của bạn và sửa một số hạn chế cho câu trả lời của Luke. Thử cái này:

::: tập tin .env :::

# This way, you CAN use comments in your .env files
NODE_PATH="src/"

# You can also have extra/empty lines in it
SASS_PATH="node_modules:src/styles"

Sau đó, trong gói json của bạn, bạn sẽ tạo một tập lệnh sẽ đặt các biến và chạy nó trước các tập lệnh bạn cần chúng:

::: pack.json :::

scripts: {
  "set-env": "export $(cat .env | grep \"^[^#;]\" |xargs)",
  "storybook": "npm run set-env && start-storybook -s public"
}

Một số quan sát:

  • Biểu thức chính quy trong lệnh mèo grep'ed sẽ xóa các bình luận và các dòng trống.

  • Các &&không cần phải "dán mắt" đến npm run set-env, vì nó sẽ được yêu cầu nếu bạn đã thiết lập các biến trong cùng một lệnh.

  • Nếu bạn đang sử dụng sợi, bạn có thể thấy một cảnh báo, bạn có thể thay đổi nó yarn set-envhoặc sử dụng npm run set-env --scripts-prepend-node-path &&thay thế.

Môi trường khác nhau

Một lợi thế khác khi sử dụng nó là bạn có thể có các biến môi trường khác nhau.

scripts: {
  "set-env:production": "export $(cat .production.env | grep \"^[^#;]\" |xargs)",
  "set-env:development": "export $(cat .env | grep \"^[^#;]\" |xargs)",
}

Xin vui lòng, đừng nhớ thêm các tệp .env vào kho git của bạn khi bạn có khóa, mật khẩu hoặc dữ liệu hợp lý / cá nhân trong đó!


1

sử dụng git bash trong windows. Git Bash xử lý các lệnh khác với cmd.

Hầu hết các lời nhắc lệnh của Windows sẽ bị nghẹt khi bạn đặt các biến môi trường với NODE_ENV = sản xuất như thế. (Ngoại lệ là Bash trên Windows, sử dụng Bash gốc.) Tương tự, có một sự khác biệt trong cách các cửa sổ và lệnh POSIX sử dụng các biến môi trường. Với POSIX, bạn sử dụng: $ ENV_VAR và trên các cửa sổ bạn sử dụng% ENV_VAR%. - tài liệu chéo

{
  ...
  "scripts": {
    "help": "tagove help",
    "start": "env NODE_ENV=production tagove start"
  }
  ...
}

sử dụng gói dotenv để khai báo các biến env

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.