Cara mengatur variabel lingkungan dari dalam package.json

313

Cara mengatur beberapa variabel lingkungan dari dalam package.jsonuntuk digunakannpm start perintah seperti?

Inilah yang saat ini saya miliki di package.json:

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

Saya ingin mengatur variabel lingkungan (seperti NODE_ENV) dalam skrip mulai sementara masih dapat memulai aplikasi hanya dengan satu perintah npm start,.

dev.meghraj
sumber
Anda dapat membaca jawaban ini stackoverflow.com/a/57509175/11127383
Daniel Danielecki

Jawaban:

434

Setel variabel lingkungan dalam perintah skrip:

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

Kemudian gunakan process.env.NODE_ENVdi aplikasi Anda.

Catatan: envmemastikan bahwa itu berfungsi lintas platform. Anda dapat menghilangkannya jika Anda hanya peduli dengan Mac / Linux.

cesar
sumber
65
Apakah ada yang menemukan alternatif untuk windows ..?
infinity
65
@ infinity menggunakan cross-env dan sangat mudah digunakan.
mikekidder
106
@infinity use set NODE_ENV=test&& mocha --reporter spec- tidak ada ruang antara tes dan && dengan sengaja.
Jamie Penney
18
"test": "NODE_ENV=test mocha --reporter spec"tidak akan berfungsi pada sistem Windows.
Benny Neugebauer
7
@infinity @ jamie-penney env NODE_ENV=test mocha --reporter specakan menggunakan variabel lingkungan yang dideklarasikan secara asli lintas platform, tetapi kuncinya adalah digunakan oleh npm dalam mode ad hoc dan sekali pakai, hanya untuk eksekusi skrip npm. (Ini tidak disetel atau diekspor untuk referensi di masa mendatang.) Selama Anda menjalankan perintah dari skrip npm, tidak ada masalah. Juga, "&&" harus dihapus ketika melakukannya dengan cara ini.
estaples
219

Cukup gunakan paket NPM lintas-env . Sangat mudah. Bekerja pada Windows, Linux, dan semua lingkungan. Perhatikan bahwa Anda tidak menggunakan && untuk pindah ke tugas berikutnya. Anda cukup mengatur env dan kemudian memulai tugas berikutnya. Kredit ke @mikekidder untuk saran di salah satu komentar sini.

Dari dokumentasi:

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

Perhatikan bahwa jika Anda ingin mengatur beberapa global vars, Anda cukup menyatakannya secara berurutan, diikuti dengan perintah Anda untuk dieksekusi.

Pada akhirnya, perintah yang dieksekusi (menggunakan spawn) adalah:

webpack --config build/webpack.config.js

The NODE_ENVvariabel lingkungan akan ditetapkan oleh lintas-env

TetraDev
sumber
Triple backslash dapat digunakan untuk menghindari tanda kutip yang diperlukan:"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' mocha"
bvj
1
Solusi terbaik karena lintas platform.
bernardn
Dapatkah seseorang akhirnya membantu saya memutuskan apakah saya harus menggunakan envatau cross-env? Di satu sisi, env tidak mengharuskan saya untuk menginstal apa pun dan di sisi lain cross-envlebih populer. Bisakah seseorang mengonfirmasi jika envberfungsi di semua platform?
Rishav
2
@Rishav envtidak berfungsi apa adanya di semua platform, karenanya alasan untuk cross-envada. Cukup gunakan cross-envdan lakukan saja.
TetraDev
38

Karena saya sering menemukan diri saya bekerja dengan beberapa variabel lingkungan, saya merasa berguna untuk menyimpannya dalam .envfile terpisah (pastikan untuk mengabaikan ini dari kontrol sumber Anda).

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

Kemudian letakkan di export $(cat .env | xargs) &&depan perintah skrip Anda.

Contoh:

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

Untuk tes Anda dapat melihat variabel env dengan menjalankan npm run env(linux) atau npm run env-windows(windows).

Luke
sumber
1
Sangat bagus, hampir berhasil untuk saya! Saya ingin menambahkan beberapa komentar: - Anda tidak dapat memiliki baris kosong di file .env Anda - Komentar dalam file .env Anda akan merusak skrip Anda - Jika beberapa skrip menggunakan file .env yang sama, Anda harus mengulanginya - Saya harus menghapus tempat sebelum &&berfungsi - Jika Anda memiliki banyak file .env, mungkin akan sedikit lebih sulit untuk mempertahankan Jawaban Anda mengilhami saya untuk menyiapkan saran ini: stackoverflow.com/questions/25112510/…
Felipe N Moura
37

Saya hanya ingin menambahkan dua sen saya di sini untuk penjelajah Node di masa depan. Di Ubuntu 14.04 NODE_ENV=testsaya tidak berfungsi, saya harus menggunakan export NODE_ENV=testsetelah itu NODE_ENV=testmulai bekerja juga, aneh.

Pada Windows seperti yang telah dikatakan Anda harus menggunakan set NODE_ENV=testtetapi untuk solusi lintas-platform perpustakaan cross-env tampaknya tidak melakukan trik dan apakah Anda benar-benar membutuhkan perpustakaan untuk melakukan ini:

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

Bilah vertikal diperlukan karena jika tidak, Windows akan mogok pada export NODE_ENVperintah yang tidak dikenal : D. Tidak tahu tentang ruang trailing tetapi hanya untuk memastikan saya menghapusnya juga.

TeemuK
sumber
6
Apakah Anda menggunakan &&? NODE_ENV=test yaddaberarti "jalankan yadda, tetapkan NODE_ENVdalam yaddavariabel lingkungan. NODE_ENV=test && yaddaberarti" atur NODE_ENVdalam lingkungan lokal, tetapi jangan ekspor, lalu jalankan yadda. " NODE_ENV=test yaddaadalah pendekatan yang disukai.
Josh Kelley
Maaf yang belum memeriksa akun stackoverflow saya dalam beberapa saat. Tetapi pada dasarnya Windows yang konyol tidak bekerja menggunakan NODE_ENV=test && npm run testatau sesuatu yang serupa. Saya membuat solusi yang lebih baik menggunakan process.env["NODE_ENV"] = "testing";di dalam file testhelper.js saya.
TeemuK
5
@TeemuK hanya untuk menambahkan dua sen saya juga, ketika Anda menjalankan perintah dengan &&Anda kehilangan variabel lingkungan Anda, pengaturan variabel lingkungan tanpa ekspor hanya bekerja pada perintah saat ini (yang bukan apa-apa). untuk menjalankan perintah dengan variabel env tanpa mengekspor u lakukan: NODE_ENV=test npm run test. Akhirnya alasan itu berhasil setelah Anda diekspor, adalah karena variabel Anda sekarang tersedia (diekspor) di sesi, NODE_ENV Anda tanpa ekspor tidak melakukan apa-apa.
Tarek
19

Coba ini di Windows dengan mengganti YOURENV:

  {
    ...
     "scripts": {
       "help": "set NODE_ENV=YOURENV && tagove help",
       "start": "set NODE_ENV=YOURENV && tagove start"
     }
    ...
  }
Pascal Mayr
sumber
1
Iya! Terima kasih! Ini adalah jawaban yang saya cari! : D
Daniel Tonon
6
Saya harus menghapus spasi sebelum &&.
Kenneth Solberg
Komentar @ KennethSolberg adalah sentuhan terakhir yang membuatnya bekerja untuk saya (hanya Windows)
ulu
Saya juga punya masalah ruang. Ketika masuk panjang string saya bisa tahu ruang ditambahkan. Saya mencoba melarikan diri kutipan - dan mereka sebenarnya disimpan di envar. Saya mencoba pembatas lain tetapi tidak berhasil. Menghapus ruang atau memangkas nilai, yang terasa salah bagi saya, adalah satu-satunya cara untuk mengatasi masalah ini.
Neil Guy Lindberg
8

tiba-tiba saya menemukan bahwa actionhero menggunakan kode berikut, yang memecahkan masalah saya dengan hanya meneruskan --NODE_ENV=productionopsi perintah skrip mulai.

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

saya akan sangat menghargai untuk menerima jawaban dari orang lain yang tahu cara yang lebih baik untuk mengatur variabel lingkungan dalam package.json atau skrip init atau sesuatu seperti, di mana aplikasi dibooting oleh orang lain.

dev.meghraj
sumber
4

Untuk variabel lingkungan yang lebih besar atau ketika Anda ingin menggunakannya kembali, Anda dapat menggunakannya env-cmd.

./.env mengajukan:

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

./package.json:

{
  "scripts": {
    "test": "env-cmd mocha -R spec"
  }
}
KARASZI István
sumber
bagaimana Anda menggunakan ENV1 dalam skrip?
ValRob
Biasaprocess.env.ENV1
KARASZI István
tapi, di dalam package.json? saya telah membaca itu tidak mungkin (?)
ValRob
Saya tidak mengerti. Kenapa kamu ingin melakukan itu?
KARASZI István
mungkin merupakan pendekatan konyol, tapi saya telah memperbarui macOs Catalina dan sekarang perintah mongodb tidak berfungsi, jadi saya perlu menentukan data / folder mongod --dbpath ~/data/db. Saya ingin menjalankan sesuatu seperti npm mongodbdan itu akan mendapatkan variabel lingkungan dbpath dan menjalankan mondodb seperti biasa ... dan .. saya ingin membaginya dengan anggota lain.
ValRob
2

Meskipun tidak secara langsung menjawab pertanyaan saya ingin membagikan ide di atas jawaban lainnya. Dari apa yang saya dapatkan masing-masing akan menawarkan beberapa tingkat kompleksitas untuk mencapai kemandirian lintas platform.

Pada skenario saya, semua yang saya inginkan, pada awalnya, untuk mengatur variabel untuk mengontrol apakah akan mengamankan server dengan otentikasi JWT (untuk tujuan pengembangan)

Setelah membaca jawaban saya memutuskan hanya untuk membuat 2 file yang berbeda, dengan otentikasi dihidupkan dan dimatikan masing-masing.

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

File-file tersebut hanyalah pembungkus yang memanggil file index.js asli (yang saya beri nama baru 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
    }
}

Mungkin ini bisa membantu orang lain

Luiz Henrique Martins Lins Rol
sumber
2
{
  ...
  "scripts": {
    "start": "ENV NODE_ENV=production someapp --options"
  }
  ...
}
Cailean
sumber
2

Ini akan berfungsi di konsol Windows :

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

npm run aaa

keluaran: test

Lihat jawaban ini untuk detailnya.

Sergey
sumber
5
Seharusnya set TMP=test&& npm run bbb. Ruang sebelumnya &&juga akan dibentuk sebagai bagian dari NODE_ENVstring itu
FisNaN
@FisNaN Seharusnya tidak terjadi jika Anda mengelilinginya dengan tanda kutip ".
kaiser
2

gunakan git bash di windows. Git Bash memproses perintah secara berbeda dari cmd.

Sebagian besar perintah Windows akan tersedak ketika Anda mengatur variabel lingkungan dengan NODE_ENV = produksi seperti itu. (Pengecualian adalah Bash pada Windows, yang menggunakan Bash asli.) Demikian pula, ada perbedaan dalam bagaimana perintah windows dan POSIX menggunakan variabel lingkungan. Dengan POSIX, Anda menggunakan: $ ENV_VAR dan di windows Anda menggunakan% ENV_VAR%. - cross-env doc

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

gunakan paket dotenv untuk mendeklarasikan variabel env

Shubham Shaw
sumber
1

Anda seharusnya tidak mengatur variabel ENV di package.json. actionhero menggunakan NODE_ENVuntuk memungkinkan Anda mengubah opsi konfigurasi yang diambil dari file di ./config. Periksa file konfigurasi redis , dan lihat bagaimana NODE_ENV digunakan untuk mengubah opsi basis data diNODE_ENV=test

Jika Anda ingin menggunakan variabel ENV lain untuk mengatur sesuatu (mungkin port HTTP), Anda masih tidak perlu mengubah apa pun di package.json. Misalnya, jika Anda menetapkan PORT=1234ENV dan ingin menggunakannya sebagai port HTTP NODE_ENV=production, cukup rujuk di file konfigurasi yang relevan, yaitu:

# in config/servers/web.js
exports.production = { 
  servers: {
    web: function(api){
      return {
       port: process.env.PORT
      }
    }
  }
}
Evan
sumber
Bagus. saya pikir Anda tidak membaca pertanyaan saya .. masalah saya adalah bagaimana mengatur NODE_ENV bukan apa gunanya.
dev.meghraj
1
Jika Anda ingin mengatur beberapa properti lingkungan, Anda tidak melakukannya dalam npm startperintah. Menggunakan potongan di atas, jika Anda ingin menjalankan server Anda menggunakan port ENV itu akan: export PORT=1234; npm start. Anda dapat menambahkan deklarasi ENV sebanyak yang Anda butuhkan, tetapi deklarasi tersebut tidak termasuk dalam file package.json. Jika Anda khawatir tentang memastikan mereka ada Anda harus menggunakan default di file konfigurasi Anda: port: process.env.PORT || 8080.
Tony
1
Mungkin cara alternatif untuk menjelaskan ini adalah bahwa NODE_ENV (dan variabel lingkungan lainnya) adalah bagian dari lingkungan (karenanya namanya). Mereka biasanya properti dari server Anda menjalankan aplikasi daripada aplikasi Anda. Anda dapat mengaturnya secara manual melalui perintah yang Anda jalankan, yaitu: NODE_ENV=test npm startatau mengaturnya dengan shell
Evan
3
Saya tidak setuju. menggunakan ./config untuk setiap lingkungan membatasi Anda untuk menggunakan lingkungan statis saat Anda menggunakan aplikasi Anda. Ini adalah filosofi usang yang tidak akan memungkinkan Anda untuk memunculkan jenis lingkungan baru saat diperlukan. IE untuk setiap lingkungan baru yang Anda inginkan, Anda harus menambahkan .config. Mengatur variabel lingkungan saat runtime bisa menjadi opsi yang unggul saat tumpukan teknologi Anda membutuhkan lebih banyak fleksibilitas. Saya pikir ./config Anda akan bagus untuk menyiapkan "jenis" lingkungan, tetapi aplikasi Anda akan lebih fleksibel jika Anda dapat mendefinisikan hal-hal seperti string dsn dan titik akhir api saat runtime.
Jesse Greathouse
@ JesseGreathouse - Saya memiliki aplikasi node.js dan saya perlu mengatur variabel lingkungan saat runtime - file apa yang akan saya atur?
Roger Dodger
1

npm (dan benang) melewatkan banyak data dari package.json ke dalam skrip sebagai variabel lingkungan. Gunakan npm run envuntuk melihat semuanya. Ini didokumentasikan dalam https://docs.npmjs.com/misc/scripts#environment dan tidak hanya untuk skrip "siklus hidup" seperti prepublishtetapi juga skrip yang dijalankan oleh npm run.

Anda dapat mengakses kode dalam ini (misalnya process.env.npm_package_config_portdalam JS) tetapi sudah tersedia untuk shell yang menjalankan skrip sehingga Anda juga dapat mengaksesnya sebagai $npm_...ekspansi dalam "skrip" (unix sintaks, mungkin tidak berfungsi di windows?).

Bagian "config" tampaknya dimaksudkan untuk penggunaan ini:

  "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/"
  } 

Kualitas penting dari bidang "config" ini adalah bahwa pengguna dapat menimpanya tanpa mengubah package.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

Lihat npm config dan benang config docs.
Tampaknya benang berbunyi ~/.npmrcsehingga npm config setmempengaruhi kedua, tetapi yarn config setmenulis untuk ~/.yarnrc, sehingga hanya benang akan melihatnya :-(

Beni Cherniavsky-Paskin
sumber
1

Jawaban @ luke hampir yang saya butuhkan! Terima kasih.

Karena jawaban yang dipilih sangat mudah (dan benar), tetapi sudah lama, saya ingin menawarkan alternatif untuk mengimpor variabel dari file terpisah .env ketika menjalankan skrip Anda dan memperbaiki beberapa batasan pada jawaban Luke. Coba ini:

::: File .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"

Kemudian, di paket json Anda, Anda akan membuat skrip yang akan mengatur variabel dan menjalankannya sebelum skrip yang Anda butuhkan:

::: package.json :::

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

Beberapa pengamatan:

  • Ekspresi reguler dalam perintah cat grep'ed akan menghapus komentar dan baris kosong.

  • The &&tidak perlu menjadi "terpaku" untuk npm run set-env, karena akan diperlukan jika Anda menetapkan variabel dalam perintah yang sama.

  • Jika Anda menggunakan benang, Anda mungkin melihat peringatan, Anda dapat mengubahnya yarn set-envatau menggunakannya npm run set-env --scripts-prepend-node-path &&.

Lingkungan yang berbeda

Keuntungan lain saat menggunakannya adalah Anda dapat memiliki variabel lingkungan yang berbeda.

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

Tolong, ingatlah untuk tidak menambahkan file .env ke repositori git Anda ketika Anda memiliki kunci, kata sandi atau data pribadi yang masuk akal!

Felipe N Moura
sumber