feat(init): detect css modules and auto-install compatibility workarounds - #3059
feat(init): detect css modules and auto-install compatibility workarounds#3059NriotHrreion wants to merge 1 commit into
Conversation
commit: |
Performance benchmarksCompared 0 improved · 0 regressed · 6 within ±1.5%
View detailed results and traces 🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1114197494
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const plugins = findProperty(config, "plugins"); | ||
| if (!plugins) { | ||
| const indent = objectPropertyIndent(config, code); | ||
| insertObjectProperty(output, config, `${indent}plugins: [${expression}],`, code, true); |
There was a problem hiding this comment.
Preserve plugins supplied through config spreads
For a Node-target CSS Modules project whose config is composed as export default { ...sharedConfig }, findProperty sees no direct plugins property, so this branch appends plugins: [patchCssModules()] after the spread. That replaces rather than extends sharedConfig.plugins, potentially removing vinext, React, and other required plugins from the effective Vite config. Detect and merge spread-provided plugins, or reject this ambiguous shape instead of silently overwriting them.
Useful? React with 👍 / 👎.
| } else if (hasCssModules && existingViteConfigPath) { | ||
| updateViteConfigForCssModules( | ||
| existingViteConfigPath, | ||
| fs.readFileSync(existingViteConfigPath, "utf-8"), | ||
| ); |
There was a problem hiding this comment.
Let
--force bypass CSS config validation
When --platform=node --force is used in a CSS Modules project, this preflight still parses and validates the existing config before setupNodePlatform can replace it. Thus an unsupported existing shape such as css: getCss() throws even though --force is specifically the recovery path for overwriting a Node-target Vite config; gate this validation on !options.force so replacement can proceed.
Useful? React with 👍 / 👎.
Closes #2992
Overview
Vite scopes CSS Modules before running user PostCSS plugins, which differs from Next.js and can silently break transformations that depend on original selectors, such as
postcss-extend-rule.vite-css-modulesrestores the expected processing order, but its default class-name hashing can produce different results across vinext's separate server and client environments (see #2992 (comment)).This PR makes CSS Modules projects work consistently by automatically setting up
vite-css-modulesand deterministic, project-relative class names, preserving PostCSS behavior while preventing server/client class-name mismatches in development and production builds.What changed
vinext init, scan the original Next.js project folder for css modules, if there is, enable the css modules compatibility setup path.vite-css-moduleswill be installed as a devDependency.vite-css-moduleswill be added to vite config as a plugin, along with thegenerateScopedName()config.Verification
vite-css-modulesis verified in the PR test(css): css module compatibility issue and workaround verification #3000pnpm test tests/init.test.ts tests/init-cloudflare.test.tsQuestion
Should we add an option (maybe a cli flag) to let developers decide whether to apply the css modules compatibility setup?