Automatically mock css module imports
See original GitHub issueClear and concise description of the problem
When using snapshots, any change to a module.(css|scss)
file will change the generated class.
This creates a massive amount of noise in commits and pr. This random class name behavior is not desirable in a testing context, where you want predictability.
I would be open to submitting a PR for this issue if that was desired.
Suggested solution
The object imported from a module.(css|scss)
file could be mocked to:
new Proxy(new Object(), {
get(_, style) {
return style;
},
});
This means that when a class is accessed, it returns the raw string, reproducably:
import styles from "./Renderer.module.scss";
console.log(styles.underline) // "underline"
Instead of the occasionally randomized variant:
import styles from "./Renderer.module.scss";
console.log(styles.underline) // "_underline_i69w2_32" (until someone modifies Renderer.module.scss)
Alternative
This can be solved in each test file, by just mocking the module.
vi.mock("./Renderer.module.scss", () => ({
default: new Proxy(new Object(), {
get(_, style) {
return style;
},
}),
}));
This is perfectly workable, but there is no reason a developer should need to do this - returning the same string every time is expected behavior in my opinion.
Additional context
Diffs where every class had its name changed (but nothing was actually changed) are massive, and can obscure actual changes - they suck. For example, if a pr includes a change to a css file and a modification to the classes of an object, the second change will be hidden behind the noise of the first, reducing the utility of the snapshot as a change detector.
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn’t already an issue that request the same feature to avoid creating a duplicate.
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:11 (6 by maintainers)
So, #1803 implements this logic:
module.*
exports a proxy in that case to not affect runtime (meaning,styles.{value}
will always return a key with filename hash)css.include
), css is processed and injected into DOMmodule.*
returns pseudo-scoped class names (styles.module
always returns_module_${filenameHash}
,styles.someRandomValue
will returnundefined
)css.modules.classNameStrategy: 'scoped'
css.modules.classNameStrategy
option:scoped
- usecss.modules.generateScopeName
from user config or fallback to default behaviour, this is how it works in dev and prodnon-scoped
- returns just the namestable
- returns the nama and hash, based on filepath, relative to rootIn case anyone else runs into this issue in the future – I got stuck here for while because I thought the option was:
But it’s actually:
The first one has no effect.