Skip to content

Commit

Permalink
chore: don't process module.css files, rename mangleClassName -> scop…
Browse files Browse the repository at this point in the history
…eClassNames
  • Loading branch information
sheremet-va committed Sep 3, 2022
1 parent 4265b85 commit 29a4754
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 26 deletions.
33 changes: 29 additions & 4 deletions docs/config/index.md
Expand Up @@ -679,14 +679,12 @@ Show heap usage after each test. Useful for debugging memory leaks.

- **Type**: `boolean | { include?, exclude? }`

Configure if CSS should be processed. When excluded, CSS files will be replaced with empty strings to bypass the subsequent processing.

By default, processes only CSS Modules, because it affects runtime. JSDOM and Happy DOM don't fully support injecting CSS, so disabling this setting might help with performance.
Configure if CSS should be processed. When excluded, CSS files will be replaced with empty strings to bypass the subsequent processing. CSS Modules will return a proxy to not affect runtime.

#### css.include

- **Type**: `RegExp | RegExp[]`
- **Default**: `[/\.module\./]`
- **Default**: `[]`

RegExp pattern for files that should return actual CSS and will be processed by Vite pipeline.

Expand All @@ -697,6 +695,33 @@ RegExp pattern for files that should return actual CSS and will be processed by

RegExp pattern for files that will return an empty CSS file.

#### css.modules

- **Type**: `{ scopeClassNames? }`
- **Default**: `{}`

#### css.modules.scopeClassNames

- **Type**: `boolean`
- **Default**: false

If you decide to process CSS files, you can configure if class names inside CSS modules should be scoped. By default, Vitest exports a proxy, bypassing CSS Modules processing.

You might want to enable this, if your CSS classes are conflicting with each other, when CSS is inlined. For example, when you are accessing computed styles:

```tsx
// global.module.css
// .error { width: 600px }

// element.module.css
// .error { width: 100px }

// test
const styles = window.getComputedStyles(<div className={error}></div>)
// it's possible to have two different classes with conflicting styles
expect(styles).toMatchObject({ with: '100px' })
```

### maxConcurrency

- **Type**: `number`
Expand Down
3 changes: 1 addition & 2 deletions packages/vitest/src/node/config.ts
Expand Up @@ -183,9 +183,8 @@ export function resolveConfig(

resolved.css ??= {}
if (typeof resolved.css === 'object') {
resolved.css.include ??= [/\.module\./]
resolved.css.modules ??= {}
resolved.css.modules.mangleClassName ??= false
resolved.css.modules.scopeClassNames ??= false
}

resolved.cache ??= { dir: '' }
Expand Down
30 changes: 12 additions & 18 deletions packages/vitest/src/node/plugins/cssEnabler.ts
Expand Up @@ -26,33 +26,27 @@ export function CSSEnablerPlugin(ctx: Vitest): VitePlugin {
return false
}

const shouldReturnProxy = (id: string) => {
const { css } = ctx.config
if (typeof css === 'boolean')
return css
if (!isCSSModule(id))
return false
return !css.modules?.mangleClassName
}

return {
name: 'vitest:css-enabler',
enforce: 'pre',
transform(code, id) {
if (!isCSS(id))
return
if (!shouldProcessCSS(id)) {
return { code: '' }
}
else if (shouldReturnProxy(id)) {
// TODO parse and check if object actually exists
if (shouldProcessCSS(id))
return

// return proxy for css modules, so that imported module has names:
// styles.foo returns a "foo" instead of "undefined"
if (isCSSModule(id)) {
const code = `export default new Proxy(Object.create(null), {
get(_, style) {
return style;
},
})`
get(_, style) {
return style;
},
})`
return { code }
}

return { code: '' }
},
}
}
6 changes: 6 additions & 0 deletions packages/vitest/src/node/plugins/index.ts
Expand Up @@ -98,6 +98,12 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest())
},
}

if (!preOptions?.css?.modules?.scopeClassNames) {
config.css ??= {}
config.css.modules ??= {}
config.css.modules.generateScopedName = (name: string) => name
}

if (!options.browser) {
// disable deps optimization
Object.assign(config, {
Expand Down
4 changes: 2 additions & 2 deletions packages/vitest/src/types/config.ts
Expand Up @@ -370,13 +370,13 @@ export interface InlineConfig {
*
* When excluded, the CSS files will be replaced with empty strings to bypass the subsequent processing.
*
* @default { include: [/\.module\./], modules: { mangleClassName: false } }
* @default { include: [], modules: { scopeClassNames: false } }
*/
css?: boolean | {
include?: RegExp | RegExp[]
exclude?: RegExp | RegExp[]
modules?: {
mangleClassName?: boolean
scopeClassNames?: boolean
}
}
/**
Expand Down

0 comments on commit 29a4754

Please sign in to comment.