Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(css): support custom regexp of css modules #6404

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ export default defineConfig(async ({ command, mode }) => {
| 'dashes'
| 'dashesOnly'
| null
isCssModule?: string | RegExp | ((id: string) => boolean)
}
```

Expand Down
2 changes: 1 addition & 1 deletion docs/guide/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ If the project contains valid PostCSS config (any format supported by [postcss-l

### CSS Modules

Any CSS file ending with `.module.css` is considered a [CSS modules file](https://github.com/css-modules/css-modules). Importing such a file will return the corresponding module object:
Any CSS file ending with `.module.css` is considered a [CSS modules file](https://github.com/css-modules/css-modules). You can change this behavior using the [`css.modules.isCssModule` option](/config/#css-modules). Importing such a file will return the corresponding module object:

```css
/* example.module.css */
Expand Down
3 changes: 3 additions & 0 deletions packages/playground/css/custom-module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.apply-color {
color: olive;
}
6 changes: 6 additions & 0 deletions packages/playground/css/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ <h1>CSS</h1>
<p>Imported CSS module:</p>
<pre class="modules-code"></pre>

<p class="custom-modules">
use CSS modules not just .module.xxx: this should be olive
</p>
<p>Imported custom filename with CSS module :</p>
<pre class="custom-modules-code"></pre>

<p class="modules-sass">CSS modules w/ SASS: this should be orangered</p>
<p>Imported SASS module:</p>
<pre class="modules-sass-code"></pre>
Expand Down
13 changes: 13 additions & 0 deletions packages/playground/css/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ import mod from './mod.module.css'
document.querySelector('.modules').classList.add(mod['apply-color'])
text('.modules-code', JSON.stringify(mod, null, 2))

import customMod from './custom-module.css'
document
.querySelector('.custom-modules')
.classList.add(customMod['apply-color'])
text('.custom-modules-code', JSON.stringify(customMod, null, 2))

import sassMod from './mod.module.scss'
document.querySelector('.modules-sass').classList.add(sassMod['apply-color'])
text('.modules-sass-code', JSON.stringify(sassMod, null, 2))
Expand Down Expand Up @@ -50,6 +56,13 @@ if (import.meta.hot) {
text('.modules-code', JSON.stringify(newMod.default, null, 2))
})

import.meta.hot.accept('./custom-module.css', (newMod) => {
const list = document.querySelector('.custom-modules').classList
list.remove(mod.applyColor)
list.add(newMod.applyColor)
text('.custom-modules-code', JSON.stringify(newMod.default, null, 2))
})

import.meta.hot.accept('./mod.module.scss', (newMod) => {
const list = document.querySelector('.modules-sass').classList
list.remove(mod.applyColor)
Expand Down
6 changes: 5 additions & 1 deletion packages/playground/css/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ module.exports = {
},
css: {
modules: {
generateScopedName: '[name]__[local]___[hash:base64:5]'
generateScopedName: '[name]__[local]___[hash:base64:5]',

// string: '.module'
// function: id => id.includes('.module')
isCssModule: /custom-module|\.module/

// example of how getJSON can be used to generate
// typescript typings for css modules class names
Expand Down
22 changes: 21 additions & 1 deletion packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export interface CSSModulesOptions {
| 'dashes'
| 'dashesOnly'
| null
isCssModule?: string | RegExp | ((id: string) => boolean)
}

const cssLangs = `\\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\\?)`
Expand Down Expand Up @@ -590,6 +591,25 @@ function getCssResolversKeys(
return Object.keys(resolvers) as unknown as Array<keyof CSSAtImportResolvers>
}

function isCssModule(
modulesOptions: CSSOptions['modules'],
id: string
): boolean {
if (modulesOptions && modulesOptions.isCssModule) {
const { isCssModule } = modulesOptions
if (typeof isCssModule === 'function') {
return isCssModule(id)
} else if (
typeof isCssModule === 'string' ||
isCssModule instanceof RegExp
) {
const regexp = new RegExp(isCssModule)
jsonz1993 marked this conversation as resolved.
Show resolved Hide resolved
return regexp.test(id)
}
}
return modulesOptions !== false && cssModuleRE.test(id)
}

async function compileCSS(
id: string,
code: string,
Expand All @@ -605,7 +625,7 @@ async function compileCSS(
deps?: Set<string>
}> {
const { modules: modulesOptions, preprocessorOptions } = config.css || {}
const isModule = modulesOptions !== false && cssModuleRE.test(id)
const isModule = isCssModule(modulesOptions, id)
// although at serve time it can work without processing, we do need to
// crawl them in order to register watch dependencies.
const needInlineImport = code.includes('@import')
Expand Down