Vite / Webpack - plugin to transform dynamic css class names on-the-fly
npm install dynamic-css-plugin"btn-primary btn-primary-disabled" ==> .app_Xscyf.app_LfRuA
bash
npm install dynamic-css-plugin -D
`
---
$3
vite.config.js
#### Import into _Vite_ config
`js
import dynamicCssPlugin from "dynamic-css-plugin/vite";
`
#### Add to _Vite_ plugins
`js
plugins: [
dynamicCssPlugin({
transform: "app_[md4:hash:base64:5]"
})
];
`
> Full Vite example
---
$3
webpack.config.js
#### Import into _Webpack_ config
`js
import DynamicCssPlugin from "dynamic-css-plugin/webpack";
`
#### Add to _Webpack_ plugins
`js
plugins: [
new DynamicCssPlugin({
transform: "app_[md4:hash:base64:5]"
})
];
`
> Full Webpack example
Options
- enabled: true - If false, the plugin will not run
- scope: "" - Applies a scope to the injected method. Useful if multiple instances are on the same page such as with micro-frontends
- debug: false - Enables debug logging
$3
- transform: "[md4:hash:base64:5]" - The transform template or config object
- transform: {} - The transform config object
- transform.template: "[md4:hash:base64:5]" - The format of transformed class names
- "prefix\_[{algorithm}:hash:{encoding}:{length}]"
- transform.attributes: /^(class)$/ - Regex for HTML attributes to transform
- transform.ignoreTags: /(path)/i - Regex for HTML tags to ignore
- transform.ignoreValues: /^(css|sc|icon)-/i - Regex for HTML attribute values to ignore
- transform.ignoreFiles: /\.notransform\.(css|scss)$/i - Regex for files to ignore
$3
- inject: {} - The injection config
- inject.entryPoint: undefined The entry point for the injected method in the bundle, if undefined the first entry is used
- inject.src: "./src/inject/index.js" The code to apply options and generate the file to inject
- inject.file: "./src/inject/index_generated.js" The code to inject
$3
- patch: PatchReactDom - The patch function
`jsx
import PatchReactDom from "dynamic-css-plugin/patch/react-dom";
`
Patch method signature:
`jsx
function PatchReactDom(scope = "") {
return {
test: /react-dom/,
search: /(\w+)\.setAttribute\(/g,
replace: globalThis['${scope}setAttributeDynamic'].call($1,
};
}
`
---
$3
> ignoreValues default excludes class names with the following prefixes that are commonly generated by other libraries and should not be transformed
- css- which is the emotion default
- sc- which is the styled-components default
- icon- which is the the standard for icon classes
Limitations
Since we are only patching calls to "setAttribute" inside react-dom that means if a class is applied a different way such as with vanilla JS or using classList the transform will not apply. This is largely ok since these patterns don’t necessarily follow the "react way of doing things". However if you do need to support these patterns you can use the injected method directly.
For example:
`js
import DynamicCss from "dynamic-css-plugin";
document.body.classList.add(DynamicCss("theme-light"));
``