ساختار فایل‌ها و پوشه‌ها

پروژه‌ی devnotes ساخته شده و اجرا می‌شود. حالا باید بدانیم هر پوشه و فایل چه نقشی دارد، چون در تمام فصل‌های بعد دائماً به آن‌ها مراجعه می‌کنیم. در این درس فقط نقش هر بخش را در سطح کلی مرور می‌کنیم؛ جزئیات layout.tsx و page.tsx در فصل ۲ و جزئیات اسکریپت‌ها در (اجرای پروژه، اسکریپت‌ها و Turbopack) می‌آید.

پیش‌نیاز

  • درس CH01-S04: ساخت پروژه با create-next-app و اجرای npm run dev

نمای کلی ساختار پروژه

با انتخاب‌هایی که در درس قبل داشتیم (TypeScript، ESLint، Tailwind CSS، App Router و بدون پوشه‌ی src)، ساختار پروژه تقریباً به این شکل است:

text
devnotes/
├── app/
│   ├── favicon.ico
│   ├── globals.css
│   ├── layout.tsx
│   └── page.tsx
├── public/
│   └── (چند فایل SVG نمونه)
├── node_modules/
├── .next/
├── .gitignore
├── eslint.config.mjs
├── next-env.d.ts
├── next.config.ts
├── package.json
├── package-lock.json
├── postcss.config.mjs
├── README.md
└── tsconfig.json

فهرست دقیق فایل‌ها ممکن است بسته به نسخه‌ی فرعی Next.js و انتخاب‌هایتان کمی فرق کند. مثلاً پوشه‌ی .next بعد از اجرای npm run dev ساخته می‌شود. ساختار کلی ثابت است و همین چیزی است که باید بشناسید.

پوشه‌ی app: قلب برنامه

پوشه‌ی app مهم‌ترین بخش پروژه است. در App Router، ساختار پوشه‌ها و فایل‌های داخل app مسیرهای سایت را تعیین می‌کند. این همان مسیریابی مبتنی بر فایل‌سیستم است که در درس‌های اول دیدیم.

فایل نقش
app/layout.tsx Root Layout؛ ساختار مشترک تمام صفحات (شامل تگ‌های html و body). وجود این فایل الزامی است.
app/page.tsx صفحه‌ی اصلی سایت، یعنی مسیر /
app/globals.css استایل سراسری؛ در پروژه‌ی ما شامل تنظیمات Tailwind CSS هم هست
app/favicon.ico آیکون تب مرورگر

وقتی در آینده پوشه‌ی جدیدی مثل app/posts بسازید و داخلش page.tsx بگذارید، مسیر /posts به‌طور خودکار ایجاد می‌شود. نام‌هایی مثل page.tsx و layout.tsx نام‌های قراردادی (Convention) هستند و Next.js با دیدن آن‌ها می‌داند چه کار کند. فایل‌های ویژه‌ی دیگر را در (مهم‌ترین تغییرات Next.js 16) می‌بینیم.

پوشه‌ی public: فایل‌های استاتیک

هر فایلی که در public بگذارید، از آدرس ریشه‌ی سایت در دسترس است. مثلاً فایل public/logo.svg از آدرس /logo.svg قابل دسترسی می‌شود. تصاویر، آیکون‌ها و فایل‌های ثابتی مثل robots.txt معمولاً اینجا قرار می‌گیرند. جزئیات این پوشه در CH10-S05 است. فایل‌های SVG نمونه‌ای که در ابتدا داخل آن هستند، مربوط به صفحه‌ی شروع‌اند و بعداً حذف می‌شوند.

فایل‌های پیکربندی در ریشه‌ی پروژه

فایل نقش آیا دستی ویرایش می‌شود؟
package.json نام پروژه، اسکریپت‌ها و فهرست وابستگی‌ها بله، معمولاً با npm install یا برای افزودن اسکریپت
package-lock.json نسخه‌ی دقیق تمام بسته‌های نصب‌شده، برای اینکه نصب روی هر سیستم نتیجه‌ی یکسان بدهد خیر؛ npm آن را مدیریت می‌کند
next.config.ts تنظیمات Next.js؛ بعداً برای گزینه‌هایی مثل cacheComponents و تصاویر به آن برمی‌گردیم بله
tsconfig.json تنظیمات TypeScript، از جمله alias مسیر @/* گاهی
eslint.config.mjs تنظیمات ESLint برای بررسی کیفیت کد گاهی
postcss.config.mjs پیکربندی PostCSS که Tailwind CSS از آن استفاده می‌کند به‌ندرت
next-env.d.ts تعریف نوع‌های لازم برای Next.js در TypeScript خیر؛ خودکار ساخته می‌شود و نباید ویرایش شود
.gitignore فهرست فایل‌هایی که Git نباید دنبال کند گاهی
README.md توضیحات پروژه بله، اختیاری

پوشه‌هایی که خودکار ساخته می‌شوند

  • node_modules: همه‌ی کتابخانه‌های نصب‌شده در آن قرار دارند. حجمش زیاد است و هرگز دستی ویرایش نمی‌شود. در .gitignore قرار دارد و اگر پاکش کنید، دستور npm install دوباره آن را می‌سازد.
  • .next: خروجی‌های داخلی Next.js (فایل‌های ساخته‌شده و داده‌های موقت) در آن نگه داشته می‌شود. با اجرای npm run dev یا npm run build ساخته می‌شود. این پوشه هم در .gitignore است و می‌توان با خیال راحت آن را پاک کرد؛ دفعه‌ی بعد دوباره ساخته می‌شود.

alias مسیر @/*

در درس قبل گفتیم import alias را روی مقدار پیش‌فرض نگه می‌داریم. این تنظیم در tsconfig.json قرار دارد و بخش مربوط به آن به این شکل است:

json
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./*"]
    }
  }
}

این یعنی @/ به ریشه‌ی پروژه اشاره می‌کند. با این روش به‌جای مسیرهای نسبی طولانی، مسیر را از ریشه می‌نویسیم:

ts
// بدون alias
import { getPosts } from "../../../lib/posts";

// با alias
import { getPosts } from "@/lib/posts";

پوشه‌ی lib هنوز در پروژه‌ی ما وجود ندارد و این فقط یک مثال است. از فصل ۵ که لایه‌ی دسترسی به داده را می‌سازیم، از این alias استفاده می‌کنیم.

آزمایش کوتاه: پوشه یعنی مسیر

برای دیدن رابطه‌ی ساختار فایل‌ها با مسیرها، یک آزمایش ساده انجام می‌دهیم. این آزمایش اختیاری است و آخرش آن را پاک می‌کنیم تا پروژه تمیز بماند.

  1. سرور را با npm run dev اجرا کنید.
  2. داخل app یک پوشه به نام test بسازید.
  3. داخل آن فایل page.tsx را با این محتوا بسازید:
tsx
// app/test/page.tsx
export default function TestPage() {
  return <h1>این یک صفحه‌ی آزمایشی است</h1>;
}
  1. مرورگر را باز کنید و به http://localhost:3000/test بروید.
  2. پس از دیدن نتیجه، پوشه‌ی app/test را حذف کنید.

خروجی مورد انتظار

بدون هیچ تنظیم مسیریابی، صفحه‌ی /test با عنوان «این یک صفحه‌ی آزمایشی است» نمایش داده می‌شود. پس از حذف پوشه، همان آدرس خطای «صفحه پیدا نشد» (404) می‌دهد.

ساختار DevNotes در ادامه‌ی دوره

در فصل ۲ ساختار اولیه‌ی DevNotes را روی همین پروژه می‌سازیم و در فصل‌های بعد پوشه‌های بیشتری مثل lib و components اضافه می‌شوند. هر بار که ساختار تغییر کند، دلیل تغییر و فایل‌های تحت‌تأثیر را مشخص می‌کنیم.

جمع‌بندی

  • پوشه‌ی app مسیرهای برنامه را تعیین می‌کند. layout.tsx ساختار مشترک و page.tsx محتوای صفحه را تعریف می‌کند.
  • پوشه‌ی public برای فایل‌های استاتیک است و محتوای آن از ریشه‌ی سایت در دسترس قرار می‌گیرد.
  • فایل‌های ریشه مثل package.json، next.config.ts و tsconfig.json پیکربندی پروژه را نگه می‌دارند.
  • node_modules و .next خودکار ساخته می‌شوند، دستی ویرایش نمی‌شوند و در Git ثبت نمی‌شوند.
  • alias مسیر @/* به ریشه‌ی پروژه اشاره می‌کند و importها را کوتاه‌تر می‌کند.
  • در درس بعد (CH01-S06) اجرای پروژه، اسکریپت‌ها و Turbopack را بررسی می‌کنیم.