I've discovered a clever workaround that involves generating hashed classes for CSS modules and extracting the stylesheet. Instead of importing the regular CSS module stylesheet, I import the one with hashed classes. Most bundlers capable of importing CSS modules should be able to handle the extracted CSS file.
To achieve this, I utilize babel-plugin-css-modules-transform with the following setup:
…
"plugins": [
[
"css-modules-transform",
{
"extractCss": {
"dir": "./lib/",
"relativeRoot": "./src/",
"filename": "[path]/[name].compiled.css"
},
"keepImport": true,
"importPathFormatter": "./importPathFormatter"
}
]
]
…
The keepImport
setting retains the import statement but changes it from something like
import * as styles from 'styles.module.css'
to
import 'styles.module.css'
.
I combine this option with an undocumented feature called
importPathFormatter
to import the transformed CSS. Any CSS preprocessing such as postCSS is deferred to the consuming application.
This is how the contents of ./importPathFormatter.js
look:
module.exports = path => path.replace(/\.css$/, '.compiled.css');
In the future, I plan to transition my projects to vanilla extract and leverage rollup/vite for bundling. However, for now, this solution serves me well.