60- آموزش جاوااسکریپت | پروژه عملی : قسمت 1 از 5- ساخت اپلیکیشن GitHub Finder (راهاندازی و طراحی)
در این بخش، ساخت اپلیکیشن GitHub Finder را آغاز میکنیم. با استفاده از Bootstrap و Bootswatch، رابط کاربری را طراحی کرده و زیرساخت پروژه شامل ساختار فایلها و تنظیمات اولیه API گیتهاب را برای مدیریت درخواستهای غیرهمگام پیادهسازی میکنیم.
ساخت پروژه GitHub Finder؛ معرفی پروژه و طراحی رابط کاربری
در این بخش، پروژهای به نام GitHub Finder ایجاد میکنیم. هدف این پروژه، جستوجوی کاربران GitHub بر اساس نام کاربری و نمایش اطلاعات عمومی پروفایل آنهاست.
کاربر با واردکردن یک نام کاربری میتواند اطلاعاتی مانند موارد زیر را مشاهده کند:
- تصویر پروفایل
- نام و نام کاربری
- توضیحات پروفایل
- تعداد Repositoryها
- تعداد Followers
- تعداد Following
- پنج Repository اخیر
- لینک مشاهده هر Repository
- تعداد Forkها
- تعداد Watcherها
در این مرحله هنوز منطق جاوااسکریپت و ارتباط با API را پیادهسازی نمیکنیم. ابتدا ساختار پروژه و رابط کاربری اولیه را آماده میکنیم.
1. روند کلی عملکرد برنامه
روند کار برنامه به این شکل خواهد بود:
- کاربر نام کاربری GitHub را در کادر جستوجو وارد میکند.
- با هر بار تایپ، یک رویداد روی input اجرا میشود.
- برنامه با استفاده از GitHub API، اطلاعات کاربر را دریافت میکند.
- یک درخواست دیگر برای دریافت Repositoryهای کاربر ارسال میشود.
- اطلاعات پروفایل و پنج Repository اخیر در صفحه نمایش داده میشوند.
- اگر کاربر پیدا نشود، پیام
User not foundنمایش داده خواهد شد. - اگر محتوای input کاملاً پاک شود، اطلاعات پروفایل نیز از صفحه حذف میشوند.
برای مثال، هنگام واردکردن نامی مانند bradtraversy، برنامه پروفایل Brad Traversy و Repositoryهای اخیر او را نمایش میدهد.
2. استفاده از Bootstrap و Bootswatch
برای طراحی رابط کاربری از Bootstrap استفاده میکنیم. Bootstrap مجموعهای از کلاسهای آماده برای طراحی سریع و واکنشگراست.
در کنار Bootstrap از Bootswatch نیز استفاده میکنیم. Bootswatch نسخههای آماده و سفارشیشدهای از Bootstrap ارائه میدهد که شامل رنگبندی و فونتهای متفاوت هستند.
برای استفاده از یک قالب Bootswatch، لازم نیست فایلها را دانلود کنیم. کافی است لینک CDN آن را در بخش <head> فایل HTML قرار دهیم.
در این پروژه از قالب Lumen استفاده میکنیم:
<link
rel="stylesheet"
href="https://bootswatch.com/4/lumen/bootstrap.min.css"
>
در صورت نیاز میتوان فایلهای Bootstrap JavaScript را نیز از CDN دریافت کرد. Bootstrap نسخه ۴ برای برخی قابلیتهای تعاملی به jQuery و Popper.js نیاز دارد:
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
در این پروژه بیشتر از کلاسهای CSS استفاده میکردن این فایلها مشکلی ایجاد نمیکند.
3. ساختار فایلهای پروژه
ابتدا یک پوشه با نام زیر ایجاد میکنیم:
GitHub Finder
سپس این فایلها را داخل آن قرار میدهیم:
GitHub Finder/
│
├── index.html
├── app.js
├── github.js
└── ui.js
وظیفه هر فایل:
github.js
این فایل مسئول ارتباط با GitHub API است. در ادامه کلاس GitHub را در این فایل ایجاد میکنیم.
کارهایی مانند موارد زیر در این فایل انجام میشوند:
- ارسال درخواست به API
- دریافت اطلاعات کاربر
- دریافت Repositoryها
- استفاده از
fetch - استفاده از
async/await
ui.js
این فایل مسئول مدیریت رابط کاربری و DOM است.
وظایف این فایل:
- نمایش پروفایل کاربر
- نمایش Repositoryها
- نمایش پیام خطا
- پاککردن پروفایل قبلی
- قراردادن اطلاعات دریافتشده داخل HTML
app.js
این فایل، فایل اصلی برنامه است و بخشهای مختلف را به یکدیگر متصل میکند.
در این فایل:
- به input event listener اضافه میکنیم.
- مقدار واردشده توسط کاربر را میخوانیم.
- از کلاس
GitHubبرای دریافت اطلاعات استفاده میکنیم. - از کلاس
UIبرای نمایش اطلاعات کمک میگیریم.
4. دلیل استفاده از چند فایل جاوااسکریپت
در پروژههای قبلی ممکن است همه کدها را در یک فایل مانند app.js نوشته باشیم. اما با بزرگترشدن پروژه، قرار دادن تمام کدها در یک فایل باعث بینظمی میشود.
در این پروژه، کدها را بر اساس وظیفه از هم جدا میکنیم:
- کد مربوط به API در
github.js - کد مربوط به DOM در
ui.js - کد مربوط به منطق اصلی برنامه در
app.js
چون در این مرحله از JavaScript Modules استفاده نمیکنیم، باید هر فایل را با یک تگ <script> جداگانه وارد کنیم:
<script src="github.js"></script>
<script src="ui.js"></script>
<script src="app.js"></script>
ترتیب این فایلها بسیار مهم است.
ابتدا github.js را قرار میدهیم، چون کلاس GitHub در آن تعریف میشود. سپس ui.js را قرار میدهیم، چون کلاس UI در آن قرار خواهد داشت. در نهایت app.js را وارد میکنیم، چون از هر دو کلاس استفاده میکند.
ترتیب صحیح:
<script src="github.js"></script>
<script src="ui.js"></script>
<script src="app.js"></script>
اگر app.js قبل از github.js یا ui.js بارگذاری شود، ممکن است با خطاهایی مانند خطای زیر مواجه شویم:
GitHub is not defined
یا:
UI is not defined
در پروژههای مدرنتر میتوانیم از import و export استفاده کنیم، اما در این بخش برای سادگی از چند تگ <script> استفاده میکنیم.
5. ایجاد فایل index.html
ابتدا فایل index.html را ایجاد کرده و ساختار پایه HTML را در آن قرار میدهیم:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GitHub Finder</title>
<link
rel="stylesheet"
href="https://bootswatch.com/4/lumen/bootstrap.min.css"
>
</head>
<body>
<!-- محتوای برنامه در این قسمت قرار میگیرد -->
<script src="github.js"></script>
<script src="ui.js"></script>
<script src="app.js"></script>
</body>
</html>
عنوان صفحه را نیز به شکل زیر قرار میدهیم:
<title>GitHub Finder</title>
6. ایجاد نوار navigation
در بالای صفحه یک نوار navigation ساده ایجاد میکنیم:
<nav class="navbar navbar-dark bg-primary mb-3">
<div class="container">
<a href="#" class="navbar-brand">GitHub Finder</a>
</div>
</nav>
کلاسهای استفادهشده:
navbar
این کلاس، عنصر را به یک نوار navigation تبدیل میکند.
navbar-dark
رنگ متن را برای پسزمینههای تیره تنظیم میکند.
bg-primary
رنگ پسزمینه را به رنگ اصلی Bootstrap تبدیل میکند.
mb-3
به عنصر، فاصله از پایین یا margin-bottom اضافه میکند.
container
محتوا را در یک عرض مناسب قرار میدهد و باعث میشود صفحه ظاهر منظمتری داشته باشد.
navbar-brand
برای نمایش نام یا برند برنامه استفاده میشود.
7. ایجاد بخش جستوجو
بعد از navigation، یک container برای بخش جستوجو قرار میدهیم:
<div class="container search-container">
<!-- فرم جستوجو -->
</div>
کلاس container از Bootstrap برای تنظیم عرض و فاصله داخلی استفاده میشود.
کلاس search-container فعلاً یک کلاس سفارشی است. ممکن است در ادامه برای اعمال استایلهای اختصاصی از آن استفاده کنیم.
8. ایجاد کارت جستوجو
برای نمایش عنوان، توضیحات و input، از ساختار Card در Bootstrap استفاده میکنیم:
<div class="search card card-body">
<h1>Search GitHub Users</h1>
<p class="lead">
Enter a username to fetch a user profile and repos
</p>
<input
type="text"
id="searchUser"
class="form-control"
placeholder="GitHub username..."
>
</div>
کلاسهای مهم این بخش:
card
محتوا را داخل یک کارت قرار میدهد.
card-body
به محتوای کارت فاصله داخلی مناسب میدهد.
lead
متن پاراگراف را کمی بزرگتر و برجستهتر نمایش میدهد.
form-control
ظاهر input را مطابق استایل Bootstrap تنظیم میکند.
9. ایجاد عنوان و توضیحات
عنوان بخش جستوجو:
<h1>Search GitHub Users</h1>
توضیحات زیر عنوان:
<p class="lead">
Enter a username to fetch a user profile and repos
</p>
این متن به کاربر توضیح میدهد که باید یک نام کاربری وارد کند تا پروفایل و Repositoryهای آن دریافت شوند.
10. ایجاد input جستوجو
input اصلی برنامه را به شکل زیر ایجاد میکنیم:
<input
type="text"
id="searchUser"
class="form-control"
placeholder="GitHub username..."
>
ویژگیهای این input:
type="text"
مشخص میکند که این input برای دریافت متن است.
id="searchUser"
این شناسه در JavaScript برای پیداکردن input استفاده خواهد شد:
document.getElementById('searchUser');
class="form-control"
ظاهر input را با Bootstrap هماهنگ میکند.
placeholder
متنی است که تا قبل از ورود مقدار، داخل input نمایش داده میشود:
placeholder="GitHub username..."
در مرحله بعد، یک event listener به همین input اضافه میکنیم تا با هر بار تایپ کاربر، جستوجو انجام شود.
11. ایجاد محل نمایش پروفایل
در حال حاضر اطلاعات پروفایل را بهصورت مستقیم داخل HTML قرار نمیدهیم؛ زیرا این اطلاعات بعداً از API دریافت میشوند.
برای همین، یک عنصر خالی بهعنوان محل قرارگیری پروفایل ایجاد میکنیم:
<br>
<div id="profile"></div>
شناسه profile در کلاس UI استفاده خواهد شد:
document.getElementById('profile');
بعداً JavaScript محتوای HTML مربوط به پروفایل و Repositoryها را درون این عنصر قرار میدهد.
در ابتدا این عنصر خالی است:
<div id="profile"></div>
اما بعد از جستوجوی موفق، محتوایی شبیه کارت پروفایل داخل آن قرار خواهد گرفت.
12. ایجاد Footer
در پایین صفحه یک footer ساده ایجاد میکنیم:
<footer class="mt-5 p-3 text-center bg-light">
GitHub Finder ©
</footer>
کلاسهای استفادهشده:
mt-5
به footer فاصله از بالا میدهد.
p-3
برای تمام جهات، padding ایجاد میکند.
text-center
متن را در مرکز قرار میدهد.
bg-light
یک پسزمینه روشن برای footer ایجاد میکند.
13. کد کامل فایل index.html
در نهایت، فایل HTML ما به شکل زیر خواهد بود:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GitHub Finder</title>
<!-- Bootswatch Theme -->
<link
rel="stylesheet"
href="https://bootswatch.com/4/lumen/bootstrap.min.css"
>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-dark bg-primary mb-3">
<div class="container">
<a href="#" class="navbar-brand">
GitHub Finder
</a>
</div>
</nav>
<!-- Search Section -->
<main class="container search-container">
<div class="search card card-body">
<h1>Search GitHub Users</h1>
<p class="lead">
Enter a username to fetch a user profile and repos
</p>
<input
type="text"
id="searchUser"
class="form-control"
placeholder="GitHub username..."
>
</div>
<br>
<!-- Profile content will be inserted here -->
<div id="profile"></div>
<div id="repos"></div>
</main>
<!-- Footer -->
<footer class="mt-5 p-3 text-center bg-light">
GitHub Finder ©
</footer>
<!-- Optional Bootstrap JavaScript dependencies -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<!-- Application scripts -->
<script src="github.js"></script>
<script src="ui.js"></script>
<script src="app.js"></script>
</body>
</html>
14. محدودیت درخواستهای GitHub API
اگر بدون احراز هویت به GitHub API درخواست ارسال کنیم، تعداد درخواستها در یک بازه زمانی محدود خواهد بود.
این موضوع در پروژه ما اهمیت زیادی دارد؛ زیرا قرار است با هر بار تایپ کاربر، یک درخواست به API ارسال شود. بنابراین اگر کاربر یک نام کاربری را حرفبهحرف وارد کند، درخواستهای متعددی ارسال خواهند شد.
برای استفاده از امکانات احراز هویت GitHub میتوانیم یک OAuth App ایجاد کنیم.
مسیر ایجاد برنامه:
https://github.com/settings/applications/new
برای ورود به این صفحه باید در GitHub لاگین باشیم.
در فرم ایجاد برنامه معمولاً اطلاعاتی مانند موارد زیر وارد میشود:
- Application name
- Homepage URL
- Application description
- Authorization callback URL
برای محیط آموزشی و اجرای محلی، میتوانیم از آدرسهایی مانند نمونه زیر استفاده کنیم:
http://localhost:8100
و برای callback نیز:
http://localhost:8100
پس از ثبت برنامه، GitHub اطلاعاتی مانند موارد زیر در اختیار ما قرار میدهد:
- Client ID
- Client Secret
نکته امنیتی مهم
قرار دادن Client Secret در کد سمت کاربر، برای پروژه واقعی مناسب نیست؛ زیرا تمام کدهای frontend در مرورگر قابل مشاهده هستند.
برای مثال، اگر اطلاعات حساس را در فایلی مانند github.js قرار دهیم، کاربر میتواند آنها را از طریق موارد زیر مشاهده کند:
- View Source
- DevTools
- Network
- فایلهای JavaScript بارگذاریشده
در پروژههای واقعی باید:
- اطلاعات حساس در سرور نگهداری شوند.
- درخواست به GitHub از طریق backend ارسال شود.
- Client Secret هرگز در` ذخیره قرار نگیرد.
- کلیدها در فایلهای محیطی مانند
.envذخیره شوند.
در این پروژه، چون هدف آموزشی است و قرار نیست آن را در محیط production منتشر کنیم، این موضوع را فقط برای آشنایی با روند کار مطرح میکنیم.
جمعبندی این بخش
در این مرحله:
- پروژه
GitHub Finderرا معرفی کردیم. - روند کلی جستوجوی کاربران GitHub را بررسی کردیم.
- ساختار پروژه و فایلهای آن را ایجاد کردیم.
- مسئولیت فایلهای
github.js،ui.jsوapp.jsرا مشخص کردیم. - Bootstrap و Bootswatch را از طریق CDN به پروژه اضافه کردیم.
- navigation، بخش جستوجو، input و محل نمایش پروفایل را ساختیم.
- footer پروژه را ایجاد کردیم.
- اهمیت ترتیب بارگذاری فایلهای JavaScript را توضیح دادیم.
- درباره محدودیت درخواستهای GitHub API و ساخت OAuth App صحبت کردیم.
- با خطر قرار دادن Client Secret در frontend آشنا شدیم.
در بخش بعدی، به فایلهای JavaScript میپردازیم و ابتدا event listener مربوط به input جستوجو را پیادهسازی میکنیم. سپس با استفاده از Fetch API و async/await اطلاعات کاربران و Repositoryهای آنها را از GitHub دریافت خواهیم کرد.