تنظیمات و متغیر محیطی؛ PORT معتبر و نگهداری امن .env
در این درس ۴ بخش
پورت ۳۰۰۰ ممکن است در رایانهٔ همکارتان اشغال باشد. اگر عدد در چند فایل تکرار شده باشد، تغییر ساده به خطای پنهان تبدیل میشود. تنظیمات باید یک نقطهٔ ورود روشن داشته باشند و پیش از شروع کار بررسی شوند. متغیر محیطی یکی از روشهای انتقال تنظیمات به فرایند است؛ با متغیر داخل یک ماژول یا مقداری که در فرم مرورگر میبینید یکی نیست.
در پوشهای تازه به نام config-lab کار کنید. در این درس هنوز سرور را باز نمیکنیم؛ فقط پیکربندی معتبر میسازیم. Node نسخهٔ LTS بهروز شاخهٔ ۲۴ یا ۲۶ میتواند فایل .env را با گزینهٔ داخلی --env-file بارگذاری کند و برای این نمونه نیازی به نصب dotenv نداریم. مقدارهای process.env متناند: PORT=3000 عدد ۳۰۰۰ آماده تحویل نمیدهد. همچنین false در فایل، رشتهٔ false است و در شرط if بهخودیخود مقدار truthy دارد.
تبدیل محدود و شکست روشن
فایل config.mjs را با کد زیر بسازید. مقدار پیشفرض فقط وقتی استفاده میشود که کلید وجود ندارد؛ متن خالی ورودی معتبر نیست. قرارداد این تمرین رقم لاتین ساده و پورت ۱۰۲۴ تا ۶۵۵۳۵ است. این بازه تصمیم آموزشی ما برای جلوگیری از پورتهای پایین در تمرین است، نه تعریف کلی همهٔ پورتهای مجاز سیستمعامل.
// config.mjs
export function loadConfig(env = process.env) {
const raw = env.PORT ?? '3000';
if (typeof raw !== 'string' || !/^\d{1,5}$/.test(raw)) {
throw new Error('PORT must contain plain digits');
}
const port = Number(raw);
if (!Number.isInteger(port) || port < 1024 || port > 65535) {
throw new RangeError('PORT must be between 1024 and 65535');
}
return Object.freeze({ host: '127.0.0.1', port });
}فایل app.mjs را هم بسازید. فقط host و port که حساس نیستند چاپ میشوند. چاپ کل process.env برای عیبیابی مناسب نیست؛ ممکن است رمز، توکن یا تنظیمات خصوصی ابزارهای دیگر در آن باشد. تعیین host به 127.0.0.1 در قرارداد ما یعنی نمونهٔ سرور بعدی باید به همین رایانه محدود باشد؛ تغییر پورت بهتنهایی مجوز دسترسی عمومی ایجاد نمیکند.
// app.mjs
import { loadConfig } from './config.mjs';
try {
const { host, port } = loadConfig();
console.log(`configured: http://${host}:${port}`);
} catch (error) {
console.error(error.message);
process.exitCode = 1;
}در VS Code فایل .env را با UTF-8 و محتوای زیر ذخیره کنید. مراقب باشید نام واقعی .env.txt نباشد؛ نمایش پسوندهای فایل در Explorer به تشخیص کمک میکند. سپس فرمان اجرا را در پوشهٔ دارای همین فایل بزنید. مسیر فایلِ معرفیشده به --env-file نسبت به پوشهٔ جاری فرمان است، نه لزوماً محل app.mjs.
PORT=3100node --env-file=.env .\app.mjsخروجی مورد انتظار configured: http://127.0.0.1:3100 است. اگر فایل معرفیشده وجود نداشته باشد، گزینهٔ --env-file خطا میدهد؛ این شکست برای تنظیمات لازم مفید است. گزینهٔ متفاوت --env-file-if-exists فایل اختیاری را تحمل میکند، ولی پنهانکردن نبود تنظیمات ضروری با آن راهحل مناسبی نیست. فایل env دریافتی از منبع ناشناس را هم بیبررسی به Node ندهید؛ کلیدهایی مانند NODE_OPTIONS میتوانند بر شیوهٔ اجرای خود Node اثر بگذارند.
فایل نمونه، فایل واقعی و Git
یک .env.example هم بسازید که فقط مقدارهای غیرمحرمانه و راهنمای لازم را دارد؛ در این تمرین همان PORT=3100 کافی است. همتیمی آن را میبیند و فایل واقعی خودش را میسازد. الگوی زیر را در .gitignore قرار دهید. این دستورالعمل فایلهای موجود در تاریخچه را پاک نمیکند و فایلِ از قبل tracked نیز صرفاً با افزودن ignore از رهگیری خارج نمیشود. اگر رازی منتشر شد، باید آن را باطل و جایگزین کنید؛ پاککردن آخرین نسخه کافی نیست.
node_modules/
.env
.env.*
!.env.exampleحتی در سرور واقعی، .env بهخودیخود گاوصندوق نیست. مجوز فایل، روش تزریق secret توسط میزبان و دسترسی فرایند اهمیت دارند. راز سرور نباید در خروجی ارسالی به مرورگر قرار بگیرد؛ این مثال رمز واقعی ندارد.
تقدم مقدار پوسته و خطای دستورهای کپیشده
اگر همان متغیر از قبل در محیط فرایند موجود باشد، بر مقدار فایل env تقدم دارد. برای آزمایش فقط همین کلید تمرینی را در نشست PowerShell تعیین کنید و بعد وضعیت قبلی را بازیابی کنید. این تغییر محدود به نشست جاری است و تنظیم دائمی ویندوز را عوض نمیکند. نحو Windows CMD و Bash با PowerShell فرق دارد.
$hadCoursePort = Test-Path Env:PORT
$previousCoursePort = $env:PORT
try {
$env:PORT = "3200"
node --env-file=.env .\app.mjs
} finally {
if ($hadCoursePort) {
$env:PORT = $previousCoursePort
} else {
Remove-Item Env:PORT -ErrorAction SilentlyContinue
}
}خروجی این بار پورت 3200 است. اگر همین فرمان را داخل مقدار npm script بنویسید، پیشفرض اجرای cmd.exe در ویندوز مطرح میشود. برای قرارداد قابلحمل، script را node --env-file=.env app.mjs بگذارید و نیازهای پوسته را به بیرون از آن ببرید. سیاست اجرای سیستم را تغییر ندهید. اگر پورت درست چاپ شد ولی سرور بعدی EADDRINUSE داد، قالب تنظیم معتبر است اما منبع سیستم اشغال است؛ این دو مسئله جدا هستند.
تمرین، پاسخ و معیار تحویل
بدون تغییر محیط واقعی، در یک فایل آزمون loadConfig را با شیءهای { PORT: "" }، { PORT: "1e3" }، { PORT: "70000" } و { PORT: "3100" } صدا بزنید. پاسخ: دو مورد نخست خطای شکل، سومی خطای بازه و آخری پورت عددی 3100 میدهد. برای ورودی {} مقدار پیشفرض 3000 است. معیار تحویل، رد ورودی نامعتبر پیش از شروع سرور، ثبت فایل نمونه بدون راز، و توضیح تفاوت پورت معتبر با پورت آزاد است. در خطایاب هیچگاه برای دیدن فقط یک مقدار، همهٔ متغیرهای محیطی را منتشر نکنید.
منابع رسمی
Node.js، متغیرهای محیطی و قالب env: https://nodejs.org/api/environment_variables.html
Node.js، گزینههای env-file: https://nodejs.org/api/cli.html
Microsoft، متغیرهای محیطی PowerShell: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables
Git، قواعد gitignore: https://git-scm.com/docs/gitignore
تألیف و مثالهای اختصاصی: تحریریه درسآوند. بارگذاری env، تقدم محیط، مقدار پیشفرض و رد ورودیها با Node.js 24.22.1 روی لینوکس بررسی شدهاند؛ دستورات نشست PowerShell در ویندوز در این محیط اجرا نشدهاند.
متن درسهای عمومی را بدون ورود بخوانید.