or run

npx @tessl/cli init
Log in

Version

Files

docs

index.md
tile.json

task.mdevals/scenario-9/

Custom CSS Module Import Transformer

Build a PostCSS processor that transforms CSS Modules with custom import naming patterns.

Background

When building a design system, you need to process CSS Modules files that use composes to inherit styles from external files. Your build system requires that all imported class names follow a specific naming convention that includes metadata about the source file for better debugging and tracking.

Requirements

Create a CSS processing utility that:

  1. Accepts a CSS string containing CSS Modules composes declarations
  2. Transforms the CSS to extract imports into explicit :import() rules
  3. Uses a custom naming strategy for imported class names that includes:
    • A prefix "ds_" (design system)
    • The original class name
    • The source file path (with special characters replaced by underscores)
  4. Returns the transformed CSS string

Your solution should handle:

  • Single class imports: composes: button from "./components/button.css"
  • Multiple class imports: composes: card footer from "../shared/layout.css"
  • Global compositions should be preserved without transformation

Example

Input CSS:

.primaryButton {
  composes: baseButton from "./base.css";
  background: blue;
}

.card {
  composes: container shadow from "../ui/layout.css";
  padding: 20px;
}

Expected Output:

:import("./base.css") {
  ds_baseButton_base_css: baseButton;
}
:import("../ui/layout.css") {
  ds_container_ui_layout_css: container;
  ds_shadow_ui_layout_css: shadow;
}
.primaryButton {
  composes: ds_baseButton_base_css;
  background: blue;
}

.card {
  composes: ds_container_ui_layout_css ds_shadow_ui_layout_css;
  padding: 20px;
}

Implementation

Create a file transformer.js that exports a single function:

@generates

/**
 * Transforms CSS with custom import naming
 * @param {string} css - Input CSS string with composes declarations
 * @returns {Promise<string>} - Transformed CSS with custom import names
 */
async function transformCSS(css) {
  // Implementation here
}

module.exports = { transformCSS };

Test Cases

  • Given CSS with a single compose from an external file, the output includes a custom named import with prefix, class name, and sanitized path @test
  • Given CSS with multiple classes composed from the same file, each class gets its own uniquely named import identifier @test
  • Given CSS with composes from multiple different files, separate :import() rules are created for each file @test

Dependencies { .dependencies }

postcss-modules-extract-imports { .dependency }

Provides CSS Modules import extraction with customizable import naming.

@satisfied-by

postcss { .dependency }

Provides CSS parsing and processing capabilities.

@satisfied-by