packwise-skills 1.0.0 → 1.2.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 -23
- package/CLAUDE.md +25 -25
- package/LICENSE +21 -0
- package/README.md +404 -295
- package/audit.md +224 -224
- package/bin/packwise.js +322 -155
- package/install.sh +123 -0
- package/package.json +32 -31
- package/skill.md +944 -719
- package/sub-skills/ai/local-llm.md +183 -183
- package/sub-skills/ai/python-ml.md +164 -164
- package/sub-skills/backend/go-server.md +184 -184
- package/sub-skills/backend/java-spring.md +241 -241
- package/sub-skills/backend/node-server.md +164 -164
- package/sub-skills/backend/php-laravel.md +175 -175
- package/sub-skills/backend/python-server.md +164 -164
- package/sub-skills/backend/rust-backend.md +118 -118
- package/sub-skills/cli/python-cli.md +236 -236
- package/sub-skills/cli/sdk-library.md +497 -497
- package/sub-skills/cloud/ci-cd-pipelines.md +350 -350
- package/sub-skills/cloud/docker.md +191 -191
- package/sub-skills/cloud/kubernetes.md +277 -277
- package/sub-skills/cloud/payment-integration.md +307 -307
- package/sub-skills/cross-platform/multiplatform.md +252 -252
- package/sub-skills/desktop/electron.md +783 -783
- package/sub-skills/desktop/game-dev.md +443 -443
- package/sub-skills/desktop/native-app.md +123 -123
- package/sub-skills/desktop/scenarios.md +443 -443
- package/sub-skills/desktop/smart-platforms.md +324 -324
- package/sub-skills/desktop/tauri.md +428 -428
- package/sub-skills/desktop/vr-ar.md +252 -252
- package/sub-skills/desktop/web-to-desktop.md +153 -153
- package/sub-skills/embedded/car-infotainment.md +129 -129
- package/sub-skills/embedded/esp32.md +184 -184
- package/sub-skills/embedded/ros.md +150 -150
- package/sub-skills/embedded/stm32.md +160 -160
- package/sub-skills/mobile/android.md +322 -322
- package/sub-skills/mobile/capacitor.md +232 -232
- package/sub-skills/mobile/flutter-mobile.md +138 -138
- package/sub-skills/mobile/harmonyos.md +150 -150
- package/sub-skills/mobile/ios.md +245 -245
- package/sub-skills/mobile/react-native.md +443 -443
- package/sub-skills/mobile/wearables.md +230 -230
- package/sub-skills/plugins/browser-extension.md +308 -308
- package/sub-skills/plugins/jetbrains-plugin.md +226 -226
- package/sub-skills/plugins/vscode-extension.md +204 -204
- package/sub-skills/security/security-tools.md +174 -174
- package/sub-skills/web/monorepo.md +274 -274
- package/sub-skills/web/pwa.md +220 -220
- package/sub-skills/web/serverless-edge.md +295 -295
- package/sub-skills/web/spa.md +266 -266
- package/sub-skills/web/ssr.md +228 -228
- package/sub-skills/web/wasm.md +243 -243
package/sub-skills/web/spa.md
CHANGED
|
@@ -1,266 +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 |
|
|
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 |
|