Appearance
ابزارهای Build: Node.js
نسخهی ویدئویی
نسخهی ویدئویی این آموزش را میتوانید از طریق لینک زیر دریافت کنید. البته توصیهی ما مطالعهی نسخهی متنی آن است.
https://cdn.gaplication.com/o/2d02bc118258467a9d579efcf8fc62df
Nod.js یک JavaScript Runtime است، یعنی ابزاری است برای اجرای جاوااسکریپت خارج از محیط مرورگر.
تا به حال کد هایی که ما مینوشتیم در محیط مرورگر اجرا می شد، ولی در ابزار های build نباید به مرورگر وابسته باشیم؛ ابزارهای Build باید بتوانند مستقل از مرورگر اجرا شوند و تغییرات لازم روی کد ما را انجام داده و به خروجی مورد نظر تبدیل کنند. از همین رو معمولا ابزار های build با جاوااسکریپت نوشته میشوند و با Node.js اجرا میشوند چون این ابزارها در اصل برای اجرا در مرورگر ساخته نشده اند.
بیشتر بدانیم
اخیرا جایگزینهای دیگری نیز برای Node.js ساخته شده اند که سر و صدای زیادی هم دارند، از جمله Deno و Bun. ولی همچنان Node.js شناختهشدهتر و پایدارتر از سایر جایگزینهاست.
بیشتر بدانیم
معمولا Node.js را ابزاری برای نوشتن کد سمت سرور با جاوااسکریپت میشناسند. بله! یکی از کاربردهای اصلی Node.js نوشتن سمت سرور سایت است، امّا Node.js فقط به این موضوع محدود نمیشود.
برخی کاربردهای Node.js: پیادهسازی Backend سایت، تولید و استفاده از ابزارهای Build، ساخت رباتهای نرمافزاری (مثل رباتهایی که در پیامرسانها و شبکههای اجتماعی میبینیم یا رباتهایی که در صفحات وب میخزند و محتوای صفحات را جمعآوری میکنند)، ساخت رباتهای سختافزاری، ساخت اپلیکیشنهای تحت دسکتاپ (مثلا با فریمورک Electron که مبتنی بر Node.js است، اپلیکیشنهایی همچون Visual Studio Code ساخته شده است) و...
البته برخی از ابزارهای Build هم هستند که با زبانهای سطح پایین نوشته شدهاند، مزیت عمدهی این کار سرعت بسیار بالایی است که این ابزارها پیدا میکنند (مثل esbuild و LightiningCSS).
برای کار کردن با ابزار های build باید Nodejs را نصب کنیم و مقداری با اصول آن آشنا شویم.
نصب Node.js
از آنجایی که Node.js متنباز و رایگان است، از خود سایت رسمی آن به آدرس nodejs.org میتوانید آخرین نسخهاش را دانلود و نصب کنید (برای کاربرد ما معمولا نسخه LTS مناسب است، LTS به معنای Long Term Support است، یعنی نسخهای که دارای پشتیبانی طولانیمدت است).
مشکل ویندوز ۷
نسخههای جدید Node.js از ویندوز ۷ پشتیبانی نمیکنند. از این رو توصیه میکنیم در صورت امکان سیستم عامل خود را ارتقا دهید. امّا اگر به هر دلیلی نمیتوانید سیستم عامل خود را بروز کنید به ترتیب زیر پیش بروید.
ابتدا نسخه ۱۲ نود را که آخرین نسخهی LTS است که ویندوز ۷ را رسماً پشتیبانی میکند دانلود و نصب کنید، برای این کار از فایل نصبی (msi) استفاده کنید.
https://nodejs.org/dist/latest-v12.x
سپس فایل zip نسخه ۱۴ نود را از اینجا دانلود کنید (نه فایل msi را)، آن را از حالت فشرده خارج کنید و محتویات داخل آن را در محل نصب Node.js که در پوشه C:\Program Files\nodejs
قرار دارد جایگزین کنید. به این شکل میتوانید از نسخه ۱۴ نود در ویندوز ۷ استفاده کنید، که در زمان نوشتن این مقاله (مهرماه ۱۴۰۱) اکثر ابزارهای Build از این نسخه پشتیبانی خوبی دارند.
خط فرمان (Command Line)
هم Node.js و هم اکثر ابزارهای بیلد دارای رابط خط فرمان هستند. برای باز کردن خط فرمان در یک پوشه کلید Shift را نگه دارید و در فضایی خالی از آن کلیکراست کنید و گزینه Open powershell window here
را انتخاب کنید. (اگر از Visual Studio Code استفاده میکنید برای باز کردن خط فرمان در پوشهی پروژه کلید ترکیبی Ctrl + `
را فشار دهید، حالا در همان سربرگ Terminal میتوانید دستورات مورد نظر خود را اجرا کنید).
اگر در خط فرمان دستور node
را تایپ کنید و Enter بزنید، داخل خط فرمان چیزی شبیه به Console جاوااسکریپت مرورگر خواهید داشت که میتوانید در آن کدهای جاوااسکریپت وارد کرده و در همان زمان خروجیاش را مشاهده کنید. این کنسول Node.js است و طبیعتا ما برای استفاده از Node.js از این روش استفاده نمیکنیم.
یک فایل جاوااسکریپت با نام app.js میسازیم و محتوای زیر را داخل آن مینویسیم:
js
console.log('Salam Donya!')
سپس برای اجرای آن، خط فرمان را در آن پوشه باز کرده و دستور زیر را مینویسیم و Enter میزنیم:
bash
node ./salam
همان طور که میبینید عبارت «Salam Donya!
» داخل خط فرمان به نمایش در میآید. تبریک میگویم. این اولین برنامه Node.js ماست!
از آن جایی که هدف ما فرانتاند است و جز برای استفاده از ابزارهای بیلد قرار نیست با Node.js کار کنیم خیلی وارد جزئیات دیگر نخواهیم شد و تا همین حد که دیدید Node.js چه طور فایلهای جاوااسکریپت را مستقل از مرورگر اجرا میکند برای این مطلب کافیست. در ادامه در مورد نحوهی نصب و استفاده از ابزارهای بیلد صحبت خواهیم کرد.
npm
پکیج چیست؟ برنامهنویسان برای انجام کارهای مختلف کدهایی مینویسند. از طرفی این کدها به درد خیلی افراد دیگر نیز میخورد. آنها این کدها را در قالب پکیج به صورت رایگان منتشر میکنند و ما میتوانیم از آنها استفاده کنیم. خود ابزارهای Build نیز در قالب پکیجهای Node.js عرضه شدهاند. خیلی خوب است که ما نیز در این کار سهیم باشیم و پکیجهایی برای استفاده سایرین عرضه کنیم.
سایت npmjs.com رجیستری رسمی پکیجهای جاوااسکریپتی است و هر کسی که میخواهد پکیجی منتشر کند باید در این سایت ثبت نام کرده و پکیج خود را منتشر کند. هر کسی هم که بخواهد برای انجام کاری دنبال پکیجی بگردد میتواند از npm استفاده کند.
ابزار npm به صورت خودکار همراه با Node.js نصب میشود. npm مخفف Node.js Package Manager است، زیرا در ابتدا برای مدیریت پکیجهای Node.js ایجاد شده بود، ولی امروزه برای مدیریت هرگونه پکیج جاوااسکریپتی و سیاساسی مورد استفاده قرار میگیرد.
پکیجها را به دو صورت سراسری (global) و محلی (local) میتوانیم نصب کنیم. روش نصب سراسری کاربردهای خاص دارد و به صورت کلی توصیه نمیشود. معمولا پکیجهایی را به صورت سراسری نصب میکنیم که مانند یک اپلیکیشن یا ابزار مستقل کاری خاص را انجام میدهند.
نصب پکیج به صورت سراسری
فرض کنید سایتی را به زبان انگلیسی به صورت چپچین پیادهسازی کردهایم. حالا میخواهیم با استفاده از ابزار rtlcss فایل css چپچین آن را به صورت خودکار راستچین کنیم. برای انجام این کار میتوانیم rtlcss را به صورت سراسری نصب کنیم. برای این کار مراحل زیر را طی میکنیم.
- در ابتدا در هر پوشهای که خواستیم خط فرمان را باز میکنیم (چون پکیج مورد نظر قرار است به صورت سراسری نصب شود، اهمیتی ندارد که خط فرمان در کدام پوشه باز شود).
- سپس دستور زیر را وارد کرده و Enter بزنید. کمی صبر کنید تا پکیج مورد نظر نصب شود.
npm i -g rtlcss
توضیح دستور: در ابتدا عبارت npm نوشته شده که نام ابزاری است که میخواهیم اجرا شود. کلا ساختار خط فرمان به همین صورت است که در ابتدا نام ابزار یا برنامه مورد نظر را نوشته و بعد از یک فاصله (Space) دستوراتی را که میخواهیم برنامهی مورد نظر انجام دهد مینویسیم. در اینجا ما از دستور i
استفاده کردیم که مخفف install
است و حتی میتوانستیم به جای npm i
از npm install
استفاده کنیم؛ همان طور که از نام این دستور پیداست کاربردش نصب پکیج است. سپس پارامترهای لازم آن دستور را مینویسیم. مثلا در اینجا پارامتر -g
که مخفف --global
است به معنای نصب سراسری است. در انتها نیز نام پکیجی که قرار است نصب شود را نوشتهایم.
- خط فرمان را در پوشهای که فایل css مورد نظر ما وجود دارد باز کرده و دستور زیر را وارد میکنیم:
bash
rtlcss style.css style.rtl.css
توضیح دستور: عبارت rtlcss نام ابزاری است که میخواهیم اجرا شود (چون با دستور قبلی آن را نصب کرده بودیم میتوانیم از آن استفاده کنیم) و بعد به ترتیب اسم فایل css خودمان و پس از یک فاصله (Space) نام فایل راستچین شده است که ابزار rtlcss تولیدش خواهد کرد. البته میتوانیم نام فایل دوم را ننویسیم، در این صورت خود rtlcss نام فایل خروجی را همنام با فایل اصلی انتخاب میکند با این تفاوت که انتهای آن .rtl
اضافه میکند (مثلا rtlcss style.css
باعث میشود فایلی با نام style.rtl.css
ساخته شود که راستچینشدهی همان style.css
است).
در دستور فوق به جای style.css باید نام فایل css خودتان را بنویسید تا آن را تبدیل کند.
نکته: اگر در اسم فایلتان فاصله وجود داشته باشد باید آن را داخل کوتیشن ("..."
) قرار دهید، زیرا فاصله در خط فرمان به معنای این است که میخواهید پارامتر بعدی را وارد کنید و این باعث تداخل میشود! مثلا بنویسید rtlcss "my file.css"
.
نصب پکیج به صورت محلی
روش متداول و مرسوم برای استفاده از پکیجها نصبشان به صورت محلی است.یعنی پکیجها را روی همان پروژهای که به آنها نیاز دارد نصب میکنیم.
مزایای استفاده از روش محلی نسبت به سراسری:
- وقتی نسخهای خاص از پکیج را نصب کنیم و کدهای پروژهای را مبتنی بر آن نسخه بنویسیم و بعدا بخواهیم به خاطر پروژهای دیگر که با نسخه جدید آن پکیج سازگار است و با نسخه قدیمی آن ناسازگار است پکیج را آپدیت کنیم، در روش سراسری با پروژهی قبلی که با نسخه قدیمی آن کار میکرد ناسازگار میشود و مانع کارکرد درست آن میشود.
- وقتی گروهی برنامهنویس باهم کار میکنند همه باید از یک نسخه از پکیج استفاده کنند که مشکل سازگاری پروژه با نسخههای مختلف پکیج پیش نیاید.
برای نصب پکیج به صورت محلی ابتدا باید پروژهی خود را به عنوان یک پروژهی مبتنی بر npm معرفی کنیم. برای این کار وارد پوشهی پروژه میشویم، خط فرمان را باز میکنیم و دستور زیر را وارد میکنیم:
bash
npm init
در این هنگام سؤالاتی میپرسد که میتوانیم جواب دهیم (یعنی جواب سؤال را تایپ کنیم و Enter بزنیم)، سؤالاتی مثل اسم پکیج (زیرا پروژهی ما خودش از نظر npm یک پکیج است) و version آن و....
پس از آن در پوشهی پروژه فایلی با نام package.json
تولید میشود. این فایل شامل مشخصاتی از پروژهی ماست.
اگر دستور فوق را به صورت npm init -y
وارد کنیم، بدون پرسیدن هیچ سؤالی فایل package.json
تولید میشود.
نکته
در صورت عدم وجود فایل package.json نمیشود به صورت محلی روی پروژه پکیج نصب کرد.
حالا میتوانیم اقدام به نصب یک پکیج روی همین پروژه کنیم. برای این کار دستور زیر را در خط فرمان داخل پوشه پروژه اجرا کنید:
js
npm i rtlcss
که به جای rtlcss نام هر پکیج دیگری را که میخواهید نصب کنید میشود بنویسید. با ننوشتن -g
در این دستور پکیج به صورت سراسری نصب نمی شود و فقط برای همین پروژه نصب می شود. پس از نصب پکیج چند اتفاق می افتد:
- به محتویات فایل
package.json
فیلدdependencies
اضافه میشود و پکیج نصبشده در زیرمجموعهی آن قرار میگیرد. dependencies یعنی «وابستگیها». در این قسمت لیست پکیجهای نصبشده به همراه نسخهی آنها مشخّص میشود. از آنجایی که پروژهی ما برای اجرا معمولا به وجود این پکیجها وابسته میشود به آنها وابستگیهای برنامه گفته میشود. - فایلی به نام
package-lock.json
ساخته میشود که محتوای آن لیست دقیق نسخههای نصبشده از پکیجهای برنامهی ما و نسخهی وابستگیهای آن پکیجها و نسخهی وابستگیهای وابستگیهایشان و... است. npm محتوای این فایل را به صورت خودکار تولید میکند و برای جلوگیری از ناسازگاری نسخهها بین برنامهنویسان باید در git کامیت شود. - پوشهی
node_modules
به وجود میآید که شامل فایلهای پکیجها و وابستگیهایشان است. ساختار درونی این پوشه به این صورت است که به ازای هر وابستگی، پوشهای با همان نام ساخته میشود. درون هر پوشه یک فایل package.json مربوط به آن پکیج وجود دارد که شامل مشخصات پکیج، فایلهای اصلی آن و وابستگیهایش است.
پوشهی node_modules نباید در git کامیت شود، زیرا معمولا حجم زیادی دارد و واقعا ضرورت هم ندارد. زیرا سایر کسانی که روی پروژه کار میکنند کافیست دستور npm i
را به همین شکل ساده و بدون نوشتن نام پکیجی خاص اجرا کند. این کار باعث میشود npm با خواندن فایلهای package.json و package-lock.json خود به خود همه پکیجهای لازم را نصب کند و درون پوشهی node_modules بریزد. پس این پوشه را باید در .gitignore
معرفی کنید.
برخی از پکیجها از طریق خط فرمان قابل استفاده هستند، فایلهای قابل اجرای این پکیجها همگی در پوشهی node_modules/.bin
ذخیره میشود. پس مثلا اگر بخواهیم rtlcss را که به صورت محلی نصب شده است از طریق خط فرمان اجرا کنیم این طور مینویسیم:
sh
./node_modules/.bin/rtlcss ./rtlcss.css
این طوری rtlcss اجرا میشود و فایل راستچینشدهی rtlcss.rtl.css ساخته میشود.
برای اینکه نوشتن دستورات خط فرمان در این حالت طولانی نشود دو راهکار اصلی وجود دارد:
- استفاده از npx: ابزار npx همراه با Node.js به صورت خودکار نصب میشود. نحوهی استفاده از آن به این صورت است:
sh
npx rtlcss ./rtlcss.css
به این شکل دیگر نیازی به آدرس دادن به داخل پوشه .bin
نیست.
بیشتر بدانیم
کاربرد دیگر npx استفاده از یک پکیج، بدون نصب سراسری یا محلی است!
مثلا فرض کنید یک فایل css چپچین دارید و همان جا میخواهید همان را راستچین کنید، بدون اینکه لازم باشد پکیج rtlcss را نصب کنید (چه سراسری و چه محلی) میتوانید دستور زیر را تایپ کنید:
npx rtlcss style.css
با این کار npx در همان لحظه پکیج مورد نظر را دانلود کرده و با استفاده از آن فایل style.css را تبدیل به style.rtl.css میکند.
- استفاده از npm scripts:
در package.json یک فیلدی به نام scripts وجود دارد (اگر ندارد خودتان میتوانید اضافهاش کنید!). با استفاده از آن می توان scriptهای دلخواهی تعریف کرد. با کمک این فیلد میتوانید لیستی از دستورات خط فرمان پرکاربرد را درون package.json تعریف کنید و بعداً به راحتی از آنها استفاده کنید (مثل نوشتن تابع در برنامهنویسی 😉).
فیلد scripts آبجکتی است که کلیدهایش نام اسکریپت مورد نظر (هر نام دلخواهی که دوست دارید) و مقدارهایش دستورات خط فرمانی است که میخواهیم اجرا شود. در این دستوراتی که اینجا مینویسیم نیازی نیست به پوشهی node_modules/.bin
ارجاع کنیم یعنی در آن به راحتی و همانند پکیجی که سراسری نصب شده است میتوانیم به پکیجهای محلی دسترسی داشته باشیم.
برای مثال پکیج rtlcss را به صورت محلی نصب کردهایم. حالا برای راستچین کردن فایل style.css خود، درون package.json اسکریپت تعریف میکنیم:
json
{
...
"scripts": {
"rast-chin": "rtlcss ./style.css"
},
"dependencies": {
"rtlcss": "^4.0.0"
}
}
حالا برای اجرای اسکریپت rast-chin کافی است دستور زیر را تایپ کنیم:
npm run rast-chin
بدین وسیله npm اسکریپت مورد نظر را برای ما اجرا میکند و فایل مورد نظر تبدیل میشود.
بیشتر بدانیم | وابستگیهای زمان توسعه
شاید در جایی ببینید که پکیج را به صورت npm i -D rtlcss
(یا npm i --save-dev rtlcss
) نصب میکنند. در صورتی که پکیج را به این صورت نصب کنید، درون package.json زیرمجموعهی فیلد "devDependencies"
قرار میگیرد. در کدهای کلاینت معمولی و کارهایی که ما در ابزارهای Build داریم واقعاً تفاوت خاصی بین فیلد "dependencies" و "devDependencies" نیست! ولی اگر هدف ما ساخت یک پکیج برای انتشار در npm باشد، یا پروژهی ما فرانتاندی نباشد این دو فیلد با هم تفاوتهایی دارند.
قسمت dev در devDependencies کوتاهشدهی واژهی development به معنای توسعه است. وابستگیهایی که در زیرمجموعهی آن قرار میگیرند وابستگیهایی هستند که ما در هنگام توسعهی پروژه به آنها نیاز داریم و بعد از اینکه توسعهی پروژه تمام شد و منتشر شد دیگر نیازی به آنها نیست. مثلاً rtlcss فایل css پروژه را راستچین میکند و فایل جدیدی تولید میکند، بعد ما پروژه را منتشر میکنیم و در اختیار کاربران قرار میدهیم. در اینجا کاربر برای استفاده از پروژهی ما نیازی به نصب کردن rtlcss ندارد، چرا که rtlcss خروجی کار خود را در زمان توسعه تولید کرده بود و کاربر نهایی هم دارد از آن خروجی استفاده میکند. بنابراین از نظر منطقی تمام ابزارهای Build وابستگی زمان توسعه هستند و استانداردتر است که همه با -D
نصب شوند.
حالا از نظر عملیاتی چه تفاوتی بین این دو نوع نصب هست؟ همان طور که قبلا گفتیم هر کدام از پکیجهایی که نصب میکنیم خودشان شامل یک فایل package.json هستند. npm پس از نصب یک پکیج آن فایل را میخواند و تمام وابستگیهای معمولی آن را نیز نصب میکند و باز مجددا همین کار را برای وابستگیهای آنها نیز انجام میدهد (به همین دلیل معمولا پوشهی node_modules خیلی شلوغ است). پکیجها برای اجرای درست به وابستگیهای معمولی خود وابسته هستند، ولی به وابستگیهای زمان توسعه نه. به همین دلیل npm آنها را نصب نمیکند.
نکته: فایلهای build شده هم نباید کامیت شوند، لذا باید نام فایلهایی را که خروجی build هستند در gitignore بنویسیم. زیرا روش درست استفاده از ابزارهای بیلد این است که دستورات مربوط به بیلد در اسکریپتهای npm نوشته شود. حالا همهی کسانی که روی پروژه کار میکنند با اجرای آن اسکریپتها فایل خروجی build را خواهند داشت، به همین دلیل لازم نیست برای نگهداری این فایلها ریپازیتوری git را شلوغ کنیم.
برای راحتتر کار کردن با اسکریپتهای npm روشها و ابزارهایی وجود دارد که در ادامه به آنها خواهیم پرداخت.
نکاتی پیرامون npm scripts
در کل برای کار کردن با خط فرمان مطالعه و یادگیری لینوکس را توصیه میکنم.
برای اجرای دو اسکریپت پشت سر هم میتوانید از &&
استفاده کنید.