feat: add CJS support via vite-plugin-commonjs (#198)
* feat: add CJS support via vite-plugin-commonjs
Add vite-plugin-commonjs to handle require() and module.exports in
both App Router and Pages Router. This enables CJS interop in server
components and pages, including CJS require('server-only') boundary
enforcement by @vitejs/plugin-rsc.
- Add vite-plugin-commonjs as a dependency and register it in the plugin array
- Add App Router fixtures: CJS basic, CJS server-only, CJS server-only
violation (client component importing server-only module)
- Add Pages Router fixture: CJS basic (require/module.exports)
- Add integration tests for both routers (cjs.test.ts)
- Add App Router e2e tests for CJS rendering and server-only boundary
enforcement (tests/e2e/app-router/cjs.spec.ts)
- Add Pages Router e2e test for CJS rendering
(tests/e2e/pages-router/cjs.spec.ts)
* fix: use buildViteConfig() for Pages Router production builds
The Pages Router build path hardcoded plugins: [vinext()] in inline
config, duplicating plugins when a vite.config.ts also registers
vinext(). This caused double-transformation errors during production
builds. Use buildViteConfig() instead, matching the App Router path
which already handles this correctly.
* fix: move server-only-violation fixture to isolated directory
The server-only-violation fixture causes a fatal build error during
production builds of app-basic (the RSC plugin rejects the intentional
violation). This breaks unrelated tests in app-router.test.ts.
Move the fixture to tests/fixtures/app-cjs-violation/ so it doesn't
poison the shared app-basic production build. Remove the E2E test case
since it requires the app-basic dev server; the server-only boundary
enforcement for CJS require() is verified by the RSC plugin's build
validation.
* fix: address review feedback from bonk
- Remove unused components/random.tsx (dead code, Pages Router CJS test
uses pages/cjs/random.ts instead)
- Add trailing newlines to fixture files
- Move commonjs() plugin earlier in array (after tsconfigPaths, before
vinext:config) so CJS->ESM transform runs before directive scanning
- Tighten test assertions: use regex for 'Random:.*4' to be specific
while handling React SSR comment nodes between text and expressions
---------
Co-authored-by: Steve Faulkner <sfaulkner@cloudflare.com>