# 【Next.js】Private Folders

在 Next.js 中，\*\*Private Folders（私有資料夾）\*\*是指：

> 🔒 **不會被當作路由、自動產生頁面或靜態資源的資料夾**。  
> 這些資料夾的名稱 **開頭是底線 `_` 或雙底線 `__`**，也就是說：

### ✅ 資料夾名稱開頭為 `_` 或 `__` ⇒ Next.js 會自動忽略它

---

## 🔍 什麼是 Private Folders？

這是 Next.js 的一項慣例（convention），用來 **隔離你不想當作頁面處理的輔助程式碼或元件檔案**。

---

## 📁 使用範例

假設你有以下結構：

```
app/
├── page.tsx
├── _utils/              ← ✅ 不會當成路由
│   └── formatter.ts
├── __tests__/           ← ✅ 不會當成路由
│   └── page.test.tsx

```

這些 `_utils/`、`__tests__/` 都是 **Private Folders**：

- **不會產生 `/utils` 路由**
- **不會被包含在 build 出來的頁面中**
- **適合放測試、工具、常數、hooks 等程式碼**

---

## ✅ 實用用途

<table id="bkmrk-%E8%B3%87%E6%96%99%E5%A4%BE%E5%90%8D%E7%A8%B1-%E7%94%A8%E9%80%94%E7%AF%84%E4%BE%8B-_utils%2F-%E6%94%BE"><thead><tr><th>資料夾名稱</th><th>用途範例</th></tr></thead><tbody><tr><td>`_utils/`</td><td>放工具函式（e.g. dateFormat）</td></tr><tr><td>`_hooks/`</td><td>放自訂 React Hook</td></tr><tr><td>`__tests__/`</td><td>放單元測試</td></tr><tr><td>`__mocks__/`</td><td>放 Jest mock 資料</td></tr></tbody></table>

---

## 🧠 注意事項

<table id="bkmrk-%E8%A1%8C%E7%82%BA-%E8%AA%AA%E6%98%8E-%E2%9C%85-%E5%85%81%E8%A8%B1-import-%E4%BD%BF%E7%94%A8"><thead><tr><th>行為</th><th>說明</th></tr></thead><tbody><tr><td>✅ 允許 `import` 使用</td><td>Private folders 裡的檔案仍然可以被引用</td></tr><tr><td>❌ 不會產生 URL</td><td>不會出現像 `/__tests__` 這種頁面</td></tr><tr><td>✅ 適用於 `pages/` 與 `app/` 架構</td><td>兩種路由系統都支援</td></tr><tr><td>⚠️ 無法自訂規則</td><td>Next.js 只會根據 `_` 或 `__` 開頭自動判斷</td></tr></tbody></table>

---

## 📝 範例：使用 `_utils/format.ts`

```ts
// app/_utils/format.ts
export function formatCurrency(amount: number) {
  return `$${amount.toFixed(2)}`
}

```

```tsx
// app/products/page.tsx
import { formatCurrency } from '../_utils/format'

export default function ProductPage() {
  return <p>{formatCurrency(123.456)}</p>
}

```

---

## ✅ 小結

<table id="bkmrk-%E9%A0%85%E7%9B%AE-%E8%AA%AA%E6%98%8E-%E5%91%BD%E5%90%8D%E8%A6%8F%E5%89%87-%E8%B3%87%E6%96%99%E5%A4%BE%E5%90%8D%E7%A8%B1%E9%96%8B%E9%A0%AD%E7%82%BA-"><thead><tr><th>項目</th><th>說明</th></tr></thead><tbody><tr><td>命名規則</td><td>資料夾名稱開頭為 `_` 或 `__`</td></tr><tr><td>功能</td><td>不產生頁面、不加入 build 路由</td></tr><tr><td>適合用途</td><td>工具、hook、測試、mock、常數</td></tr><tr><td>是否能 import</td><td>✅ 可以被引用使用</td></tr></tbody></table>

---

這是一個非常好也非常細緻的問題，牽涉到 JavaScript / TypeScript 社群和工具生態中的 **命名慣例（naming conventions）**，並不是 Next.js 特有的規定，而是社群共識。

---

## 🔍 TL;DR 結論

<table id="bkmrk-%E5%91%BD%E5%90%8D%E5%BD%A2%E5%BC%8F-%E7%94%A8%E9%80%94-%2F-%E6%85%A3%E4%BE%8B-%E4%BE%86%E6%BA%90-_fol"><thead><tr><th>命名形式</th><th>用途 / 慣例</th><th>來源</th></tr></thead><tbody><tr><td>`_folder`</td><td>🔒 私有資料夾，Next.js 慣例（前綴式）</td><td>Next.js、社群通用慣例</td></tr><tr><td>`__tests__`</td><td>✅ 測試資料夾，Jest 標準結構（雙底線前後）</td><td>[Jest 官方](https://jestjs.io/docs/structure)</td></tr><tr><td>`__mocks__`</td><td>✅ Mock 資料夾，Jest 標準</td><td>Jest</td></tr><tr><td>`_filename.ts`</td><td>私有或輔助用檔案（非主模組）</td><td>Node / TypeScript 社群</td></tr></tbody></table>

---

## ✅ 單底線 `_`：**一般表示私有或特殊用途**

- `_utils/`、`_hooks/`、`_internal/`
- 表示：**這不是一個路由，也不是 API 端點，只是輔助邏輯用**

這種用法來自許多框架（Django、Rails、Node.js）與社群習慣。

---

## ✅ 雙底線 `__`：**通常是工具/測試框架的保留命名**

來自 **Jest、React Native、Metro Bundler 等工具**：

- `__tests__` → Jest 會自動找出來執行單元測試
- `__mocks__` → Jest 用來定義自動 mock 資料
- `__snapshots__` → Jest 的 snapshot 測試檔案

👉 **雙底線前後一致**，通常代表「這是特殊目的目錄」，會被工具偵測與處理。

---

## 🧠 命名語意總整理

<table id="bkmrk-%E5%91%BD%E5%90%8D-%E8%AA%9E%E6%84%8F-%E5%B8%B8%E8%A6%8B%E7%94%A8%E9%80%94-_%E5%90%8D%E7%A8%B1-%E7%A7%81%E6%9C%89-%2F-"><thead><tr><th>命名</th><th>語意</th><th>常見用途</th></tr></thead><tbody><tr><td>`_名稱`</td><td>私有 / 忽略 / 特殊用途（Next.js 慣例）</td><td>`_utils`, `_internal`, `_api`</td></tr><tr><td>`__名稱__`</td><td>測試工具專用</td><td>`__tests__`, `__mocks__`</td></tr><tr><td>無底線</td><td>公開模組 / 頁面 / API 等</td><td>`products`, `user`, `api`</td></tr></tbody></table>

---

## ✅ Next.js 怎麼處理這些命名？

<table id="bkmrk-%E8%B3%87%E6%96%99%E5%A4%BE%E5%90%8D%E7%A8%B1-%E6%98%AF%E5%90%A6%E6%9C%83%E8%BD%89%E6%88%90%E8%B7%AF%E7%94%B1%EF%BC%9F-%E7%94%A8%E9%80%94%E5%BB%BA%E8%AD%B0-"><thead><tr><th>資料夾名稱</th><th>是否會轉成路由？</th><th>用途建議</th></tr></thead><tbody><tr><td>`products/`</td><td>✅ 是</td><td>頁面</td></tr><tr><td>`_products/`</td><td>❌ 否</td><td>工具 / 非頁面模組</td></tr><tr><td>`__tests__/`</td><td>❌ 否</td><td>單元測試、快照測試用</td></tr></tbody></table>

---

## 📌 延伸知識：為何不是 `_tests/` 而是 `__tests__`？

這來自 **Unix / Bash 與正規表達式處理的傳統**：

- `__tests__` 這種明確結構更容易在工具中用 glob 匹配，如：
    
    ```bash
    find . -name '__tests__'
    jest "**/__tests__/**/*.test.tsx"
    
    ```

這是 Jest 與 Babel 的官方推薦格式。

---

## ✅ 總結

<table id="bkmrk-%E5%91%BD%E5%90%8D%E9%A1%9E%E5%9E%8B-%E6%84%8F%E5%9C%96-%2F-%E5%B7%A5%E5%85%B7%E6%94%AF%E6%8F%B4-_xxx%2F"><thead><tr><th>命名類型</th><th>意圖 / 工具支援</th></tr></thead><tbody><tr><td>`_xxx/`</td><td>Next.js 私有目錄，僅開頭底線</td></tr><tr><td>`__xxx__/`</td><td>Jest 風格目錄，工具自動識別處理</td></tr><tr><td>`_xxx.ts`</td><td>單一檔案私有語意</td></tr></tbody></table>

---

## 此外通常utils 其他分類資料夾只要不在app 下就不會產生路由，也是一種常用的方法

[![image-1753426662774.png](https://bookstack.treemanou.com/uploads/images/gallery/2025-07/scaled-1680-/WjkEchrWj4prc83H-image-1753426662774.png)](https://bookstack.treemanou.com/uploads/images/gallery/2025-07/WjkEchrWj4prc83H-image-1753426662774.png)