process.env הוא אובייקט עם מאפיין אחד לכל משתנה סביבה שה-shell העביר לתוכנית ה-Node.js שלכם: process.env.PORT, process.env.DATABASE_URL וכן הלאה. משתנה שלא הוגדר נקרא כ-undefined, ומשתנה שהוגדר הוא תמיד מחרוזת. קראו אותו פעם אחת בעליית התוכנית, תנו לו ברירת מחדל, והמירו אותו לטיפוס שאתם צריכים.
הוא הדפיס shop on port 8080 in eu-west (המשתנה REGION מעולם לא הוגדר, אז ברירת המחדל שלו נכנסה לפעולה), ואז string number: המשתנה הוא טקסט עד ש-Number() ממיר אותו. מחקו את שתי ההצבות הראשונות והריצו שוב כדי לראות את כל ברירות המחדל.
הגדרת משתני סביבה ב-shell
המשתנים מגיעים מהמקום שבו Node.js מופעל. בטרמינל:
// macOS and Linux: for one command
PORT=8080 NODE_ENV=production node app.js
// macOS and Linux: for the rest of the terminal session
export PORT=8080
// Windows PowerShell
$env:PORT = "8080"; node app.js
// Windows cmd.exe
set PORT=8080
node app.js
לפלטפורמות אירוח (Heroku, Render, Vercel, Docker, Kubernetes) יש דף הגדרות או קובץ לאותה מטרה; הקוד שלכם קורא אותם באותה דרך.
הכל מחרוזת
מכאן מגיעים רוב הבאגים עם process.env. 'false' ו-'0' הן מחרוזות לא ריקות, ולכן הן truthy:
הבדיקה הנאיבית הדפיסה debug is ON עבור משתנה שערכו false, אז השוו למחרוזת המדויקת שאתם מצפים לה. במספרים, Number(process.env.X) הופך ערך חסר ל-NaN, לכן החילו את ברירת המחדל לפני ההמרה, כמו שהדוגמה הראשונה עשתה עם ??.
NODE_ENV
NODE_ENV הוא מוסכמה, לא יכולת של Node.js: Node.js אף פעם לא מגדיר אותו. ספריות קוראות אותו. Express, למשל, מסתיר stack traces מדפי שגיאה כשהערך הוא production, והרבה כלים מדלגים על בדיקות שנועדו רק לפיתוח.
הוא הדפיס mode: production ו-verbose logs: false; שנו את 'production' ל-'development' והשורה השנייה תתהפך. היצמדו ל-production, development ו-test, כי ספריות בודקות בדיוק את המילים האלה.
קבצי .env: --env-file ו-dotenv
להקליד כל משתנה לפני node נמאס מהר. קובץ .env שומר אותם בתיקיית הפרויקט, אחד בכל שורה:
// .env
PORT=8080
DATABASE_URL=postgres://localhost/shop
API_KEY=dev-key-123
מ-Node.js 20.6 ואילך קוראים אותו עם דגל, בלי שום חבילה:
node --env-file=.env app.js
בגרסאות ישנות יותר, או אם אתם מעדיפים, התקינו את החבילה dotenv (npm install dotenv) וטענו אותה ממש בראש קובץ הכניסה, לפני שקוד כלשהו קורא את process.env:
require('dotenv').config(); // copies .env into process.env
console.log(process.env.PORT); // 8080
אף אחת מהן לא דורסת משתנה שכבר הוגדר ב-shell, כך שהגדרות ה-production גוברות על הקובץ.
להיכשל מוקדם על משתנים חסרים
כתובת חסרה של מסד נתונים צריכה לעצור את התוכנית בעלייה עם הודעה ברורה, ולא לקרוס בבקשה הראשונה שעה אחר כך:
הוא הדפיס Missing environment variables: API_KEY; הוסיפו process.env.API_KEY = 'test'; בראש הקוד והוא ידפיס Config OK. בתוכנית אמיתית, אחרי ההודעה קראו ל-process.exit(1), כי קוד יציאה שאינו אפס הוא הדרך שבה סקריפט deploy או פלטפורמת קונטיינרים מבינים שהעלייה נכשלה.
לעולם אל תעשו commit לסודות
הוסיפו את .env ל-.gitignore ביום שבו אתם יוצרים אותו. במקומו עשו commit לקובץ .env.example עם שמות המשתנים וערכים מזויפים, כדי שאחרים יידעו מה להגדיר. מפתח שאי פעם נדחף ל-repository צריך להיחשב כמפתח שדלף ולהיות מוחלף, גם אם אחר כך מחקתם את ה-commit.
שאלות נפוצות
למה process.env.MY_VAR הוא undefined?
המשתנה לא הוגדר ב-shell שהפעיל את Node.js, או שהוא הוגדר בטרמינל אחר. גם קובץ .env לא נקרא אוטומטית: הפעילו את Node.js עם --env-file=.env או טענו אותו עם dotenv לפני שאתם קוראים את הערך.
אפשר לשנות את process.env בזמן שהתוכנית רצה?
כן. הצבה process.env.X = 'value' משנה אותו לתהליך הנוכחי ולכל תהליך בן שהוא יפעיל אחר כך, אבל אף פעם לא ל-shell שהפעיל את Node.js. Node.js ממיר את הערך שהצבתם למחרוזת.
האם שמות של משתני סביבה רגישים לאותיות גדולות וקטנות?
ב-Linux וב-macOS כן: PORT ו-port הם שני משתנים. ב-Windows לא. היצמדו לשמות באותיות גדולות עם קווים תחתונים, והשאלה לא תעלה.
האם הדפדפן יכול לקרוא את process.env?
לא. לדפדפנים אין משתני סביבה. כלי build כמו Vite ו-Next.js מעתיקים משתנים נבחרים לקוד ה-frontend בזמן ה-build, וזה גם אומר שהערכים האלה ציבוריים.