CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-lightningcss

A CSS parser, transformer, and minifier written in Rust with Node.js bindings

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

bundling.mddocs/

CSS Bundling

Bundle CSS files with dependency resolution, @import inlining, and asset tracking for complete CSS processing pipelines that combine multiple files into optimized output.

Capabilities

Bundle Function

Synchronously bundles a CSS file and its dependencies by inlining @import rules.

/**
 * Bundles a CSS file and its dependencies, inlining @import rules
 * @param options - Bundle configuration options (same as transform but without code)
 * @returns Bundle result with combined CSS and dependency information
 */
function bundle<C extends CustomAtRules>(
  options: BundleOptions<C>
): TransformResult;

type BundleOptions<C extends CustomAtRules> = Omit<TransformOptions<C>, 'code'>;

Usage Examples:

import { bundle } from "lightningcss";

// Basic CSS bundling
const result = bundle({
  filename: "src/main.css", // Entry point CSS file
  minify: true,
  targets: {
    chrome: 90 << 16,
    firefox: 88 << 16
  }
});

console.log(new TextDecoder().decode(result.code));

// Bundle with CSS modules
const moduleBundle = bundle({
  filename: "src/components/index.css",
  cssModules: true,
  minify: true
});

console.log(moduleBundle.exports); // Combined CSS module exports

Bundle Async Function

Asynchronously bundles CSS files with custom resolver support for advanced file loading scenarios.

/**
 * Bundles a CSS file and its dependencies asynchronously, inlining @import rules
 * @param options - Async bundle configuration with optional custom resolver
 * @returns Promise resolving to bundle result
 */
function bundleAsync<C extends CustomAtRules>(
  options: BundleAsyncOptions<C>
): Promise<TransformResult>;

interface BundleAsyncOptions<C extends CustomAtRules> extends BundleOptions<C> {
  resolver?: Resolver;
}

Usage Examples:

import { bundleAsync } from "lightningcss";

// Async bundling with default file system resolver
const result = await bundleAsync({
  filename: "src/styles.css",
  minify: true,
  sourceMap: true
});

// Custom resolver for non-file-system sources
const customResult = await bundleAsync({
  filename: "virtual://main.css",
  resolver: {
    async resolve(specifier, originatingFile) {
      // Custom resolution logic (e.g., resolve from database, URL, etc.)
      if (specifier.startsWith('virtual://')) {
        return specifier;
      }
      return path.resolve(path.dirname(originatingFile), specifier);
    },
    
    async read(file) {
      // Custom file reading logic
      if (file.startsWith('virtual://')) {
        return await fetchFromDatabase(file);
      }
      return await fs.readFile(file, 'utf8');
    }
  }
});

Custom Resolver Interface

Define custom file resolution and reading logic for advanced bundling scenarios.

/** Custom resolver to use when loading CSS files. */
interface Resolver {
  /** Read the given file and return its contents as a string. */
  read?: (file: string) => string | Promise<string>;

  /**
   * Resolve the given CSS import specifier from the provided originating file to a
   * path which gets passed to `read()`.
   */
  resolve?: (specifier: string, originatingFile: string) => string | Promise<string>;
}

Usage Examples:

import { bundleAsync } from "lightningcss";
import path from "path";
import fs from "fs/promises";

// URL-based resolver
const urlResolver: Resolver = {
  async resolve(specifier, originatingFile) {
    if (specifier.startsWith('http')) {
      return specifier; // Keep URLs as-is
    }
    if (originatingFile.startsWith('http')) {
      return new URL(specifier, originatingFile).href;
    }
    return path.resolve(path.dirname(originatingFile), specifier);
  },
  
  async read(file) {
    if (file.startsWith('http')) {
      const response = await fetch(file);
      return await response.text();
    }
    return await fs.readFile(file, 'utf8');
  }
};

const result = await bundleAsync({
  filename: "https://cdn.example.com/styles.css",
  resolver: urlResolver,
  minify: true
});

// Package-based resolver
const packageResolver: Resolver = {
  async resolve(specifier, originatingFile) {
    if (specifier.startsWith('@')) {
      // Resolve scoped packages from node_modules
      return require.resolve(specifier + '/style.css');
    }
    return path.resolve(path.dirname(originatingFile), specifier);
  },
  
  async read(file) {
    return await fs.readFile(file, 'utf8');
  }
};

Bundle Result Processing

Process the bundling results to extract combined CSS, source maps, and dependency information.

// Bundle results use the same TransformResult interface
interface TransformResult {
  /** The bundled and transformed CSS code. */
  code: Uint8Array;
  /** The generated source map, if enabled. */
  map: Uint8Array | void;
  /** Combined CSS module exports from all bundled files, if enabled. */
  exports: CSSModuleExports | void;
  /** CSS module references from all bundled files. */
  references: CSSModuleReferences;
  /** All dependencies found during bundling, if enabled. */
  dependencies: Dependency[] | void;
  /** Warnings that occurred during bundling. */
  warnings: Warning[];
}

Usage Examples:

import { bundle } from "lightningcss";
import fs from "fs";

const result = bundle({
  filename: "src/main.css",
  sourceMap: true,
  cssModules: true,
  analyzeDependencies: true,
  minify: true
});

// Write bundled CSS
fs.writeFileSync('dist/bundle.css', result.code);

// Write source map if generated
if (result.map) {
  fs.writeFileSync('dist/bundle.css.map', result.map);
}

// Process CSS module exports
if (result.exports) {
  const moduleMap = Object.fromEntries(
    Object.entries(result.exports).map(([key, value]) => [key, value.name])
  );
  fs.writeFileSync('dist/css-modules.json', JSON.stringify(moduleMap, null, 2));
}

// Log dependency information
if (result.dependencies) {
  console.log('Bundle dependencies:');
  result.dependencies.forEach(dep => {
    console.log(`  ${dep.type}: ${dep.url}`);
  });
}

// Handle warnings
if (result.warnings.length > 0) {
  console.warn('Bundle warnings:');
  result.warnings.forEach(warning => {
    console.warn(`  ${warning.message} at ${warning.loc.filename}:${warning.loc.line}:${warning.loc.column}`);
  });
}

Bundling with Import Analysis

Enable dependency analysis during bundling to track @import and url() dependencies.

interface DependencyOptions {
  /** Whether to preserve `@import` rules rather than removing them. */
  preserveImports?: boolean;
}

Usage Examples:

const result = bundle({
  filename: "src/main.css",
  analyzeDependencies: {
    preserveImports: false // Default: remove @import rules after inlining
  },
  minify: true
});

// Dependencies contain all @import and url() references
result.dependencies?.forEach(dep => {
  if (dep.type === 'import') {
    console.log(`Imported: ${dep.url} with media: ${dep.media}`);
  } else if (dep.type === 'url') {
    console.log(`Asset: ${dep.url}`);
  }
});

docs

bundling.md

index.md

rust-api.md

style-attributes.md

targets.md

transformation.md

visitors.md

tile.json