Skip to content

Commit 6d56517

Browse files
committed
added CLAUDE.md
1 parent 647a997 commit 6d56517

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed

CLAUDE.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This is `@nette/vite-plugin` - a Vite plugin that integrates Vite with Nette Framework and Latte templating engine. The plugin handles:
8+
9+
- Asset management between Vite's dev server and Nette applications
10+
- Dev server URL communication via JSON info file (`nette.json`)
11+
- Default configuration optimized for Nette project structure
12+
- CORS configuration for dev server integration
13+
14+
## Commands
15+
16+
```bash
17+
# Build TypeScript to JavaScript (compiles src/ to dist/)
18+
npm run build
19+
20+
# Run all tests
21+
npm test
22+
23+
# Run linter
24+
npm run lint
25+
26+
# Auto-fix linting issues
27+
npm run lint:fix
28+
```
29+
30+
## Architecture
31+
32+
### Plugin Lifecycle
33+
34+
The plugin implements three Vite hooks in sequence:
35+
36+
1. **`config` hook**: Applies Nette-specific defaults before Vite resolves configuration
37+
- Sets `root` to `assets/` directory
38+
- Sets `build.outDir` to `www/assets/` (validates `www/` exists)
39+
- Configures CORS for dev server integration
40+
- Resolves entry points from plugin config
41+
42+
2. **`configResolved` hook**: Stores resolved Vite configuration for use in other hooks
43+
44+
3. **`configureServer` hook**: Sets up dev server info file generation
45+
- Only runs in `serve` mode (not during build)
46+
- Attaches listeners to HTTP server lifecycle
47+
48+
### Info File Mechanism
49+
50+
**Purpose**: Communicates dev server URL from Vite to Nette/PHP backend
51+
52+
**Flow**:
53+
- When dev server starts listening → writes `www/assets/.vite/nette.json` with `devServer` URL
54+
- Updates `resolvedConfig.server.origin` to the same URL (critical for asset references)
55+
- When server closes → removes the JSON file
56+
- SIGINT handler ensures cleanup on Ctrl+C
57+
58+
**File structure**:
59+
```json
60+
{
61+
"devServer": "http://localhost:5173"
62+
}
63+
```
64+
65+
**Why `server.origin` matters**: Setting this ensures that asset references in CSS/JS (images, fonts, etc.) load from the dev server URL instead of attempting to load from the backend. Without this, imported assets would 404 during development.
66+
67+
### Configuration Philosophy
68+
69+
The plugin provides **convention over configuration** optimized for Nette Framework projects:
70+
71+
- **Default `root`**: `assets/` (Nette convention for source assets)
72+
- **Default `outDir`**: `www/assets/` (requires `www/` directory to exist - throws error if missing)
73+
- **Default `base`**: empty string (assets served from document root, not subdirectory)
74+
- **Default `publicDir`**: `public/` relative to root (static files copied as-is to outDir)
75+
- **Manifest**: enabled by default (required for Nette Assets to resolve hashed filenames)
76+
- **Assets directory**: empty string (no subdirectory like `/static`, files output directly to `outDir`)
77+
78+
All defaults can be overridden via user's `vite.config.js`.
79+
80+
**Design rationale**: These defaults match standard Nette project structure where `www/` is the document root and contains an `assets/` subdirectory for compiled frontend files. Source assets live in project root's `assets/` folder to keep them separate from the public web directory.
81+
82+
### Entry Point Resolution
83+
84+
When `entry` option is provided:
85+
- Single string: converted to array with one resolved path
86+
- Array: each entry resolved relative to `root`
87+
- Absolute paths: used as-is without prefix
88+
- Result becomes `build.rollupOptions.input`
89+
90+
### CORS Strategy
91+
92+
The plugin configures CORS to allow:
93+
1. Vite's default allowed origins
94+
2. The project's own host (http/https depending on config)
95+
96+
This enables the Nette backend to fetch assets from Vite dev server during development.
97+
98+
**Why automatic CORS is needed**: Even when Vite runs on the same hostname as the PHP app (e.g., `myapp.local`), CORS is required because the dev server runs on a different port. The plugin automatically includes the project's host in allowed origins to solve this.
99+
100+
### Integration with Nette Assets
101+
102+
The plugin bridges two operational modes:
103+
104+
**Development Mode** (when `nette.json` exists and app is in debug mode):
105+
- Vite dev server runs (`npm run dev`)
106+
- Plugin creates `www/assets/.vite/nette.json` with dev server URL
107+
- Nette Assets PHP library detects this file
108+
- Assets load directly from Vite dev server with Hot Module Replacement (HMR)
109+
- Template tag `{asset 'app.js'}``<script src="http://localhost:5173/app.js" type="module"></script>`
110+
111+
**Production Mode** (when `nette.json` doesn't exist):
112+
- Optimized build created (`npm run build`)
113+
- Vite generates `manifest.json` in `outDir/.vite/`
114+
- Nette Assets reads manifest to resolve hashed filenames
115+
- Template tag `{asset 'app.js'}``<script src="/assets/app-4a8f9c7.js" type="module"></script>`
116+
117+
### Asset Loading Constraints
118+
119+
Only these assets can be loaded via `{asset}` in production:
120+
121+
1. **Entry points** specified in plugin config's `entry` option
122+
2. **Public folder files** from `assets/public/` (copied as-is)
123+
3. **Dynamic imports** referenced by JavaScript/CSS (auto-discovered by Vite)
124+
125+
Regular files in `assets/` are **not** directly loadable unless imported by an entry point. This is by design - Vite only bundles assets that are part of the dependency graph.
126+
127+
## Testing Strategy
128+
129+
**Framework**: Mocha with Node's built-in `assert`
130+
131+
**Test organization**:
132+
- `index.test.ts`: Plugin configuration, hooks, and integration tests
133+
- `info-file.test.ts`: Info file generation, cleanup, and edge cases
134+
- `utils.ts`: Shared test utilities (temp directory cleanup)
135+
136+
**Key patterns**:
137+
- Each test creates isolated temp directory via `beforeEach`
138+
- Tests change `process.cwd()` to temp directory
139+
- `afterEach` cleanup restores original cwd and removes temp files
140+
- Mock HTTP server with event handlers to simulate Vite dev server
141+
- Asynchronous tests use callbacks for event-driven assertions
142+
143+
**Mock structure for server tests**:
144+
```typescript
145+
const mockDevServer = {
146+
httpServer: {
147+
on: (event, callback) => { /* simulate events */ },
148+
address: () => ({ port: 5173 })
149+
}
150+
};
151+
```
152+
153+
## TypeScript Configuration
154+
155+
- **Target**: ES2020
156+
- **Module**: ESNext (for Vite compatibility)
157+
- **Output**: `dist/` directory with declaration files
158+
- **Source**: `src/` directory (single file: `index.ts`)
159+
- **Strict mode**: Enabled
160+
161+
## Code Style
162+
163+
Uses `@nette/eslint-plugin` with TypeScript support:
164+
- Node.js and Mocha globals configured
165+
- Browser environment disabled (Node-only plugin)
166+
- Customized config via `nette.configs.customize()`
167+
168+
## Error Handling
169+
170+
**Validation**: Plugin validates that `www/` directory exists when using default `outDir`. Throws descriptive error if missing:
171+
```
172+
The output directory "www/assets" does not exist. Please set "build.outDir" in your Vite config.
173+
```
174+
175+
**Cleanup**: SIGINT handler ensures info file is removed even on abrupt termination.

0 commit comments

Comments
 (0)