vite-css-modules
TypeScript icon, indicating that this package has built-in type declarations

1.4.2 • Public • Published

vite-css-modules

This Vite plugin fixes several CSS Module bugs by handling CSS Modules as JS Modules.

The goal of this project is to incorporate this fix directly into Vite (PR #16018). Meanwhile, this plugin is published for early adopters and users who are unable to upgrade Vite.

→ Play with a demo on StackBlitz

Improvements

  • Handle CSS Modules as JS Modules

    The plugin changes how Vite processes CSS Modules. Currently, Vite bundles each CSS Module entry-point separately using postcss-modules.

    By treating them as JavaScript modules, they can now be integrated into Vite's module graph, allowing Vite to handle the bundling. This allows:

    • CSS Module dependencies to be de-duplicated (fix #7504, #15683)
    • HMR in CSS Module dependencies (fix #16074)
    • Vite plugins to process individual CSS Modules (fix #10079, #10340)
  • Improved error handling

    Currently, Vite (or more specifically, postcss-modules) fails silently when unable to resolve a composes dependency. This plugin will catch missing exports if the build.target is es2022 or higher. (fix #16075)

For more details, see the FAQ below.

Install

npm install -D vite-css-modules

Setup

In vite.config.js:

import { patchCssModules } from 'vite-css-modules'

export default {
    plugins: [
        patchCssModules()

        // Other plugins
    ],

    css: {
        // Configure CSS Modules as you previously did
        modules: {
            // ...
        },

        // Or LightningCSS
        lightningcss: {
            cssModules: {
                // ...
            }
        }
    }
}

This patches your Vite to handle CSS Modules in a more predictable way.

FAQ

What issues does this plugin address?

Vite uses postcss-modules to create a separate bundle for each CSS Module entry point, which leads to the following problems:

  1. CSS Modules are not integrated with the Vite build

    postcss-modules bundles each CSS Module entry-point in a black-box, preventing Vite plugins from accessing any of the dependencies it resolves. This effectively limits further CSS post-processing from Vite plugins (e.g. SCSS, PostCSS, or LightningCSS).

    Although postcss-modules tries to apply other PostCSS plugins to dependencies, it seems to have issues:

  2. Duplicated CSS Module dependencies

    Since each CSS Module is bundled separately at each entry-point, dependencies shared across those entry-points are duplicated in the final Vite build.

    This leads to bloated final outputs, and the duplicated composed classes can disrupt the intended style by overriding previously declared classes.

How does this work?

Plugin

Inherently, CSS Modules are CSS files with a JavaScript interface exporting the class names.

This plugin preserves their nature and compiles each CSS Module into an JS module that loads the CSS. In each CSS Module, the composes are transformed into JavaScript imports, and the exports consist of the class names. This allows Vite (or Rollup) to efficiently resolve, bundle, and de-duplicate the CSS Modules.

This process mirrors the approach taken by Webpack’s css-loader, making it easier for those transitioning from Webpack. And since this technically does less work to load CSS Modules, I'm sure it's marginally faster in larger apps.

Patch

The patch disables Vite's default CSS Modules behavior, injects this plugin right before Vite's vite:css-post plugin, and patches the vite:css-post plugin to handle the JS output from the plugin.

Package Sidebar

Install

npm i vite-css-modules

Weekly Downloads

47

Version

1.4.2

License

MIT

Unpacked Size

87.5 kB

Total Files

11

Last publish

Collaborators

  • hirokiosame