or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-vite-plugin-lib-inject-css

Inject CSS at the top of chunk files in Vite library mode using import statements, supporting multiple entries.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/vite-plugin-lib-inject-css@2.2.x

To install, run

npx @tessl/cli install tessl/npm-vite-plugin-lib-inject-css@2.2.0

index.mddocs/

Vite Plugin Lib Inject CSS

Vite Plugin Lib Inject CSS automatically injects CSS import statements at the top of generated JavaScript chunk files in Vite library mode builds. It solves the common problem of associating CSS styles with component libraries, enabling automatic style imports without manual intervention while maintaining SSR compatibility.

Package Information

  • Package Name: vite-plugin-lib-inject-css
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install vite-plugin-lib-inject-css -D

Core Imports

import { libInjectCss } from 'vite-plugin-lib-inject-css';

For CommonJS:

const { libInjectCss } = require('vite-plugin-lib-inject-css');

Basic Usage

import { defineConfig } from 'vite';
import { libInjectCss } from 'vite-plugin-lib-inject-css';

export default defineConfig({
  plugins: [
    libInjectCss(),
  ],
  build: {
    lib: {
      entry: 'src/index.ts',
      formats: ['es']
    }
  }
});

Architecture

The plugin works by:

  1. Configuration Enhancement: Automatically sets required Vite options (cssCodeSplit: true, ssrEmitAssets: true, hoistTransitiveImports: false)
  2. AST Analysis: Uses @ast-grep/napi to parse JavaScript and find optimal injection points after imports and expression statements
  3. CSS Discovery: Leverages Vite's internal chunk.viteMetadata.importedCss to identify CSS files associated with each chunk
  4. Import Injection: Adds appropriate import statements (import './style.css'; for ES modules, require('./style.css'); for CommonJS) at the top of chunks
  5. Source Map Preservation: Maintains source maps when enabled using magic-string

Capabilities

Plugin Factory Function

Creates a Vite plugin instance that handles CSS injection in library builds.

/**
 * Inject css at the top of each generated chunk file, only works with library mode.
 * @returns Vite Plugin object configured for CSS injection
 */
function libInjectCss(): Plugin;

Usage Examples:

import { defineConfig } from 'vite';
import { libInjectCss } from 'vite-plugin-lib-inject-css';

// Basic single-entry configuration
export default defineConfig({
  plugins: [libInjectCss()],
  build: {
    lib: {
      entry: 'src/index.ts',
      formats: ['es']
    }
  }
});

// Multi-entry configuration
export default defineConfig({
  plugins: [libInjectCss()],
  build: {
    lib: {
      formats: ['es', 'cjs'],
      entry: {
        index: 'src/index.ts',
        button: 'src/components/button/index.ts',
        select: 'src/components/select/index.ts',
      }
    },
    rollupOptions: {
      output: {
        chunkFileNames: 'chunks/[name].[hash].js',
        assetFileNames: 'assets/[name][extname]',
        entryFileNames: '[name].js',
      },
    },
  }
});

Plugin Configuration Behavior

The plugin automatically configures several Vite options:

CSS Code Splitting

// Automatically set by the plugin
build: {
  cssCodeSplit: true  // Required for CSS injection to work
}

SSR Asset Emission

// Automatically set by the plugin
build: {
  ssrEmitAssets: true  // Required for SSR builds
}

Transitive Imports Hoisting

// Automatically set by the plugin (can be overridden)
rollupOptions: {
  output: {
    hoistTransitiveImports: false  // Prevents tree-shaking issues
  }
}

Types

interface Plugin {
  name: string;
  apply: 'build';
  enforce: 'post';
  config(config: UserConfig): Partial<UserConfig>;
  configResolved(config: ResolvedConfig): void;
  options(): void;
  generateBundle(opts: OutputOptions, bundle: OutputBundle): void;
}

// From Vite types
interface ResolvedConfig {
  build: {
    lib?: LibBuildOptions;
    ssr?: boolean;
    ssrEmitAssets?: boolean;
    sourcemap?: boolean;
  };
  command: 'build' | 'serve';
}

interface OutputOptions {
  format: 'es' | 'cjs' | 'umd' | 'iife';
}

interface OutputBundle {
  [fileName: string]: OutputAsset | OutputChunk;
}

interface UserConfig {
  build?: {
    lib?: LibBuildOptions;
    cssCodeSplit?: boolean;
    ssrEmitAssets?: boolean;
    rollupOptions?: {
      output?: {
        hoistTransitiveImports?: boolean;
        chunkFileNames?: string;
        assetFileNames?: string;
        entryFileNames?: string;
      };
    };
  };
}

interface LibBuildOptions {
  entry: string | string[] | { [key: string]: string };
  formats?: ('es' | 'cjs' | 'umd' | 'iife')[];
}

interface OutputAsset {
  type: 'asset';
  fileName: string;
  source: string | Uint8Array;
}

interface OutputChunk {
  type: 'chunk';
  fileName: string;
  code: string;
  map?: any;
  viteMetadata?: {
    importedCss: Set<string>;
  };
}

Operating Requirements

The plugin has specific operating requirements:

  • Library Mode Only: Must be used with Vite's library mode (build.lib configured)
  • Build Command Only: Only operates during build process (command === 'build')
  • CSS Code Split: Requires cssCodeSplit: true (automatically set)
  • SSR Assets: For SSR builds, requires ssrEmitAssets: true (automatically set)

Error Handling and Warnings

The plugin provides console warnings for common configuration issues:

  • Warns when not in library mode or building process
  • Alerts about SSR configuration conflicts that may cause injection failures
  • Uses colored console output for better visibility

Generated Output Format

The plugin generates different import formats based on the output format:

// For ES modules (format: 'es')
import './assets/component.css';
// ... rest of chunk code

// For CommonJS (format: 'cjs')
require('./assets/component.css');
// ... rest of chunk code

CSS file paths are automatically calculated as relative paths from the chunk location to the CSS file location.