برنامه نویسی

Full-Featured Next.js 14 پروژه با الهام از ساختار MVC Laravel

در این مقاله ، ما چگونگی ساخت یک پروژه کامل بعدی را بررسی خواهیم کرد. Laravel یک چارچوب قدرتمند PHP است که از الگوی MVC پیروی می کند و روشی تمیز و سازمان یافته برای ساخت برنامه های وب ارائه می دهد. از طرف دیگر ، یک چارچوب React است که عملکردی از قبیل رندر سمت سرور (SSR) ، تولید سایت استاتیک (SSG) و API را امکان پذیر می کند و آن را به یک انتخاب عالی برای ساخت برنامه های وب مدرن تبدیل می کند.

ما با بررسی ساختار دایرکتوری پروژه Laravel ارائه می دهیم ، و سپس آن را با استفاده از پروژه بعدی. js 14 تبدیل خواهیم کرد روتر برنامه، اطمینان از اینکه هر ویژگی و مؤلفه در پروژه Laravel دارای یک معادل در پروژه بعدی است. ما همچنین نحوه استفاده را پوشش خواهیم داد غوغا برای mongoDb و پریسما برای MySQL ، ارائه نمونه های کد در طول مسیر.


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

در اینجا ساختار دایرکتوری پروژه Laravel ارائه شده است:

📂 laravel-advanced-project/
│── 📂 app/
│   │── 📂 Console/
│   │   │── Kernel.php
│   │── 📂 Events/
│   │   │── PostCreated.php
│   │   │── UserRegistered.php
│   │── 📂 Exceptions/
│   │   │── Handler.php
│   │── 📂 Http/
│   │   │── 📂 Controllers/
│   │   │   │── 📂 API/
│   │   │   │   │── PostController.php
│   │   │   │   │── UserController.php
│   │   │   │── 📂 Web/
│   │   │   │   │── HomeController.php
│   │   │   │   │── ProfileController.php
│   │   │── 📂 Middleware/
│   │   │   │── Authenticate.php
│   │   │   │── RedirectIfAuthenticated.php
│   │   │── 📂 Requests/
│   │   │   │── UserRequest.php
│   │   │   │── PostRequest.php
│   │── 📂 Models/
│   │   │── User.php
│   │   │── Post.php
│   │   │── Comment.php
│   │── 📂 Notifications/
│   │   │── NewCommentNotification.php
│   │── 📂 Policies/
│   │   │── PostPolicy.php
│   │   │── CommentPolicy.php
│   │── 📂 Providers/
│   │   │── AppServiceProvider.php
│   │   │── AuthServiceProvider.php
│   │   │── EventServiceProvider.php
│   │── 📂 Services/
│   │   │── UserService.php
│   │   │── PostService.php
│   │── 📂 Traits/
│   │   │── ApiResponse.php
│── 📂 bootstrap/
│   │── app.php
│── 📂 config/
│   │── app.php
│   │── auth.php
│   │── database.php
│── 📂 database/
│   │── 📂 factories/
│   │   │── UserFactory.php
│   │   │── PostFactory.php
│   │── 📂 migrations/
│   │   │── 2024_01_01_000000_create_users_table.php
│   │   │── 2024_01_01_000001_create_posts_table.php
│   │   │── 2024_01_01_000002_create_comments_table.php
│   │── 📂 seeders/
│   │   │── DatabaseSeeder.php
│   │   │── UserSeeder.php
│   │   │── PostSeeder.php
│── 📂 lang/
│   │── 📂 en/
│   │   │── auth.php
│   │   │── validation.php
│── 📂 public/
│   │── 📂 css/
│   │   │── app.css
│   │── 📂 js/
│   │   │── app.js
│   │── 📂 images/
│   │── index.php
│── 📂 resources/
│   │── 📂 views/
│   │   │── 📂 layouts/
│   │   │   │── app.blade.php
│   │   │── 📂 users/
│   │   │   │── index.blade.php
│   │   │   │── show.blade.php
│   │   │── 📂 posts/
│   │   │   │── index.blade.php
│   │   │   │── show.blade.php
│   │── 📂 js/
│   │   │── app.js
│   │── 📂 sass/
│   │   │── app.scss
│── 📂 routes/
│   │── api.php
│   │── web.php
│── 📂 storage/
│   │── 📂 app/
│   │   │── uploads/
│   │── 📂 logs/
│   │   │── laravel.log
│── 📂 tests/
│   │── 📂 Feature/
│   │   │── UserTest.php
│   │   │── PostTest.php
│   │── 📂 Unit/
│   │   │── UserServiceTest.php
│   │   │── PostServiceTest.php
│── .env
│── .gitignore
│── artisan
│── composer.json
│── package.json
│── phpunit.xml
│── README.md
│── webpack.mix.js
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


NEXT.JS 14 ساختار دایرکتوری پروژه (با استفاده از روتر برنامه)

حال ، بیایید ساختار پروژه Laravel را به یک پروژه Next.JS 14 با استفاده از روتر برنامهبشر ما پروژه Next.js را به شکلی سازماندهی می کنیم که ساختار لاراول را آینه می دهد ، و اطمینان حاصل می کند که هر مؤلفه در پروژه بعدی معادل دارد.

📂 nextjs-advanced-project/
│── 📂 app/
│   │── 📂 api/
│   │   │── 📂 posts/
│   │   │   │── route.js
│   │   │── 📂 users/
│   │   │   │── route.js
│   │── 📂 lib/
│   │   │── 📂 events/
│   │   │   │── postCreated.js
│   │   │   │── userRegistered.js
│   │   │── 📂 middleware/
│   │   │   │── authenticate.js
│   │   │   │── redirectIfAuthenticated.js
│   │   │── 📂 models/
│   │   │   │── User.js
│   │   │   │── Post.js
│   │   │   │── Comment.js
│   │   │── 📂 services/
│   │   │   │── userService.js
│   │   │   │── postService.js
│   │   │── 📂 utils/
│   │   │   │── apiResponse.js
│   │── 📂 middleware/
│   │   │── authMiddleware.js
│   │── 📂 components/
│   │   │── 📂 layouts/
│   │   │   │── AppLayout.jsx
│   │   │── 📂 users/
│   │   │   │── UserList.jsx
│   │   │   │── UserProfile.jsx
│   │   │── 📂 posts/
│   │   │   │── PostList.jsx
│   │   │   │── PostDetail.jsx
│   │── 📂 pages/
│   │   │── 📂 users/
│   │   │   │── page.jsx
│   │   │   │── [id]/
│   │   │   │   │── page.jsx
│   │   │── 📂 posts/
│   │   │   │── page.jsx
│   │   │   │── [id]/
│   │   │   │   │── page.jsx
│   │   │── 📂 profile/
│   │   │   │── page.jsx
│   │   │── 📂 home/
│   │   │   │── page.jsx
│── 📂 config/
│   │── app.js
│   │── auth.js
│   │── database.js
│── 📂 database/
│   │── 📂 migrations/
│   │   │── 2024_01_01_000000_create_users_table.js
│   │   │── 2024_01_01_000001_create_posts_table.js
│   │   │── 2024_01_01_000002_create_comments_table.js
│   │── 📂 seeders/
│   │   │── databaseSeeder.js
│   │   │── userSeeder.js
│   │   │── postSeeder.js
│── 📂 public/
│   │── 📂 css/
│   │   │── app.css
│   │── 📂 js/
│   │   │── app.js
│   │── 📂 images/
│── 📂 styles/
│   │── globals.css
│── 📂 tests/
│   │── 📂 feature/
│   │   │── user.test.js
│   │   │── post.test.js
│   │── 📂 unit/
│   │   │── userService.test.js
│   │   │── postService.test.js
│── .env
│── .gitignore
│── package.json
│── README.md
│── next.config.js
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


next.js 14 پروژه: اجرای کامل

ما اکنون می گذرانیم هر دایرکتوری و پرونده در بعدی. 14 ساختار پروژه و اجرای رمز کامل برای همه چیز این شامل:

  1. مسیرهای API (با استفاده از روتر برنامه Next.js)
  2. مدل (استفاده از Mongoose برای MongoDB و Prisma برای MySQL)
  3. خدمات (منطق تجارت)
  4. ظروف میانبر (احراز هویت ، مجوز و غیره)
  5. اجزای (اجزای UI قابل استفاده مجدد)
  6. صفحات (با استفاده از روتر برنامه Next.js)
  7. وقایع (معماری رویداد محور)
  8. سود (توابع ابزار مانند پاسخ API)
  9. مهاجرت پایگاه داده و بذر
  10. تست (تست های واحد و ویژگی)
  11. پیکربندی محیط
  12. استایل (CSS و سبک های جهانی)

بیایید شروع کنیم!


1 مسیرهای API

در Next.JS 14 ، مسیرهای API در app/api/ دایرکتوری هر مسیر با یک منبع خاص مطابقت دارد (به عنوان مثال ، کاربران ، پست ها).

app/api/users/route.js

import { NextResponse } from 'next/server';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

// GET /api/users - Fetch all users
export async function GET() {
  try {
    const users = await prisma.user.findMany();
    return NextResponse.json(users);
  } catch (error) {
    return NextResponse.json({ error: 'Failed to fetch users' }, { status: 500 });
  }
}

// POST /api/users - Create a new user
export async function POST(request) {
  try {
    const data = await request.json();
    const user = await prisma.user.create({ data });
    return NextResponse.json(user, { status: 201 });
  } catch (error) {
    return NextResponse.json({ error: 'Failed to create user' }, { status: 500 });
  }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

app/api/posts/route.js

import { NextResponse } from 'next/server';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

// GET /api/posts - Fetch all posts
export async function GET() {
  try {
    const posts = await prisma.post.findMany({
      include: { author: true, comments: true },
    });
    return NextResponse.json(posts);
  } catch (error) {
    return NextResponse.json({ error: 'Failed to fetch posts' }, { status: 500 });
  }
}

// POST /api/posts - Create a new post
export async function POST(request) {
  try {
    const data = await request.json();
    const post = await prisma.post.create({ data });
    return NextResponse.json(post, { status: 201 });
  } catch (error) {
    return NextResponse.json({ error: 'Failed to create post' }, { status: 500 });
  }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


2 مدل

ما استفاده خواهیم کرد پریسما برای mysql و غوغا برای MongoDB در اینجا نحوه تعریف مدل ها برای هر دو آورده شده است.

مدل های Prisma (MySQL)

در prisma/schema.prisma پرونده:

model User {
  id        Int      @id @default(autoincrement())
  name      String
  email     String   @unique
  password  String
  posts     Post[]
  comments  Comment[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String
  authorId  Int
  author    User     @relation(fields: [authorId], references: [id])
  comments  Comment[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model Comment {
  id        Int      @id @default(autoincrement())
  content   String
  postId    Int
  post      Post     @relation(fields: [postId], references: [id])
  authorId  Int
  author    User     @relation(fields: [authorId], references: [id])
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

مدل های Mongoose (MongoDB)

در app/lib/models/ دایرکتوری:

app/lib/models/User.js

import mongoose from 'mongoose';

const userSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  posts: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post' }],
  comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }],
}, { timestamps: true });

export default mongoose.models.User || mongoose.model('User', userSchema);
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

app/lib/models/Post.js

import mongoose from 'mongoose';

const postSchema = new mongoose.Schema({
  title: { type: String, required: true },
  content: { type: String, required: true },
  author: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }],
}, { timestamps: true });

export default mongoose.models.Post || mongoose.model('Post', postSchema);
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


3 خدمات

خدمات حاوی منطق تجارت برای برنامه شما هستند. بیایید خدمات را برای کاربران و پست ها ایجاد کنیم.

app/lib/services/userService.js

import prisma from '@/lib/prisma';

export const createUser = async (userData) => {
  return await prisma.user.create({ data: userData });
};

export const getUserById = async (userId) => {
  return await prisma.user.findUnique({ where: { id: userId } });
};

export const getAllUsers = async () => {
  return await prisma.user.findMany();
};
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

app/lib/services/postService.js

import prisma from '@/lib/prisma';

export const createPost = async (postData) => {
  return await prisma.post.create({ data: postData });
};

export const getPostById = async (postId) => {
  return await prisma.post.findUnique({ where: { id: postId }, include: { author: true } });
};

export const getAllPosts = async () => {
  return await prisma.post.findMany({ include: { author: true } });
};
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


4 ظروف میانبر

Middleware برای تأیید اعتبار ، مجوز و سایر تغییرات درخواست/پاسخ استفاده می شود.

app/middleware/authMiddleware.js

import { NextResponse } from 'next/server';
import jwt from 'jsonwebtoken';

export function middleware(request) {
  const token = request.cookies.get('token')?.value;
  if (!token) {
    return NextResponse.redirect('/login');
  }
  try {
    jwt.verify(token, process.env.JWT_SECRET);
    return NextResponse.next();
  } catch (error) {
    return NextResponse.redirect('/login');
  }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


5 اجزای

مؤلفه ها عناصر UI قابل استفاده مجدد هستند. بیایید یک طرح و برخی از مؤلفه های کاربر/پست ایجاد کنیم.

app/components/layouts/AppLayout.jsx

export default function AppLayout({ children }) {
  return (
    <div>
      <header>Header</header>
      <main>{children}</main>
      <footer>Footer</footer>
    </div>
  );
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

app/components/users/UserList.jsx

export default function UserList({ users }) {
  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


6 صفحات

صفحات در app/pages/ دایرکتوری بیایید صفحاتی را برای کاربران و پست ها ایجاد کنیم.

app/pages/users/page.jsx

import UserList from '@/components/users/UserList';
import { getAllUsers } from '@/lib/services/userService';

export default async function UsersPage() {
  const users = await getAllUsers();
  return (
    <div>
      <h1>Users</h1>
      <UserList users={users} />
    </div>
  );
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

app/pages/posts/page.jsx

import PostList from '@/components/posts/PostList';
import { getAllPosts } from '@/lib/services/postService';

export default async function PostsPage() {
  const posts = await getAllPosts();
  return (
    <div>
      <h1>Posts</h1>
      <PostList posts={posts} />
    </div>
  );
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


7 وقایع

از رویدادها برای معماری رویداد محور استفاده می شود. بیایید یک رویداد برای ثبت نام کاربر ایجاد کنیم.

app/lib/events/userRegistered.js

import { EventEmitter } from 'events';

class UserRegistered extends EventEmitter {
  constructor() {
    super();
    this.eventName = 'UserRegistered';
  }

  emitEvent(user) {
    this.emit(this.eventName, user);
  }
}

export default new UserRegistered();
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


8 سود

UTIL ها شامل توابع ابزار مانند پاسخ های API هستند.

app/lib/utils/apiResponse.js

export const successResponse = (res, data, status = 200) => {
  return res.status(status).json({ success: true, data });
};

export const errorResponse = (res, message, status = 500) => {
  return res.status(status).json({ success: false, error: message });
};
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


9 مهاجرت پایگاه داده و بذر

مهاجرت های Prisma

دستور زیر را برای ایجاد و اعمال مهاجرت اجرا کنید:

npx prisma migrate dev --name init
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

بذرکار

در prisma/seed.js پرونده:

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

async function main() {
  await prisma.user.create({
    data: {
      name: 'John Doe',
      email: 'john@example.com',
      password: 'password123',
    },
  });
}

main()
  .catch((e) => {
    console.error(e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


10 تست

تست های واحد

tests/unit/userService.test.js

import { createUser, getUserById } from '@/lib/services/userService';

describe('UserService', () => {
  it('should create a new user', async () => {
    const user = await createUser({ name: 'John Doe', email: 'john@example.com', password: 'password123' });
    expect(user).toHaveProperty('id');
  });
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


11 پیکربندی محیط

.env

DATABASE_URL=mysql://user:password@localhost:3306/nextjs-advanced-project
JWT_SECRET=your_jwt_secret
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


12 استایل

styles/globals.css

body {
  font-family: Arial, sans-serif;
}

header {
  background-color: #333;
  color: white;
  padding: 1rem;
}

footer {
  background-color: #333;
  color: white;
  padding: 1rem;
  text-align: center;
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


پایان

این راهنمای جامع هر جنبه ای از ساخت a را پوشش داده است next.js 14 پروژه با الهام از ساختار MVC لاراول. ما پیاده سازی کرده ایم مسیرهای APIبا مدلبا خدماتبا ظروف میانبربا اجزایبا صفحاتبا وقایعبا سودبا مهاجرت پایگاه دادهبا تستوت استایلبشر با دنبال کردن این ساختار ، می توانید یک مقیاس پذیر و حفظ برنامه بعدی

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا