@su-record/vibe 2.4.72 → 2.4.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +216 -215
- package/README.md +4 -4
- package/agents/research/best-practices-agent.md +13 -13
- package/agents/research/codebase-patterns-agent.md +33 -33
- package/agents/research/framework-docs-agent.md +23 -23
- package/agents/research/security-advisory-agent.md +29 -29
- package/agents/review/architecture-reviewer.md +31 -31
- package/agents/review/complexity-reviewer.md +21 -21
- package/agents/review/data-integrity-reviewer.md +29 -29
- package/agents/review/git-history-reviewer.md +24 -24
- package/agents/review/performance-reviewer.md +29 -29
- package/agents/review/python-reviewer.md +53 -53
- package/agents/review/rails-reviewer.md +40 -40
- package/agents/review/react-reviewer.md +40 -40
- package/agents/review/security-reviewer.md +29 -29
- package/agents/review/simplicity-reviewer.md +24 -24
- package/agents/review/test-coverage-reviewer.md +31 -31
- package/agents/review/typescript-reviewer.md +41 -41
- package/commands/vibe.analyze.md +103 -7
- package/commands/vibe.reason.md +106 -0
- package/commands/vibe.review.md +123 -38
- package/commands/vibe.run.md +286 -223
- package/commands/vibe.spec.md +425 -186
- package/commands/vibe.utils.md +104 -3
- package/commands/vibe.verify.md +179 -86
- package/dist/cli/detect.js +40 -40
- package/dist/cli/detect.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/llm.js +5 -5
- package/dist/cli/llm.js.map +1 -1
- package/dist/cli/setup.js +3 -3
- package/dist/cli/setup.js.map +1 -1
- package/dist/lib/ContextCompressor.js +1 -1
- package/dist/lib/ContextCompressor.js.map +1 -1
- package/dist/lib/MemoryManager.d.ts +13 -155
- package/dist/lib/MemoryManager.d.ts.map +1 -1
- package/dist/lib/MemoryManager.js +52 -617
- package/dist/lib/MemoryManager.js.map +1 -1
- package/dist/lib/gemini-api.js +12 -12
- package/dist/lib/gemini-api.js.map +1 -1
- package/dist/lib/gemini-oauth.js +22 -22
- package/dist/lib/gemini-oauth.js.map +1 -1
- package/dist/lib/gemini-storage.js +3 -3
- package/dist/lib/gemini-storage.js.map +1 -1
- package/dist/lib/gpt-api.js +11 -11
- package/dist/lib/gpt-api.js.map +1 -1
- package/dist/lib/gpt-oauth.js +28 -28
- package/dist/lib/gpt-oauth.js.map +1 -1
- package/dist/lib/gpt-storage.js +3 -3
- package/dist/lib/gpt-storage.js.map +1 -1
- package/dist/lib/memory/KnowledgeGraph.d.ts +34 -0
- package/dist/lib/memory/KnowledgeGraph.d.ts.map +1 -0
- package/dist/lib/memory/KnowledgeGraph.js +216 -0
- package/dist/lib/memory/KnowledgeGraph.js.map +1 -0
- package/dist/lib/memory/KnowledgeGraph.test.d.ts +2 -0
- package/dist/lib/memory/KnowledgeGraph.test.d.ts.map +1 -0
- package/dist/lib/memory/KnowledgeGraph.test.js +189 -0
- package/dist/lib/memory/KnowledgeGraph.test.js.map +1 -0
- package/dist/lib/memory/MemorySearch.d.ts +25 -0
- package/dist/lib/memory/MemorySearch.d.ts.map +1 -0
- package/dist/lib/memory/MemorySearch.js +85 -0
- package/dist/lib/memory/MemorySearch.js.map +1 -0
- package/dist/lib/memory/MemorySearch.test.d.ts +2 -0
- package/dist/lib/memory/MemorySearch.test.d.ts.map +1 -0
- package/dist/lib/memory/MemorySearch.test.js +149 -0
- package/dist/lib/memory/MemorySearch.test.js.map +1 -0
- package/dist/lib/memory/MemoryStorage.d.ts +77 -0
- package/dist/lib/memory/MemoryStorage.d.ts.map +1 -0
- package/dist/lib/memory/MemoryStorage.js +278 -0
- package/dist/lib/memory/MemoryStorage.js.map +1 -0
- package/dist/lib/memory/MemoryStorage.test.d.ts +2 -0
- package/dist/lib/memory/MemoryStorage.test.d.ts.map +1 -0
- package/dist/lib/memory/MemoryStorage.test.js +198 -0
- package/dist/lib/memory/MemoryStorage.test.js.map +1 -0
- package/dist/lib/memory/index.d.ts +4 -0
- package/dist/lib/memory/index.d.ts.map +1 -0
- package/dist/lib/memory/index.js +8 -0
- package/dist/lib/memory/index.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/orchestrator.js +4 -6
- package/dist/orchestrator/orchestrator.js.map +1 -1
- package/dist/tools/convention/analyzeComplexity.d.ts +3 -1
- package/dist/tools/convention/analyzeComplexity.d.ts.map +1 -1
- package/dist/tools/convention/analyzeComplexity.js +102 -4
- package/dist/tools/convention/analyzeComplexity.js.map +1 -1
- package/dist/tools/convention/analyzeComplexity.test.d.ts +2 -0
- package/dist/tools/convention/analyzeComplexity.test.d.ts.map +1 -0
- package/dist/tools/convention/analyzeComplexity.test.js +207 -0
- package/dist/tools/convention/analyzeComplexity.test.js.map +1 -0
- package/dist/tools/convention/applyQualityRules.js +1 -1
- package/dist/tools/convention/applyQualityRules.js.map +1 -1
- package/dist/tools/convention/checkCouplingCohesion.js +2 -2
- package/dist/tools/convention/checkCouplingCohesion.js.map +1 -1
- package/dist/tools/convention/suggestImprovements.js +1 -1
- package/dist/tools/convention/suggestImprovements.js.map +1 -1
- package/dist/tools/convention/validateCodeQuality.d.ts +3 -1
- package/dist/tools/convention/validateCodeQuality.d.ts.map +1 -1
- package/dist/tools/convention/validateCodeQuality.js +145 -2
- package/dist/tools/convention/validateCodeQuality.js.map +1 -1
- package/dist/tools/convention/validateCodeQuality.test.d.ts +2 -0
- package/dist/tools/convention/validateCodeQuality.test.d.ts.map +1 -0
- package/dist/tools/convention/validateCodeQuality.test.js +230 -0
- package/dist/tools/convention/validateCodeQuality.test.js.map +1 -0
- package/dist/tools/memory/autoSaveContext.js +1 -1
- package/dist/tools/memory/autoSaveContext.js.map +1 -1
- package/dist/tools/memory/createMemoryTimeline.js +27 -27
- package/dist/tools/memory/createMemoryTimeline.js.map +1 -1
- package/dist/tools/memory/deleteMemory.js +1 -1
- package/dist/tools/memory/deleteMemory.js.map +1 -1
- package/dist/tools/memory/getMemoryGraph.js +24 -24
- package/dist/tools/memory/getMemoryGraph.js.map +1 -1
- package/dist/tools/memory/getSessionContext.js +36 -36
- package/dist/tools/memory/getSessionContext.js.map +1 -1
- package/dist/tools/memory/linkMemories.js +21 -21
- package/dist/tools/memory/linkMemories.js.map +1 -1
- package/dist/tools/memory/prioritizeMemory.js +1 -1
- package/dist/tools/memory/prioritizeMemory.js.map +1 -1
- package/dist/tools/memory/restoreSessionContext.js +1 -1
- package/dist/tools/memory/restoreSessionContext.js.map +1 -1
- package/dist/tools/memory/searchMemories.js +1 -1
- package/dist/tools/memory/searchMemories.js.map +1 -1
- package/dist/tools/memory/searchMemoriesAdvanced.js +42 -42
- package/dist/tools/memory/searchMemoriesAdvanced.js.map +1 -1
- package/dist/tools/memory/startSession.js +2 -2
- package/dist/tools/memory/startSession.js.map +1 -1
- package/dist/tools/memory/updateMemory.js +1 -1
- package/dist/tools/memory/updateMemory.js.map +1 -1
- package/dist/tools/semantic/analyzeDependencyGraph.js +38 -38
- package/dist/tools/semantic/analyzeDependencyGraph.js.map +1 -1
- package/dist/tools/semantic/findReferences.js +1 -1
- package/dist/tools/semantic/findReferences.js.map +1 -1
- package/dist/tools/semantic/findSymbol.js +1 -1
- package/dist/tools/semantic/findSymbol.js.map +1 -1
- package/dist/tools/time/getCurrentTime.js +1 -1
- package/dist/tools/time/getCurrentTime.js.map +1 -1
- package/dist/tools/ui/previewUiAscii.js +2 -2
- package/dist/tools/ui/previewUiAscii.js.map +1 -1
- package/hooks/hooks.json +11 -2
- package/hooks/scripts/llm-orchestrate.js +1 -1
- package/hooks/scripts/utils.js +31 -6
- package/languages/csharp-unity.md +82 -83
- package/languages/dart-flutter.md +89 -88
- package/languages/go.md +76 -75
- package/languages/java-spring.md +85 -84
- package/languages/kotlin-android.md +64 -63
- package/languages/python-django.md +83 -82
- package/languages/python-fastapi.md +82 -81
- package/languages/rust.md +75 -74
- package/languages/swift-ios.md +73 -72
- package/languages/typescript-electron.md +70 -71
- package/languages/typescript-nextjs.md +93 -92
- package/languages/typescript-node.md +64 -63
- package/languages/typescript-nuxt.md +113 -112
- package/languages/typescript-react-native.md +82 -81
- package/languages/typescript-react.md +76 -75
- package/languages/typescript-tauri.md +74 -75
- package/languages/typescript-vue.md +73 -72
- package/package.json +1 -1
- package/skills/git-worktree.md +25 -25
- package/skills/multi-llm-orchestration.md +4 -6
- package/skills/priority-todos.md +39 -39
- package/skills/vibe-capabilities.md +2 -2
- package/vibe/config.json +2 -2
|
@@ -1,40 +1,41 @@
|
|
|
1
|
-
#
|
|
1
|
+
# TypeScript + Next.js Quality Rules
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Core Principles (inherited from core + React)
|
|
4
4
|
|
|
5
5
|
```markdown
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
# Core Principles (inherited from core + React)
|
|
7
|
+
Single Responsibility (SRP)
|
|
8
|
+
No Duplication (DRY)
|
|
9
|
+
Reusability
|
|
10
|
+
Low Complexity
|
|
11
|
+
Function <= 30 lines, JSX <= 50 lines
|
|
12
|
+
All React rules apply
|
|
12
13
|
```
|
|
13
14
|
|
|
14
|
-
## Next.js
|
|
15
|
+
## Next.js Specific Rules
|
|
15
16
|
|
|
16
|
-
### 1. App Router (Next.js 13+)
|
|
17
|
+
### 1. App Router (Next.js 13+) First
|
|
17
18
|
|
|
18
19
|
```typescript
|
|
19
|
-
//
|
|
20
|
+
// Good: App Router structure
|
|
20
21
|
app/
|
|
21
|
-
├── layout.tsx #
|
|
22
|
-
├── page.tsx #
|
|
23
|
-
├── loading.tsx #
|
|
24
|
-
├── error.tsx #
|
|
25
|
-
├── not-found.tsx # 404
|
|
22
|
+
├── layout.tsx # Root layout
|
|
23
|
+
├── page.tsx # Home page
|
|
24
|
+
├── loading.tsx # Loading UI
|
|
25
|
+
├── error.tsx # Error UI
|
|
26
|
+
├── not-found.tsx # 404 page
|
|
26
27
|
├── users/
|
|
27
28
|
│ ├── page.tsx # /users
|
|
28
29
|
│ ├── [id]/
|
|
29
30
|
│ │ └── page.tsx # /users/:id
|
|
30
|
-
│ └── loading.tsx # /users
|
|
31
|
+
│ └── loading.tsx # /users loading
|
|
31
32
|
└── api/
|
|
32
33
|
└── users/
|
|
33
34
|
└── route.ts # API Route
|
|
34
35
|
|
|
35
|
-
//
|
|
36
|
+
// Good: Server Component (default)
|
|
36
37
|
export default async function UsersPage() {
|
|
37
|
-
//
|
|
38
|
+
// Fetch data on server
|
|
38
39
|
const users = await getUsers();
|
|
39
40
|
|
|
40
41
|
return (
|
|
@@ -45,7 +46,7 @@ export default async function UsersPage() {
|
|
|
45
46
|
);
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
//
|
|
49
|
+
// Good: Client Component (only when needed)
|
|
49
50
|
'use client';
|
|
50
51
|
|
|
51
52
|
import { useState } from 'react';
|
|
@@ -57,17 +58,17 @@ export function InteractiveButton() {
|
|
|
57
58
|
}
|
|
58
59
|
```
|
|
59
60
|
|
|
60
|
-
### 2.
|
|
61
|
+
### 2. Server Components vs Client Components
|
|
61
62
|
|
|
62
63
|
```typescript
|
|
63
|
-
//
|
|
64
|
-
// -
|
|
65
|
-
// -
|
|
66
|
-
// - DB
|
|
67
|
-
// -
|
|
64
|
+
// Good: Server Component (recommended)
|
|
65
|
+
// - Data fetching
|
|
66
|
+
// - Environment variable access
|
|
67
|
+
// - Direct DB access
|
|
68
|
+
// - Sensitive information handling
|
|
68
69
|
|
|
69
70
|
async function UserProfile({ userId }: { userId: string }) {
|
|
70
|
-
//
|
|
71
|
+
// Runs only on server (API key not exposed)
|
|
71
72
|
const user = await db.user.findUnique({
|
|
72
73
|
where: { id: userId },
|
|
73
74
|
});
|
|
@@ -75,11 +76,11 @@ async function UserProfile({ userId }: { userId: string }) {
|
|
|
75
76
|
return <div>{user.name}</div>;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
//
|
|
79
|
-
// - useState, useEffect
|
|
80
|
-
// -
|
|
81
|
-
// -
|
|
82
|
-
// -
|
|
79
|
+
// Good: Client Component (only when needed)
|
|
80
|
+
// - useState, useEffect usage
|
|
81
|
+
// - Event handlers
|
|
82
|
+
// - Browser APIs
|
|
83
|
+
// - Third-party libraries (mostly)
|
|
83
84
|
|
|
84
85
|
'use client';
|
|
85
86
|
|
|
@@ -90,20 +91,20 @@ function SearchBar() {
|
|
|
90
91
|
}
|
|
91
92
|
```
|
|
92
93
|
|
|
93
|
-
### 3. Data Fetching
|
|
94
|
+
### 3. Data Fetching Patterns
|
|
94
95
|
|
|
95
96
|
```typescript
|
|
96
|
-
//
|
|
97
|
+
// Good: Direct fetch in Server Component
|
|
97
98
|
async function PostsPage() {
|
|
98
|
-
//
|
|
99
|
+
// Auto caching, revalidation
|
|
99
100
|
const posts = await fetch('https://api.example.com/posts', {
|
|
100
|
-
next: { revalidate: 60 }, // 60
|
|
101
|
+
next: { revalidate: 60 }, // 60 second cache
|
|
101
102
|
}).then(res => res.json());
|
|
102
103
|
|
|
103
104
|
return <PostList posts={posts} />;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
//
|
|
107
|
+
// Good: Parallel data fetching
|
|
107
108
|
async function UserDashboard({ userId }: { userId: string }) {
|
|
108
109
|
const [user, posts, comments] = await Promise.all([
|
|
109
110
|
getUser(userId),
|
|
@@ -120,12 +121,12 @@ async function UserDashboard({ userId }: { userId: string }) {
|
|
|
120
121
|
);
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
//
|
|
124
|
+
// Good: Sequential data fetching (dependencies)
|
|
124
125
|
async function UserWithPosts({ username }: { username: string }) {
|
|
125
|
-
// 1.
|
|
126
|
+
// 1. Get user
|
|
126
127
|
const user = await getUserByUsername(username);
|
|
127
128
|
|
|
128
|
-
// 2.
|
|
129
|
+
// 2. Get posts by user ID
|
|
129
130
|
const posts = await getUserPosts(user.id);
|
|
130
131
|
|
|
131
132
|
return (
|
|
@@ -149,7 +150,7 @@ const createUserSchema = z.object({
|
|
|
149
150
|
name: z.string().min(1),
|
|
150
151
|
});
|
|
151
152
|
|
|
152
|
-
//
|
|
153
|
+
// Good: GET /api/users
|
|
153
154
|
export async function GET(request: NextRequest) {
|
|
154
155
|
try {
|
|
155
156
|
const users = await db.user.findMany();
|
|
@@ -162,7 +163,7 @@ export async function GET(request: NextRequest) {
|
|
|
162
163
|
}
|
|
163
164
|
}
|
|
164
165
|
|
|
165
|
-
//
|
|
166
|
+
// Good: POST /api/users
|
|
166
167
|
export async function POST(request: NextRequest) {
|
|
167
168
|
try {
|
|
168
169
|
const body = await request.json();
|
|
@@ -183,7 +184,7 @@ export async function POST(request: NextRequest) {
|
|
|
183
184
|
}
|
|
184
185
|
|
|
185
186
|
// app/api/users/[id]/route.ts
|
|
186
|
-
//
|
|
187
|
+
// Good: GET /api/users/:id
|
|
187
188
|
export async function GET(
|
|
188
189
|
request: NextRequest,
|
|
189
190
|
{ params }: { params: { id: string } }
|
|
@@ -203,7 +204,7 @@ export async function GET(
|
|
|
203
204
|
### 5. Metadata & SEO
|
|
204
205
|
|
|
205
206
|
```typescript
|
|
206
|
-
//
|
|
207
|
+
// Good: Static metadata
|
|
207
208
|
import { Metadata } from 'next';
|
|
208
209
|
|
|
209
210
|
export const metadata: Metadata = {
|
|
@@ -216,7 +217,7 @@ export const metadata: Metadata = {
|
|
|
216
217
|
},
|
|
217
218
|
};
|
|
218
219
|
|
|
219
|
-
//
|
|
220
|
+
// Good: Dynamic metadata
|
|
220
221
|
export async function generateMetadata({
|
|
221
222
|
params,
|
|
222
223
|
}: {
|
|
@@ -238,7 +239,7 @@ export async function generateMetadata({
|
|
|
238
239
|
### 6. Streaming & Suspense
|
|
239
240
|
|
|
240
241
|
```typescript
|
|
241
|
-
//
|
|
242
|
+
// Good: Streaming for fast initial render
|
|
242
243
|
import { Suspense } from 'react';
|
|
243
244
|
|
|
244
245
|
export default function Dashboard() {
|
|
@@ -246,10 +247,10 @@ export default function Dashboard() {
|
|
|
246
247
|
<div>
|
|
247
248
|
<h1>Dashboard</h1>
|
|
248
249
|
|
|
249
|
-
{/*
|
|
250
|
+
{/* Fast component renders first */}
|
|
250
251
|
<QuickStats />
|
|
251
252
|
|
|
252
|
-
{/*
|
|
253
|
+
{/* Slow component streams later */}
|
|
253
254
|
<Suspense fallback={<ChartSkeleton />}>
|
|
254
255
|
<SlowChart />
|
|
255
256
|
</Suspense>
|
|
@@ -270,7 +271,7 @@ async function SlowChart() {
|
|
|
270
271
|
### 7. Server Actions
|
|
271
272
|
|
|
272
273
|
```typescript
|
|
273
|
-
//
|
|
274
|
+
// Good: Server Action (runs only on server)
|
|
274
275
|
'use server';
|
|
275
276
|
|
|
276
277
|
import { revalidatePath } from 'next/cache';
|
|
@@ -279,18 +280,18 @@ export async function createUser(formData: FormData) {
|
|
|
279
280
|
const email = formData.get('email') as string;
|
|
280
281
|
const name = formData.get('name') as string;
|
|
281
282
|
|
|
282
|
-
//
|
|
283
|
+
// Direct DB access on server
|
|
283
284
|
const user = await db.user.create({
|
|
284
285
|
data: { email, name },
|
|
285
286
|
});
|
|
286
287
|
|
|
287
|
-
//
|
|
288
|
+
// Cache revalidation
|
|
288
289
|
revalidatePath('/users');
|
|
289
290
|
|
|
290
291
|
return user;
|
|
291
292
|
}
|
|
292
293
|
|
|
293
|
-
//
|
|
294
|
+
// Good: Usage on client
|
|
294
295
|
'use client';
|
|
295
296
|
|
|
296
297
|
import { createUser } from './actions';
|
|
@@ -309,19 +310,19 @@ export function CreateUserForm() {
|
|
|
309
310
|
### 8. Middleware
|
|
310
311
|
|
|
311
312
|
```typescript
|
|
312
|
-
// middleware.ts (
|
|
313
|
+
// middleware.ts (root)
|
|
313
314
|
import { NextResponse } from 'next/server';
|
|
314
315
|
import type { NextRequest } from 'next/server';
|
|
315
316
|
|
|
316
317
|
export function middleware(request: NextRequest) {
|
|
317
|
-
//
|
|
318
|
+
// Auth check
|
|
318
319
|
const token = request.cookies.get('token')?.value;
|
|
319
320
|
|
|
320
321
|
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
|
|
321
322
|
return NextResponse.redirect(new URL('/login', request.url));
|
|
322
323
|
}
|
|
323
324
|
|
|
324
|
-
//
|
|
325
|
+
// Add headers
|
|
325
326
|
const response = NextResponse.next();
|
|
326
327
|
response.headers.set('X-Custom-Header', 'value');
|
|
327
328
|
|
|
@@ -333,14 +334,14 @@ export const config = {
|
|
|
333
334
|
};
|
|
334
335
|
```
|
|
335
336
|
|
|
336
|
-
### 9.
|
|
337
|
+
### 9. Environment Variables
|
|
337
338
|
|
|
338
339
|
```typescript
|
|
339
|
-
//
|
|
340
|
-
const dbUrl = process.env.DATABASE_URL; //
|
|
340
|
+
// Good: Server-only environment variables
|
|
341
|
+
const dbUrl = process.env.DATABASE_URL; // Server components only
|
|
341
342
|
const apiKey = process.env.API_SECRET_KEY;
|
|
342
343
|
|
|
343
|
-
//
|
|
344
|
+
// Good: Client-exposed environment variables (NEXT_PUBLIC_ prefix)
|
|
344
345
|
const publicUrl = process.env.NEXT_PUBLIC_API_URL;
|
|
345
346
|
|
|
346
347
|
// .env.local
|
|
@@ -349,12 +350,12 @@ API_SECRET_KEY=secret123
|
|
|
349
350
|
NEXT_PUBLIC_API_URL=https://api.example.com
|
|
350
351
|
```
|
|
351
352
|
|
|
352
|
-
### 10.
|
|
353
|
+
### 10. Image Optimization
|
|
353
354
|
|
|
354
355
|
```typescript
|
|
355
356
|
import Image from 'next/image';
|
|
356
357
|
|
|
357
|
-
//
|
|
358
|
+
// Good: Next.js Image component (auto optimization)
|
|
358
359
|
export function UserAvatar({ user }: { user: User }) {
|
|
359
360
|
return (
|
|
360
361
|
<Image
|
|
@@ -362,12 +363,12 @@ export function UserAvatar({ user }: { user: User }) {
|
|
|
362
363
|
alt={user.name}
|
|
363
364
|
width={100}
|
|
364
365
|
height={100}
|
|
365
|
-
priority // LCP
|
|
366
|
+
priority // priority for LCP images
|
|
366
367
|
/>
|
|
367
368
|
);
|
|
368
369
|
}
|
|
369
370
|
|
|
370
|
-
//
|
|
371
|
+
// Good: External images (requires next.config.js configuration)
|
|
371
372
|
// next.config.js
|
|
372
373
|
module.exports = {
|
|
373
374
|
images: {
|
|
@@ -376,66 +377,66 @@ module.exports = {
|
|
|
376
377
|
};
|
|
377
378
|
```
|
|
378
379
|
|
|
379
|
-
##
|
|
380
|
+
## Anti-patterns
|
|
380
381
|
|
|
381
382
|
```typescript
|
|
382
|
-
//
|
|
383
|
+
// Bad: Server-only code in Client Component
|
|
383
384
|
'use client';
|
|
384
385
|
|
|
385
386
|
function BadComponent() {
|
|
386
|
-
const data = await db.user.findMany(); //
|
|
387
|
+
const data = await db.user.findMany(); // Bad: Cannot access DB from client
|
|
387
388
|
}
|
|
388
389
|
|
|
389
|
-
//
|
|
390
|
+
// Bad: Browser API in Server Component
|
|
390
391
|
async function BadServerComponent() {
|
|
391
|
-
const width = window.innerWidth; //
|
|
392
|
+
const width = window.innerWidth; // Bad: window only exists in browser
|
|
392
393
|
}
|
|
393
394
|
|
|
394
|
-
//
|
|
395
|
+
// Bad: Calling API Route from another API Route
|
|
395
396
|
export async function GET() {
|
|
396
|
-
const response = await fetch('http://localhost:3000/api/users'); //
|
|
397
|
-
//
|
|
398
|
-
const users = await getUsers(); //
|
|
397
|
+
const response = await fetch('http://localhost:3000/api/users'); // Bad
|
|
398
|
+
// Instead, call DB function directly
|
|
399
|
+
const users = await getUsers(); // Good
|
|
399
400
|
}
|
|
400
401
|
|
|
401
|
-
//
|
|
402
|
+
// Bad: Exposing environment variables
|
|
402
403
|
'use client';
|
|
403
404
|
|
|
404
405
|
function BadClient() {
|
|
405
|
-
const apiKey = process.env.API_SECRET_KEY; //
|
|
406
|
+
const apiKey = process.env.API_SECRET_KEY; // Bad: undefined (on client)
|
|
406
407
|
}
|
|
407
408
|
```
|
|
408
409
|
|
|
409
|
-
##
|
|
410
|
+
## Performance Optimization
|
|
410
411
|
|
|
411
412
|
```typescript
|
|
412
|
-
//
|
|
413
|
+
// Good: Static Generation (SSG)
|
|
413
414
|
export async function generateStaticParams() {
|
|
414
415
|
const posts = await getPosts();
|
|
415
416
|
return posts.map(post => ({ id: post.id }));
|
|
416
417
|
}
|
|
417
418
|
|
|
418
|
-
//
|
|
419
|
-
export const revalidate = 60; // 60
|
|
419
|
+
// Good: Incremental Static Regeneration (ISR)
|
|
420
|
+
export const revalidate = 60; // Regenerate every 60 seconds
|
|
420
421
|
|
|
421
|
-
//
|
|
422
|
+
// Good: Dynamic Rendering (SSR)
|
|
422
423
|
export const dynamic = 'force-dynamic';
|
|
423
424
|
|
|
424
|
-
//
|
|
425
|
+
// Good: Partial Prerendering (experimental)
|
|
425
426
|
export const experimental_ppr = true;
|
|
426
427
|
```
|
|
427
428
|
|
|
428
|
-
##
|
|
429
|
+
## Checklist
|
|
429
430
|
|
|
430
|
-
Next.js
|
|
431
|
+
When writing Next.js code:
|
|
431
432
|
|
|
432
|
-
- [ ] App Router
|
|
433
|
-
- [ ]
|
|
434
|
-
- [ ]
|
|
435
|
-
- [ ]
|
|
436
|
-
- [ ] Suspense
|
|
437
|
-
- [ ] Next.js Image
|
|
438
|
-
- [ ]
|
|
439
|
-
- [ ]
|
|
440
|
-
- [ ]
|
|
441
|
-
- [ ] TypeScript
|
|
433
|
+
- [ ] Use App Router (avoid Pages Router)
|
|
434
|
+
- [ ] Server Components first (minimize client)
|
|
435
|
+
- [ ] Consider Server Actions instead of API Routes
|
|
436
|
+
- [ ] Define metadata (SEO)
|
|
437
|
+
- [ ] Streaming with Suspense
|
|
438
|
+
- [ ] Use Next.js Image component
|
|
439
|
+
- [ ] Use environment variables correctly
|
|
440
|
+
- [ ] Auth/permission check with Middleware
|
|
441
|
+
- [ ] Configure caching strategy (revalidate)
|
|
442
|
+
- [ ] TypeScript strict mode
|