Next.js 14大型專案目錄架構,這樣的目錄架構更好的原因


前言

今天我們來聊聊關於Next.js 14的大型專案目錄架構。你是否曾經在專案愈做愈大的時候,突然覺得專案目錄變得混亂不堪?那麼,這篇文章就是為你而寫的!

為什麼好的目錄架構這麼重要?

在大型專案中,目錄架構就像是專案的骨架。好的目錄架構能夠讓開發者輕鬆找到所需的檔案,讓專案更具可維護性和可擴展性。特別是當多位開發者共同協作時,清晰的目錄架構更是必不可少。

Next.js 14大型專案目錄架構

我們先來看看推薦的Next.js 14目錄架構,然後再深入探討這樣的架構為何更好。

my-next-app/
├── components/
│   ├── common/
│   │   ├── Badge.tsx
│   │   ├── Button.tsx
│   │   └── Card.tsx
│   └── layouts/
│       └── MainLayout.tsx
├── lib/
│   └── apiClient.ts
├── public/
│   ├── favicon.ico
│   └── images/
├── styles/
│   ├── globals.css
│   └── tailwind.css
├── config/
│   ├── eslint.js
│   ├── next.js
│   └── tailwind.js
├── src/
│   ├── hooks/
│   │   └── useCustomHook.ts
│   ├── pages/
│   │   ├── api/
│   │   │   └── hello.ts
│   │   ├── _app.tsx
│   │   ├── _document.tsx
│   │   └── index.tsx
│   ├── utils/
│   │   └── constants.ts
│   └── types/
│       └── index.d.ts
├── .eslintrc.json
├── next.config.mjs
├── postcss.config.js
├── prettier.config.js
├── tailwind.config.js
├── tsconfig.json
├── package.json
└── pnpm-lock.yaml

目錄架構解析

components

這個目錄包含所有的可重用元件。將元件分成common和layouts兩個子目錄可以讓我們更清楚地區分通用元件和布局元件。這不僅讓元件更易於管理,也有助於提升元件的重用性。

lib

這個目錄專門用來存放所有的共享庫和實用函數。像是apiClient.ts這類文件可以集中管理應用中的API請求,確保代碼的一致性和可維護性。

public

public目錄存放靜態資源,如圖片和favicon。Next.js會自動將這個目錄下的所有文件公開訪問,這使得管理靜態資源變得非常方便。

styles

這個目錄存放全局樣式文件。tailwind.css用來引入Tailwind CSS的配置,而globals.css則可以存放一些全局的自定義樣式。

config

config目錄用來存放各種配置文件,如eslint、Next.js和Tailwind CSS的配置。將配置文件集中管理,可以避免它們分散在專案各處,增加維護成本。

src

src目錄是應用的主要源代碼目錄,包括hooks、pages、utils和types等子目錄。這樣的結構清晰明了,每個子目錄都有明確的職責分工。

根目錄配置文件

根目錄存放了一些配置文件,如.eslintrc.json、next.config.mjs等。這些文件是專案配置的核心,集中放置在根目錄下,可以讓我們一目了然地了解專案的配置情況。

為什麼這樣的目錄架構更好?

易於維護

良好的目錄結構能夠讓開發者迅速定位到需要修改的文件,這對於維護和更新代碼非常重要。當專案規模變大時,清晰的目錄結構可以顯著減少開發者的心智負擔。

提高可擴展性

每個目錄和文件都有明確的職責分工,這使得我們在需要新增功能時,可以輕鬆地擴展專案,而不會擔心引入大量技術債。

便於協作

當多位開發者共同協作時,統一的目錄結構能夠讓所有人都遵循相同的規則,減少溝通成本和代碼合併的衝突。

短且一致的導入路徑

將常用的components和lib目錄放在根目錄下,使得導入路徑變得更短更一致。例如,我們可以直接使用import Button from 'components/common/Button',而不是繁瑣的相對路徑import Button from '../../components/common/Button'

Markdown表格:目錄結構與優點對比

目錄/文件描述優點
components存放可重用元件提高元件重用性,易於管理
lib存放共享庫和實用函數集中管理,確保代碼一致性
public存放靜態資源方便管理靜態資源
styles存放全局樣式文件全局樣式集中管理,便於調整
config存放配置文件集中管理配置文件,減少維護成本
src/hooks存放自定義hook方便管理和重用hook
src/pages存放頁面文件結構清晰,便於路由管理
src/utils存放工具函數提高代碼重用性
src/types存放類型定義文件集中管理類型,增強代碼可讀性
.eslintrc.jsonESLint配置文件統一代碼風格,減少代碼格式問題
next.config.mjsNext.js配置文件集中管理Next.js配置
postcss.config.jsPostCSS配置文件集中管理PostCSS配置
prettier.config.jsPrettier配置文件統一代碼格式,增強代碼可讀性
tailwind.config.jsTailwind CSS配置文件集中管理Tailwind CSS配置
tsconfig.jsonTypeScript配置文件集中管理TypeScript配置,增強代碼可讀性和可維護性
package.json專案依賴管理文件集中管理專案依賴,便於維護
pnpm-lock.yamlpnpm依賴鎖定文件確保專案依賴的一致性

可以用ShellScript來輕鬆達成目錄架構

Bash ShellScript

#!/bin/bash

# 創建專案目錄
mkdir my-next-app
cd my-next-app

# 初始化一個新的 Next.js 專案
npx create-next-app@latest . --typescript

# 安裝 Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

# 創建必要的目錄
mkdir -p public/images/logos
mkdir -p public/images/icons
mkdir -p components/common
mkdir -p components/layout
mkdir -p components/specific
mkdir -p contexts
mkdir -p hooks
mkdir -p services
mkdir -p store/reducers
mkdir -p styles
mkdir -p utils
mkdir -p lib
mkdir -p app

# 創建必要的文件
touch app/layout.tsx
touch app/page.tsx
touch tailwind.config.js
rm -f app/globals.css

# 創建 Tailwind CSS 入口文件
cat > styles/tailwind.css <<EOT
@tailwind base;
@tailwind components;
@tailwind utilities;
EOT

# 添加 Tailwind 到 globals.css
cat > styles/globals.css <<EOT
@tailwind base;
@tailwind components;
@tailwind utilities;
EOT

# 添加 Tailwind 配置文件
cat > tailwind.config.js <<EOT
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './pages/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
    './src/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
EOT

# 更新 tsconfig.json 以包含 src
cat > tsconfig.json <<EOT
{
  "compilerOptions": {
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "./*"
      ],
      "@components/*": [
        "components/*"
      ],
      "@app/*": [
        "app/*"
      ],
      "@hooks/*": [
        "hooks/*"
      ],
      "@contexts/*": [
        "contexts/*"
      ],
      "@services/*": [
        "services/*"
      ],
      "@store/*": [
        "store/*"
      ],
      "@styles/*": [
        "styles/*"
      ],
      "@utils/*": [
        "utils/*"
      ]
    }
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}
EOT

# 創建預設頁面和組件
cat > app/page.tsx <<EOT
import { FC } from "react";

const Home: FC = () => {
  return (
    <main className="flex min-h-screen items-center justify-center">
      <h1 className="text-3xl font-bold">Hello World!</h1>
    </main>
  );
};

export default Home;
EOT

cat > app/layout.tsx <<EOT
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "@/styles/globals.css";
import { FC, ReactNode } from "react";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

interface RootLayoutProps {
  children: ReactNode;
}

const RootLayout: FC<RootLayoutProps> = ({ children }) => {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  );
};

export default RootLayout;
EOT

結論

總結來說,良好的目錄架構是大型專案成功的關鍵之一。通過清晰的目錄結構,我們可以提高專案的可維護性、可擴展性和協作效率。希望這篇文章能夠幫助你在Next.js 14的大型專案中構建一個清晰、易於管理的目錄架構。

讓我們一起打造更好的專案,讓開發工作變得更輕鬆、更有趣!