Mangling Selectors
Selectors mangling is a next level optimization that converts long selectors like .color\:blue
to a short one .a
.
This can significantly decrease the CSS and HTML size. It also makes it harder to “steal” your web design by copy-pasting your source code.
Configuration
The mangling process for packages @stylify/bundler, @stylify/unplugin, @stylify/astro or @stylify/nuxt, works like this:
- Mangling is turned off by default and you have to enable it by setting compiler option
mangleSelectors
totrue
- Selectors are always mangled directly in the source code (here is why)
- Selectors are not mangled, when any of these packages is running in watch mode (watching files for a change)
- When you run build command in your project (fot production/dev environment), Stylify will mangle selectors
Because selectors are mangled directly within the source files, you might want to disable the mangling for local environment and enable it only in staging and production environment, so you don’t have to revert changes caused by Stylify each time you run build.
This can be easily solved by using an environment variable
:
const config = {
compiler: {
// Mangle selectors only if environment variable for mangling is set
// The name of the variable is up to you
mangleSelectors: typeof process.env.STYLIFY_MANGLE_SELECTORS !== 'undefined'
}
}
Here is a list of guides for environment variables for often use deploy services:
Compiler
When you want to mangle selectors within your custom compilation by using Compiler directly, you must set the compiler option => mangleSelectors: true
.
Again, you can use an environment variable to enable/disable mangling for the local development environment and production.
import { Compiler } from '@stylify/stylify';
const content = '';
const compiler = new Compiler({
mangleSelectors: true
});
const compilationResult = compiler.compile(content);
const mangledContent = compiler.rewriteSelectors(content, compilationResult);
const css = compilationResult.generateCss();
@stylify/bundler
Bundler uses Compiler under the hood. If you want to enable mangling, set the mangleSelectors
within the compiler config to true
.
const bundler = new Bundler({
compiler: {
// This will take an effect only, when bundler is not watching files
mangleSelectors: true
}
})
@stylify/unplugin
Unplugin passes the configuration into the Bundler under the hood.
const config = {
compiler: {
// This will take an effect only when the bundler where the plugin is used,
// is not running in a watch mode
mangleSelectors: true
}
}
@stylify/astro
Astro passes the configuration to Unplugin under the hood:
const config = {
compiler: {
// This will take an effect only when the bundler where the plugin is used,
// is not running in a watch mode
mangleSelectors: true
}
}
@stylify/nuxt
Nuxt plugin passes the configuration to the Unplugin under the hood:
const config = {
compiler: {
// This will take an effect only when the bundler where the plugin is used,
// is not running in a watch mode
mangleSelectors: true
}
}
@stylify/nuxt-module
Nuxt module sets the mangling automatically and uses an old webpack plugin that is prepared specifically for Nuxt 2. You don’t need to configure anything there.
However you can disable the mangling by setting mangleSelectors: false
:
const config = {
compiler: {
mangleSelectors: false
}
}
Why Stylify mangles selectors directly in source code
- Stylify works in a way, that it matches class attributes and processes it’s content => generates css
- When you work with some frameworks like Astro, Vue, Nuxt, Next, React, they often use Vite, Webpack or Rollup to compile their source code
- During the build, the source code is often transformed from
class="color:blue"
to something likecreateEl(el, null, {class: 'color:blue'})
or even worsec(el, 'color:blue')
- Due to these changes Stylify cannot match classes properly and some of these areas are not processed => no CSS is generated or selectors are not mangled
- The only way to solve this would be to put the Stylify plugin before all other plugins to receive raw input, but because some plugins seems to be fixed at the beginning, this doesn’t work in all cases
- Because of reasons mentioned above, this process is not reliable, it’s hard to debug and the support for it was removed in
0.6