packwise-skills 1.0.0
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/.cursorrules +23 -0
- package/CLAUDE.md +25 -0
- package/README.md +295 -0
- package/audit.md +224 -0
- package/bin/packwise.js +155 -0
- package/package.json +31 -0
- package/skill.md +719 -0
- package/sub-skills/ai/local-llm.md +183 -0
- package/sub-skills/ai/python-ml.md +164 -0
- package/sub-skills/backend/go-server.md +184 -0
- package/sub-skills/backend/java-spring.md +241 -0
- package/sub-skills/backend/node-server.md +164 -0
- package/sub-skills/backend/php-laravel.md +175 -0
- package/sub-skills/backend/python-server.md +164 -0
- package/sub-skills/backend/rust-backend.md +118 -0
- package/sub-skills/cli/python-cli.md +236 -0
- package/sub-skills/cli/sdk-library.md +497 -0
- package/sub-skills/cloud/ci-cd-pipelines.md +350 -0
- package/sub-skills/cloud/docker.md +191 -0
- package/sub-skills/cloud/kubernetes.md +277 -0
- package/sub-skills/cloud/payment-integration.md +307 -0
- package/sub-skills/cross-platform/multiplatform.md +252 -0
- package/sub-skills/desktop/electron.md +783 -0
- package/sub-skills/desktop/game-dev.md +443 -0
- package/sub-skills/desktop/native-app.md +123 -0
- package/sub-skills/desktop/scenarios.md +443 -0
- package/sub-skills/desktop/smart-platforms.md +324 -0
- package/sub-skills/desktop/tauri.md +428 -0
- package/sub-skills/desktop/vr-ar.md +252 -0
- package/sub-skills/desktop/web-to-desktop.md +153 -0
- package/sub-skills/embedded/car-infotainment.md +129 -0
- package/sub-skills/embedded/esp32.md +184 -0
- package/sub-skills/embedded/ros.md +150 -0
- package/sub-skills/embedded/stm32.md +160 -0
- package/sub-skills/mobile/android.md +322 -0
- package/sub-skills/mobile/capacitor.md +232 -0
- package/sub-skills/mobile/flutter-mobile.md +138 -0
- package/sub-skills/mobile/harmonyos.md +150 -0
- package/sub-skills/mobile/ios.md +245 -0
- package/sub-skills/mobile/react-native.md +443 -0
- package/sub-skills/mobile/wearables.md +230 -0
- package/sub-skills/plugins/browser-extension.md +308 -0
- package/sub-skills/plugins/jetbrains-plugin.md +226 -0
- package/sub-skills/plugins/vscode-extension.md +204 -0
- package/sub-skills/security/security-tools.md +174 -0
- package/sub-skills/web/monorepo.md +274 -0
- package/sub-skills/web/pwa.md +220 -0
- package/sub-skills/web/serverless-edge.md +295 -0
- package/sub-skills/web/spa.md +266 -0
- package/sub-skills/web/ssr.md +228 -0
- package/sub-skills/web/wasm.md +243 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# SPA (Single Page Application) Build Sub-Skill
|
|
2
|
+
|
|
3
|
+
Build and package pure frontend projects (React/Vue/Angular/Svelte/Solid).
|
|
4
|
+
|
|
5
|
+
**Current versions**: Vite 8.x / Webpack 5 / Angular 19 / Svelte 5 (2025-2026)
|
|
6
|
+
|
|
7
|
+
> ⚠️ **Vite 8.x**: If upgrading from Vite 6, check the [Vite migration guide](https://vitejs.dev/guide/migration) for breaking changes in plugin API and configuration format. Verify `vite-plugin-pwa`, `vite-plugin-wasm`, and other plugins are compatible with v8.
|
|
8
|
+
|
|
9
|
+
## When to Use
|
|
10
|
+
|
|
11
|
+
- Pure frontend project (no backend in the same repo)
|
|
12
|
+
- Data from external API or localStorage
|
|
13
|
+
- University course work, graduation project, portfolio
|
|
14
|
+
- Enterprise website, showcase application
|
|
15
|
+
- Admin dashboards, internal tools
|
|
16
|
+
|
|
17
|
+
## Build Tools Comparison
|
|
18
|
+
|
|
19
|
+
| Tool | Speed | Config | HMR | Best For |
|
|
20
|
+
|------|-------|--------|-----|---------|
|
|
21
|
+
| **Vite 8** | Fastest | Minimal | Instant | New projects (default for Vue/React/Svelte) |
|
|
22
|
+
| **Webpack 5** | Moderate | Complex | Good | Legacy projects, complex builds |
|
|
23
|
+
| **esbuild** | Ultra fast | Minimal | N/A | Libraries, simple apps |
|
|
24
|
+
| **Turbopack** | Very fast | Next.js only | Fast | Next.js projects |
|
|
25
|
+
|
|
26
|
+
## Framework Builds
|
|
27
|
+
|
|
28
|
+
### Vite (React / Vue / Svelte / Solid)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Create project
|
|
32
|
+
npm create vite@latest my-app -- --template react-ts # React + TypeScript
|
|
33
|
+
npm create vite@latest my-app -- --template vue-ts # Vue + TypeScript
|
|
34
|
+
npm create vite@latest my-app -- --template svelte-ts # Svelte + TypeScript
|
|
35
|
+
|
|
36
|
+
# Build
|
|
37
|
+
npm run build
|
|
38
|
+
# Output: dist/ directory
|
|
39
|
+
|
|
40
|
+
# Preview production build locally
|
|
41
|
+
npm run preview
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
// vite.config.ts
|
|
46
|
+
import { defineConfig } from 'vite';
|
|
47
|
+
import react from '@vitejs/plugin-react';
|
|
48
|
+
|
|
49
|
+
export default defineConfig({
|
|
50
|
+
plugins: [react()],
|
|
51
|
+
base: '/', // Set for sub-directory deployment
|
|
52
|
+
build: {
|
|
53
|
+
outDir: 'dist',
|
|
54
|
+
sourcemap: false, // Disable for production
|
|
55
|
+
rolldownOptions: { // ⚠️ Vite 8: renamed from rollupOptions
|
|
56
|
+
output: {
|
|
57
|
+
// Vite 8: manualChunks object form removed. Use function form or codeSplitting.
|
|
58
|
+
manualChunks(id) {
|
|
59
|
+
if (id.includes('node_modules')) {
|
|
60
|
+
return 'vendor';
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
server: {
|
|
67
|
+
proxy: { // Dev proxy to avoid CORS
|
|
68
|
+
'/api': 'http://localhost:3000',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Angular
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Build
|
|
78
|
+
ng build --configuration=production
|
|
79
|
+
# Output: dist/my-app/
|
|
80
|
+
|
|
81
|
+
# With SSR
|
|
82
|
+
ng build --configuration=production
|
|
83
|
+
ng run my-app:server:production
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### React (Create React App — Legacy)
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# CRA is no longer recommended for new projects; use Vite instead
|
|
90
|
+
npx create-react-app my-app # Legacy
|
|
91
|
+
npm run build
|
|
92
|
+
# Output: build/ directory
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Production Optimization Checklist
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
// vite.config.ts — production optimizations (Vite 8)
|
|
99
|
+
export default defineConfig({
|
|
100
|
+
build: {
|
|
101
|
+
// Vite 8: esbuild minification replaced by Oxc minifier
|
|
102
|
+
// To use terser for advanced control, install terser and set:
|
|
103
|
+
// minify: 'terser',
|
|
104
|
+
// terserOptions: { ... },
|
|
105
|
+
chunkSizeWarningLimit: 500, // Warn if chunk > 500KB
|
|
106
|
+
rolldownOptions: { // ⚠️ Vite 8: was rollupOptions
|
|
107
|
+
output: {
|
|
108
|
+
manualChunks(id) { // ⚠️ Vite 8: object form removed, use function
|
|
109
|
+
if (id.includes('node_modules')) {
|
|
110
|
+
return 'vendor';
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
// Vite 8: esbuild option deprecated, use oxc for JSX/define transforms
|
|
117
|
+
// esbuild: { drop: ['console', 'debugger'] }, // deprecated
|
|
118
|
+
// Use rolldownOptions.output.minify.compress.drop instead
|
|
119
|
+
css: {
|
|
120
|
+
modules: {
|
|
121
|
+
localsConvention: 'camelCase',
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
| Optimization | How | Impact |
|
|
128
|
+
|-------------|-----|--------|
|
|
129
|
+
| Tree shaking | Rolldown does this automatically (Vite 8) | Remove unused code |
|
|
130
|
+
| Code splitting | `manualChunks` function in Vite 8; `codeSplitting` in Rolldown | Smaller initial load |
|
|
131
|
+
| Lazy loading | `React.lazy()` / `defineAsyncComponent()` | On-demand loading |
|
|
132
|
+
| Asset compression | Brotli (`.br`) or Gzip (`.gz`) | 70-80% transfer size reduction |
|
|
133
|
+
| Image optimization | Use WebP/AVIF; `vite-plugin-imagemin` | 30-50% image size reduction |
|
|
134
|
+
| CSS purging | `purgecss` or built into Tailwind | Remove unused CSS |
|
|
135
|
+
| Preload/prefetch | `<link rel="preload">` for critical assets | Faster initial paint |
|
|
136
|
+
|
|
137
|
+
## Deployment Targets
|
|
138
|
+
|
|
139
|
+
| Platform | Method | Cost | Best For |
|
|
140
|
+
|----------|--------|------|----------|
|
|
141
|
+
| Vercel | Git push auto-deploy | Free tier | Personal/small team |
|
|
142
|
+
| Netlify | Git push auto-deploy | Free tier | Personal/small team |
|
|
143
|
+
| GitHub Pages | Git Actions auto-deploy | Free | Open source projects |
|
|
144
|
+
| Cloudflare Pages | Git push auto-deploy | Free tier | Global CDN, fast |
|
|
145
|
+
| Aliyun OSS + CDN | Upload dist/ | Pay-per-use | China access |
|
|
146
|
+
| Tencent COS + CDN | Upload dist/ | Pay-per-use | China access |
|
|
147
|
+
| AWS S3 + CloudFront | Upload dist/ | Pay-per-use | AWS ecosystem |
|
|
148
|
+
| Nginx | Manual deploy | Server cost | Self-hosted |
|
|
149
|
+
| Docker (nginx) | Containerize | Server cost | Containerized infrastructure |
|
|
150
|
+
|
|
151
|
+
### Vercel
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npm i -g vercel
|
|
155
|
+
vercel --prod
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Netlify
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npm i -g netlify-cli
|
|
162
|
+
netlify deploy --prod --dir=dist
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### GitHub Pages
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
# .github/workflows/deploy.yml
|
|
169
|
+
name: Deploy
|
|
170
|
+
on:
|
|
171
|
+
push:
|
|
172
|
+
branches: [main]
|
|
173
|
+
jobs:
|
|
174
|
+
deploy:
|
|
175
|
+
runs-on: ubuntu-latest
|
|
176
|
+
steps:
|
|
177
|
+
- uses: actions/checkout@v4
|
|
178
|
+
- uses: actions/setup-node@v4
|
|
179
|
+
with:
|
|
180
|
+
node-version: '22'
|
|
181
|
+
- run: npm ci && npm run build
|
|
182
|
+
- uses: peaceiris/actions-gh-pages@v4
|
|
183
|
+
with:
|
|
184
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
185
|
+
publish_dir: ./dist
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Nginx
|
|
189
|
+
|
|
190
|
+
```nginx
|
|
191
|
+
server {
|
|
192
|
+
listen 80;
|
|
193
|
+
server_name example.com;
|
|
194
|
+
root /var/www/myapp/dist;
|
|
195
|
+
index index.html;
|
|
196
|
+
|
|
197
|
+
# SPA routing (all routes → index.html)
|
|
198
|
+
location / {
|
|
199
|
+
try_files $uri $uri/ /index.html;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
# Cache static assets
|
|
203
|
+
location /assets/ {
|
|
204
|
+
expires 1y;
|
|
205
|
+
add_header Cache-Control "public, immutable";
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# Gzip compression
|
|
209
|
+
gzip on;
|
|
210
|
+
gzip_types text/css application/javascript application/json image/svg+xml;
|
|
211
|
+
gzip_min_length 1000;
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Docker
|
|
216
|
+
|
|
217
|
+
```dockerfile
|
|
218
|
+
FROM node:22-alpine AS builder
|
|
219
|
+
WORKDIR /app
|
|
220
|
+
COPY package*.json ./
|
|
221
|
+
RUN npm ci
|
|
222
|
+
COPY . .
|
|
223
|
+
RUN npm run build
|
|
224
|
+
|
|
225
|
+
FROM nginx:alpine
|
|
226
|
+
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
|
227
|
+
COPY --from=builder /app/dist /usr/share/nginx/html
|
|
228
|
+
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|
229
|
+
RUN chown -R appuser:appgroup /usr/share/nginx/html
|
|
230
|
+
USER appuser
|
|
231
|
+
EXPOSE 80
|
|
232
|
+
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:80/ || exit 1
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Environment Variables
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
# Vite: only VITE_ prefixed vars are exposed to client
|
|
239
|
+
VITE_API_URL=https://api.example.com
|
|
240
|
+
VITE_APP_TITLE=My App
|
|
241
|
+
|
|
242
|
+
# In code:
|
|
243
|
+
const apiUrl = import.meta.env.VITE_API_URL;
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# Angular: use environment.ts files
|
|
248
|
+
# Webpack: use process.env.REACT_APP_* (CRA) or DefinePlugin
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Common Pitfalls
|
|
252
|
+
|
|
253
|
+
| Issue | Fix |
|
|
254
|
+
|-------|-----|
|
|
255
|
+
| Refresh 404 on deploy | Nginx: `try_files $uri /index.html`; all hosting: configure SPA fallback |
|
|
256
|
+
| Path error after deploy | `vite.config.ts` set `base: '/subpath/'` for non-root deployment |
|
|
257
|
+
| CORS error in dev | Vite: `server.proxy`; Angular: `proxy.conf.json` |
|
|
258
|
+
| Env var not working | Vite: only `VITE_` prefix vars are bundled; Angular: use `environment.ts` |
|
|
259
|
+
| Large bundle (> 1MB) | Enable code splitting; lazy load routes; analyze with `rollup-plugin-visualizer` |
|
|
260
|
+
| White screen on deploy | Check browser console for errors; verify `base` path in config |
|
|
261
|
+
| CSS not loading | Check if CSS import path is correct; verify build output structure |
|
|
262
|
+
| Images not showing | Use `import` for images (Vite/Webpack process them); don't use string paths |
|
|
263
|
+
| Vite 8: `rollupOptions` not working | Renamed to `rolldownOptions` in Vite 8; see migration guide |
|
|
264
|
+
| Vite 8: esbuild options ignored | esbuild deprecated; use `oxc` for transforms, `rolldownOptions` for minification |
|
|
265
|
+
| Vite 8: `manualChunks` object form error | Object form removed; use function form or Rolldown `codeSplitting` |
|
|
266
|
+
| Vite 8: ES5 output fails | ES5 transformation no longer supported; target modern browsers only |
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# SSR (Server-Side Rendering) Build Sub-Skill
|
|
2
|
+
|
|
3
|
+
Build and package SSR frameworks (Next.js / Nuxt / Remix / SvelteKit / Astro).
|
|
4
|
+
|
|
5
|
+
**Current versions**: Next.js 16 / Nuxt 3.x / Remix 2.x / SvelteKit 2.x / Astro 5.x (2025-2026)
|
|
6
|
+
|
|
7
|
+
> ⚠️ **Next.js 16 Breaking Changes** (released Oct 2025):
|
|
8
|
+
> - **Turbopack is default bundler** — custom `webpack` configs will fail. Use `next build --webpack` to opt out.
|
|
9
|
+
> - `params` and `searchParams` must be `await`ed (synchronous access removed).
|
|
10
|
+
> - `cookies()` and `headers()` must be `await`ed.
|
|
11
|
+
> - **`middleware.ts` deprecated** → rename to `proxy.ts`, export `proxy` function (runs on Node.js, not Edge).
|
|
12
|
+
> - AMP support fully removed. `next lint` command removed.
|
|
13
|
+
> - `serverRuntimeConfig`/`publicRuntimeConfig` removed (use env vars).
|
|
14
|
+
> - `experimental.ppr` removed → use `cacheComponents: true`.
|
|
15
|
+
> - `next/image`: `minimumCacheTTL` default 60s→14400s, `qualities` default changed to `[75]` only.
|
|
16
|
+
> - Node.js 20.9+ required (Node 18 dropped). React 19.2.
|
|
17
|
+
> - Run `npx @next/codemod@canary upgrade latest` for automated migration.
|
|
18
|
+
|
|
19
|
+
## When to Use
|
|
20
|
+
|
|
21
|
+
- SEO-required websites (blogs, e-commerce, news, marketing)
|
|
22
|
+
- Dynamic pages needing server-side rendering
|
|
23
|
+
- Full-stack applications with API Routes
|
|
24
|
+
- Content-heavy sites with fast initial load
|
|
25
|
+
- Hybrid rendering (SSR + SSG + ISR)
|
|
26
|
+
|
|
27
|
+
## Framework Comparison
|
|
28
|
+
|
|
29
|
+
| Feature | Next.js 16 | Nuxt 3.x | Remix 2.x | SvelteKit 2.x | Astro 5.x |
|
|
30
|
+
|---------|-----------|---------|----------|--------------|----------|
|
|
31
|
+
| Base | React | Vue | React | Svelte | Any (React/Vue/Svelte/Solid) |
|
|
32
|
+
| Rendering | SSR/SSG/ISR/RSC | SSR/SSG/ISR | SSR | SSR/SSG | SSG + Islands |
|
|
33
|
+
| API Routes | App Router | Nitro server | Loaders/Actions | Server routes | Endpoints |
|
|
34
|
+
| Edge support | Yes (Vercel/CF) | Yes (Nitro) | Yes | Yes | Yes |
|
|
35
|
+
| Best for | Full-stack React | Full-stack Vue | Data-heavy apps | Lightweight full-stack | Content sites |
|
|
36
|
+
|
|
37
|
+
## Build
|
|
38
|
+
|
|
39
|
+
### Next.js
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Build
|
|
43
|
+
npm run build
|
|
44
|
+
# Output: .next/ directory
|
|
45
|
+
|
|
46
|
+
# Start production server
|
|
47
|
+
npm run start
|
|
48
|
+
|
|
49
|
+
# Static export (no server needed)
|
|
50
|
+
# next.config.js: output: 'export'
|
|
51
|
+
npm run build
|
|
52
|
+
# Output: out/ directory (can be deployed to any static host)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
// next.config.js
|
|
57
|
+
/** @type {import('next').NextConfig} */
|
|
58
|
+
const nextConfig = {
|
|
59
|
+
output: 'standalone', // Self-contained build with Node.js server
|
|
60
|
+
// output: 'export', // Static HTML export (no server)
|
|
61
|
+
images: {
|
|
62
|
+
unoptimized: true, // Required for static export
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
module.exports = nextConfig;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Nuxt
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Build
|
|
72
|
+
npm run build
|
|
73
|
+
# Output: .output/ directory (includes server)
|
|
74
|
+
|
|
75
|
+
# Static generation
|
|
76
|
+
npm run generate
|
|
77
|
+
# Output: .output/public/ directory
|
|
78
|
+
|
|
79
|
+
# Start production
|
|
80
|
+
node .output/server/index.mjs
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Remix
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Build
|
|
87
|
+
npm run build
|
|
88
|
+
# Output: build/ directory
|
|
89
|
+
|
|
90
|
+
# Start production
|
|
91
|
+
npm run start
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### SvelteKit
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Build (requires adapter)
|
|
98
|
+
npm run build
|
|
99
|
+
# Output depends on adapter (node/static/cloudflare/vercel)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
// svelte.config.js
|
|
104
|
+
import adapter from '@sveltejs/adapter-node'; // For Node.js server
|
|
105
|
+
// import adapter from '@sveltejs/adapter-static'; // For static export
|
|
106
|
+
// import adapter from '@sveltejs/adapter-vercel'; // For Vercel
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Astro
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Build (SSG by default)
|
|
113
|
+
npm run build
|
|
114
|
+
# Output: dist/ directory
|
|
115
|
+
|
|
116
|
+
# Build with SSR
|
|
117
|
+
# astro.config.mjs: output: 'server'
|
|
118
|
+
npm run build
|
|
119
|
+
# Output: dist/server/ + dist/client/
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
// astro.config.mjs
|
|
124
|
+
import { defineConfig } from 'astro/config';
|
|
125
|
+
import node from '@astrojs/node';
|
|
126
|
+
|
|
127
|
+
export default defineConfig({
|
|
128
|
+
output: 'server', // 'static' (default) or 'server'
|
|
129
|
+
adapter: node({ mode: 'standalone' }),
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Deployment Targets
|
|
134
|
+
|
|
135
|
+
| Platform | Next.js | Nuxt | Remix | SvelteKit | Astro |
|
|
136
|
+
|----------|---------|------|-------|----------|-------|
|
|
137
|
+
| Vercel | Native | Adapter | Native | Adapter | Adapter |
|
|
138
|
+
| Netlify | Adapter | Adapter | Adapter | Adapter | Adapter |
|
|
139
|
+
| Cloudflare Workers | Adapter | Nitro | Adapter | Adapter | Adapter |
|
|
140
|
+
| Docker (Node.js) | Standalone | Standard | Standard | Node adapter | Node adapter |
|
|
141
|
+
| Static hosting | `output: 'export'` | `generate` | N/A | Static adapter | Default |
|
|
142
|
+
| AWS Lambda | OpenNext | Nitro | Remix adapter | Adapter | Adapter |
|
|
143
|
+
|
|
144
|
+
## Docker (Next.js Standalone)
|
|
145
|
+
|
|
146
|
+
> ⚠️ **Next.js 16**: Turbopack is now the default bundler. If your project has custom `webpack` config, pass `--webpack` flag to `next build`. `serverRuntimeConfig`/`publicRuntimeConfig` removed — use env variables instead.
|
|
147
|
+
|
|
148
|
+
```dockerfile
|
|
149
|
+
FROM node:22-alpine AS builder
|
|
150
|
+
WORKDIR /app
|
|
151
|
+
COPY package*.json ./
|
|
152
|
+
RUN npm ci
|
|
153
|
+
COPY . .
|
|
154
|
+
RUN npm run build
|
|
155
|
+
|
|
156
|
+
FROM node:22-alpine
|
|
157
|
+
WORKDIR /app
|
|
158
|
+
# Standalone output includes minimal node_modules
|
|
159
|
+
COPY --from=builder /app/.next/standalone ./
|
|
160
|
+
COPY --from=builder /app/.next/static ./.next/static
|
|
161
|
+
COPY --from=builder /app/public ./public
|
|
162
|
+
RUN addgroup -S appgroup && adduser -S appuser -G appgroup && \
|
|
163
|
+
chown -R appuser:appgroup /app
|
|
164
|
+
USER appuser
|
|
165
|
+
EXPOSE 3000
|
|
166
|
+
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/ || exit 1
|
|
167
|
+
ENV NODE_ENV=production
|
|
168
|
+
CMD ["node", "server.js"]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Docker (Nuxt / Generic Node SSR)
|
|
172
|
+
|
|
173
|
+
```dockerfile
|
|
174
|
+
FROM node:22-alpine AS builder
|
|
175
|
+
WORKDIR /app
|
|
176
|
+
COPY package*.json ./
|
|
177
|
+
RUN npm ci
|
|
178
|
+
COPY . .
|
|
179
|
+
RUN npm run build
|
|
180
|
+
|
|
181
|
+
FROM node:22-alpine
|
|
182
|
+
WORKDIR /app
|
|
183
|
+
COPY --from=builder /app/.output ./.output
|
|
184
|
+
RUN addgroup -S appgroup && adduser -S appuser -G appgroup && \
|
|
185
|
+
chown -R appuser:appgroup /app
|
|
186
|
+
USER appuser
|
|
187
|
+
EXPOSE 3000
|
|
188
|
+
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/ || exit 1
|
|
189
|
+
CMD ["node", ".output/server/index.mjs"]
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## PM2 (Process Manager)
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
npm run build
|
|
196
|
+
pm2 start npm --name "myapp" -- start
|
|
197
|
+
pm2 save && pm2 startup
|
|
198
|
+
# Cluster mode:
|
|
199
|
+
pm2 start npm --name "myapp" -i max -- start
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Rendering Modes
|
|
203
|
+
|
|
204
|
+
| Mode | Description | Use Case |
|
|
205
|
+
|------|-------------|---------|
|
|
206
|
+
| **SSR** | Render on every request | Dynamic content, user-specific pages |
|
|
207
|
+
| **SSG** | Pre-render at build time | Static content, documentation |
|
|
208
|
+
| **ISR** | Re-render on interval (e.g., every 60s) | Blog posts, product pages |
|
|
209
|
+
| **Streaming SSR** | Stream HTML as it renders | Large pages, slow data sources |
|
|
210
|
+
| **Partial Prerender** | Static shell + dynamic holes | Mixed content (Next.js 14+) |
|
|
211
|
+
|
|
212
|
+
## Common Pitfalls
|
|
213
|
+
|
|
214
|
+
| Issue | Fix |
|
|
215
|
+
|-------|-----|
|
|
216
|
+
| Static resource 404 | Next.js: check `assetPrefix`; Nuxt: check `app.baseURL` |
|
|
217
|
+
| API Routes not working | Ensure Node.js >= 20.9; check runtime config for serverless |
|
|
218
|
+
| Env var leakage | Server vars should NOT have `NEXT_PUBLIC_` prefix (Next.js) |
|
|
219
|
+
| Memory leak in long-running | PM2: set `--max-memory-restart 500M`; check for event listener leaks |
|
|
220
|
+
| SSR hydration mismatch | Ensure server and client render identical HTML; avoid `Date.now()` in SSR |
|
|
221
|
+
| `getServerSideProps` slow | Add caching headers; use ISR; optimize database queries |
|
|
222
|
+
| Build fails with "out of memory" | Increase Node.js heap: `NODE_OPTIONS=--max-old-space-size=4096` |
|
|
223
|
+
| CSS flash on load (FOUC) | Extract CSS to files (default in most frameworks); avoid inline styles |
|
|
224
|
+
| Images not optimized | Next.js: use `<Image>` component; Nuxt: use `<NuxtImg>` |
|
|
225
|
+
| Next.js 16: Turbopack breaks build | Custom webpack config fails with Turbopack default; use `next build --webpack` |
|
|
226
|
+
| Next.js 16: params not awaited | `params`/`searchParams`/`cookies()`/`headers()` must be `await`ed |
|
|
227
|
+
| Next.js 16: middleware not found | Renamed to `proxy.ts`; export `proxy` function instead of `middleware` |
|
|
228
|
+
| Next.js 16: parallel route error | All parallel route slots now require explicit `default.js` files |
|