Skip to content

Commit 555bb2d

Browse files
hi-ogawaclaude
andcommitted
docs(plugin-rsc): add contributing guide with dev tips
Add comprehensive contributing guide for @vitejs/plugin-rsc covering: - New e2e testing approach using setupInlineFixture - Development workflow and testing patterns - Common patterns for server actions, HMR, CSS testing - Tips for contributors and coding agents Also add link from root CONTRIBUTING.md to plugin-rsc guide. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 26326b3 commit 555bb2d

File tree

2 files changed

+255
-0
lines changed

2 files changed

+255
-0
lines changed

CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ Some errors are masked and hidden away because of the layers of abstraction and
127127

128128
6. To close everything, just stop the test process back in your terminal.
129129

130+
## Package-Specific Contributing Guides
131+
132+
- [RSC Plugin Contributing Guide](./packages/plugin-rsc/CONTRIBUTING.md) - Development tips for @vitejs/plugin-rsc
133+
130134
## Note on Test Dependencies
131135

132136
In many test cases, we need to mock dependencies using `link:` and `file:` protocols. `pnpm` treats `link:` as symlinks and `file:` as hardlinks. To test dependencies as if they were copied into `node_modules`, use the `file:` protocol. Otherwise, use the `link:` protocol.
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
# Contributing to @vitejs/plugin-rsc
2+
3+
This guide provides essential tips for contributors working on the RSC plugin.
4+
5+
## Project Structure
6+
7+
- `src/` - Plugin source code
8+
- `examples/` - Example projects for testing and documentation
9+
- `e2e/` - End-to-end tests using Playwright
10+
- `types/` - TypeScript type definitions
11+
12+
## Testing
13+
14+
### E2E Test Setup
15+
16+
The e2e testing uses a scalable approach inspired by React Router's integration tests. Tests use Playwright and are located in `e2e/`.
17+
18+
#### Test Fixture Patterns
19+
20+
**1. Using existing examples directly:**
21+
22+
```typescript
23+
// Test against existing example projects
24+
const f = useFixture({ root: 'examples/basic', mode: 'dev' })
25+
```
26+
27+
**2. Creating isolated fixtures (full copy):**
28+
29+
```typescript
30+
// For tests that need to modify files
31+
test.beforeAll(async () => {
32+
await setupIsolatedFixture({
33+
src: 'examples/basic',
34+
dest: 'examples/e2e/temp/my-test',
35+
})
36+
})
37+
```
38+
39+
**3. Creating inline fixtures (recommended for new tests):**
40+
41+
```typescript
42+
// For creating test-specific variations
43+
test.beforeAll(async () => {
44+
await setupInlineFixture({
45+
src: 'examples/starter',
46+
dest: 'examples/e2e/temp/my-test',
47+
files: {
48+
'src/root.tsx': /* tsx */ `
49+
export function Root() {
50+
return <div>Custom test content</div>
51+
}
52+
`,
53+
'src/client.tsx': /* tsx */ `
54+
"use client";
55+
export function MyComponent() {
56+
return <span>Client component</span>
57+
}
58+
`,
59+
},
60+
})
61+
})
62+
```
63+
64+
The new test structure uses:
65+
66+
- `examples/e2e/temp/` as base directory for test projects
67+
- `setupInlineFixture` utility for creating test environments
68+
- `examples/starter` as the lightweight base template (faster than `examples/basic`)
69+
- Each test project is runnable locally: `pnpm -C packages/plugin-rsc/examples/e2e/temp/my-test dev`
70+
71+
### Adding New Test Cases
72+
73+
#### Option 1: Using `setupInlineFixture` (Recommended)
74+
75+
Best for testing specific features or edge cases:
76+
77+
```typescript
78+
import { setupInlineFixture, useFixture } from './fixture'
79+
80+
test.describe('my-feature', () => {
81+
const root = 'examples/e2e/temp/my-feature'
82+
83+
test.beforeAll(async () => {
84+
await setupInlineFixture({
85+
src: 'examples/starter', // Base template
86+
dest: root,
87+
files: {
88+
// Override/add specific files for your test
89+
'vite.config.ts': /* js */ `
90+
import rsc from '@vitejs/plugin-rsc'
91+
export default {
92+
plugins: [rsc({ /* test options */ })]
93+
}
94+
`,
95+
'src/test-component.tsx': /* tsx */ `
96+
"use client";
97+
export function TestComponent() {
98+
return <div data-testid="test">Hello</div>
99+
}
100+
`,
101+
},
102+
})
103+
})
104+
105+
test.describe('dev', () => {
106+
const f = useFixture({ root, mode: 'dev' })
107+
// Your tests here
108+
})
109+
110+
test.describe('build', () => {
111+
const f = useFixture({ root, mode: 'build' })
112+
// Your tests here
113+
})
114+
})
115+
```
116+
117+
#### Option 2: Expanding `examples/basic`
118+
119+
Best for comprehensive features that should be part of the main test suite:
120+
121+
1. Add your test case files to `examples/basic/src/routes/`
122+
2. Update the routing in `examples/basic/src/routes/root.tsx`
123+
3. Add corresponding tests in `e2e/basic.test.ts`
124+
125+
### Test Utilities
126+
127+
Key helper functions available in `e2e/helper.ts`:
128+
129+
- `waitForHydration(page)` - Wait for React hydration to complete
130+
- `expectNoReload(page)` - Ensure no page reload during operations
131+
- `expectNoPageError(page)` - Assert no JavaScript errors
132+
- `testNoJs` - Test variant with JavaScript disabled
133+
134+
### Running Tests
135+
136+
```bash
137+
# Run all e2e tests
138+
pnpm test:e2e
139+
140+
# Run specific test file
141+
pnpm test:e2e basic
142+
143+
# Run with debug output
144+
TEST_DEBUG=1 pnpm test:e2e
145+
146+
# Skip build step (faster during development)
147+
TEST_SKIP_BUILD=1 pnpm test:e2e
148+
```
149+
150+
## Development Workflow
151+
152+
### Local Development
153+
154+
1. Make changes to plugin source code in `src/`
155+
2. Test changes using existing examples:
156+
```bash
157+
cd examples/starter
158+
pnpm dev
159+
```
160+
3. Run e2e tests to ensure no regressions
161+
4. Add new tests for new features using `setupInlineFixture`
162+
163+
### Plugin Configuration Testing
164+
165+
When testing plugin options, create focused inline fixtures:
166+
167+
```typescript
168+
await setupInlineFixture({
169+
src: 'examples/starter',
170+
dest: root,
171+
files: {
172+
'vite.config.ts': /* js */ `
173+
import rsc from '@vitejs/plugin-rsc'
174+
export default {
175+
plugins: [
176+
rsc({
177+
// Test specific plugin options here
178+
loadModuleDevProxy: true,
179+
rscCssTransform: { filter: id => id.includes('test') }
180+
})
181+
]
182+
}
183+
`,
184+
},
185+
})
186+
```
187+
188+
### CSS and Style Testing
189+
190+
CSS handling is a key feature. Test CSS injection patterns:
191+
192+
```typescript
193+
files: {
194+
'src/styles.css': /* css */ `
195+
.test-class { color: red; }
196+
`,
197+
'src/component.tsx': /* tsx */ `
198+
import './styles.css'
199+
export function Component() {
200+
return <div className="test-class">Styled</div>
201+
}
202+
`
203+
}
204+
```
205+
206+
## Common Testing Patterns
207+
208+
### Server Actions Testing
209+
210+
```typescript
211+
files: {
212+
'src/actions.tsx': /* tsx */ `
213+
"use server";
214+
export async function myAction(formData: FormData) {
215+
return { success: true }
216+
}
217+
`,
218+
'src/form.tsx': /* tsx */ `
219+
import { myAction } from './actions'
220+
export function Form() {
221+
return <form action={myAction}>...</form>
222+
}
223+
`
224+
}
225+
```
226+
227+
### HMR Testing
228+
229+
Use the `expectNoReload` pattern and file editors:
230+
231+
```typescript
232+
test('hmr works', async ({ page }) => {
233+
using _ = await expectNoReload(page)
234+
const editor = f.createEditor('src/component.tsx')
235+
236+
await page.goto(f.url())
237+
editor.edit((content) => content.replace('Hello', 'Hi'))
238+
239+
await expect(page.locator('[data-testid="greeting"]')).toHaveText('Hi')
240+
})
241+
```
242+
243+
## Tips
244+
245+
- Use `/* tsx */` and `/* css */` comments for syntax highlighting in template literals
246+
- Prefer `setupInlineFixture` for new tests - it's more maintainable and faster
247+
- Always test both dev and build modes when adding new features
248+
- Use `TEST_DEBUG=1` to see detailed output during test development
249+
- Test projects are locally runnable for debugging: `pnpm -C packages/plugin-rsc/examples/e2e/temp/my-test dev`
250+
- The `examples/basic` project contains comprehensive test scenarios - study it for inspiration
251+
- Dependencies for temp test projects are managed in `examples/e2e/package.json`

0 commit comments

Comments
 (0)