simonwep / simonwep/vite-plugin-optimize-css-modules
Class shaker
Nobody has claimed this yet.
- Dominant language
- CSS
- Stars
- 48
- Forks
- 5
- PR merge metrics
- No merged PRs in 30d
Description
One thing that surprised me about CSS Modules in Vite is that it doesn't automatically shake unreferenced classes.
.unused {
font-size: 42px;
}
.used {
font-size: 27px;
}
import { used } from './foo.module.css'
...
The .unused class will appear in the output.
I noticed that this plugin does not shake unused classes either, so I made a small postprocessor that does the job.
If this seems like a good idea, I wonder if it could be incorporated into this plugin somehow. Basically it scans through the JS files to gather possible class names (/"([A-Za-z_]{1,2})"/g) then uses PurgeCSS with a custom extractor to strip the unused classes.
I think this could be incorporated as a { shake: true } option for this plugin. Shaking would require hooking into the JS output from Vite, marking known class names as used, and then stripping the unused ones before outputting the final CSS.
import { readFileSync, writeFileSync } from 'fs'
import { ExtractorResultDetailed, PurgeCSS } from 'purgecss'
const tags = ['a', 'abbr', ...]
const purgeFromJs = (content: string): ExtractorResultDetailed => {
const regex = /"([A-Za-z_]{1,2})"/g
const matches: string[] = []
let match: RegExpExecArray | null
while ((match = regex.exec(content)) !== null) {
matches.push(match[1])
}
// console.log(`Possible classes (${matches.length}): ${matches.join(', ')}`)
return {
attributes: {
names: [],
values: [],
},
ids: [],
tags,
undetermined: [],
classes: matches,
}
}
const purgeCSSResult = await new PurgeCSS().purge({
content: ['dist/assets/*.js'],
css: ['dist/assets/*.css'],
extractors: [
{
extractor: purgeFromJs,
extensions: ['js'],
},
],
})
// process.exit(0)
purgeCSSResult.forEach((result) => {
const { css, file } = result
if (!file) return
const bytesBefore = Buffer.byteLength(readFileSync(file, 'utf-8'), 'utf-8')
const bytesAfter = Buffer.byteLength(css, 'utf-8')
console.log(`Writing optimized css: ${file}`)
writeFileSync(file, css)
console.log(`Reduced size from ${bytesBefore} to ${bytesAfter} bytes`)
})
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the plugin's Vite integration and the JavaScript and CSS output stages. Review the proposed PurgeCSS custom extractor and the suggested { shake: true } option. Done means unused CSS Module classes are removed without removing referenced classes, with the behavior verified on a Vite build.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, typescript, vite
- Domain
- build-system, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100