Vite Plugin Lazy CSS Modules Inliner
raw JSON → 0.2.0 verified Mon Apr 27 auth: no javascript
A Vite plugin (v0.2.0) that enables true on-demand CSS injection for dynamically imported code by virtualizing CSS Modules. It prevents lazy components' styles from being bundled into the page's initial CSS, injecting them only when the corresponding JavaScript chunk is actually loaded. Supports Vite 4+, TypeScript, and frameworks like React, Vue, Svelte (via external *.module.css imports). Unlike typical CSS-in-JS solutions or code-splitting plugins, it preserves CSS Modules hashing, avoids preloading CSS via __vitePreload, and includes built-in RTL support via runtimeIsRtlCondition. Released as a proof-of-concept with active maintenance.
Common errors
error Error: Cannot find module 'vite-plugin-lazy-css-modules-inliner' ↓
cause Package not installed or import path incorrect
fix
Install with
npm install --save-dev vite-plugin-lazy-css-modules-inliner and verify package.json includes it. error TypeError: viteLazyCssInliner is not a function ↓
cause Using default import instead of named import
fix
Change
import viteLazyCssInliner from ... to import { viteLazyCssInliner } from .... error Error: The plugin 'vite-plugin-lazy-css-modules-inliner' requires Vite >=4 but current version is 3.x ↓
cause Incompatible Vite version
fix
Update Vite to version 4 or higher:
npm install vite@^4. error Error: getModuleInfo(id).dynamicImporters is not a function ↓
cause Using a Vite version older than 4 where getModuleInfo returns undefined
fix
Upgrade Vite to >=4, as the plugin relies on dynamicImporters property added in Vite 4.
error Warning: You are using stripPreloadDepsMode: 'all' which may break chunk loading in some scenarios ↓
cause Using a configuration option that is not recommended for general use
fix
Set stripPreloadDepsMode to 'css' (default) unless you have a specific reason to use 'all'.
Warnings
breaking requires node >= 18 and vite >= 4 ↓
fix Update Node.js to 18+ and Vite to 4+. Check engines field in package.json.
deprecated stripPreloadDepsMode: 'all' may cause unexpected behavior in shared chunks ↓
fix Use 'css' (default) unless you fully understand the implications. 'all' strips all dependencies from __vitePreload which can break chunk loading.
gotcha Mixed static and dynamic imports of the same CSS module can duplicate CSS ↓
fix Use only dynamic imports for CSS modules that are lazy-loaded, or accept the duplication. Do not mix import styles for the same module.
gotcha The plugin re-routes CSS imports inside lazy graphs to virtual modules; if you see 'Cannot find module' errors for virtual IDs, your bundler may not support virtual modules ↓
fix Ensure you are using Vite (not a custom bundler). Virtual modules are Vite-specific and won't work with plain Rollup.
gotcha RTL support requires rtlcss to be installed as a dependency if runtimeIsRtlCondition is set ↓
fix Run `npm install --save-dev rtlcss` and set runtimeIsRtlCondition in plugin options.
gotcha SSR build: virtual CSS modules are loaded as empty, so styles won't be injected server-side; client hydration will inject them, causing potential flash of unstyled content ↓
fix Ensure you have a ClientRouter or wait for hydration. Consider using a CSS-in-JS solution for SSR if flashes are unacceptable.
Install
npm install vite-plugin-lazy-css-modules-inliner yarn add vite-plugin-lazy-css-modules-inliner pnpm add vite-plugin-lazy-css-modules-inliner Imports
- viteLazyCssInliner wrong
const viteLazyCssInliner = require('vite-plugin-lazy-css-modules-inliner')correctimport { viteLazyCssInliner } from 'vite-plugin-lazy-css-modules-inliner' - PluginOptions wrong
import { PluginOptions } from 'vite-plugin-lazy-css-modules-inliner'correctimport type { PluginOptions } from 'vite-plugin-lazy-css-modules-inliner' - default import wrong
import { default as viteLazyCssInliner } from 'vite-plugin-lazy-css-modules-inliner'correctimport viteLazyCssInliner from 'vite-plugin-lazy-css-modules-inliner' - VitePlugin wrong
import VitePlugin from 'vite-plugin-lazy-css-modules-inliner'correctimport { viteLazyCssInliner } from 'vite-plugin-lazy-css-modules-inliner'
Quickstart
// vite.config.ts
import { defineConfig } from 'vite';
import { viteLazyCssInliner } from 'vite-plugin-lazy-css-modules-inliner';
export default defineConfig({
plugins: [
viteLazyCssInliner({
stripPreloadDepsMode: 'css', // default
isDev: process.env.NODE_ENV !== 'production',
includedPathes: ['src'],
excludedPathes: ['node_modules'],
}),
],
});
// MyComponent.jsx
import styles from './MyComponent.module.css';
const MyComponent = () => <div className={styles.root}>Hello</div>;
export default MyComponent;