Skip to content

mizdra/css-modules-kit

Repository files navigation

CSS Modules Kit

A toolkit for making CSS Modules useful.

Intro

By default, CSS Modules have limited language features in editors. For example:

  • Clicking on styles.button does not jump to its definition in Button.module.css.
  • When renaming styles.button, the corresponding .button {...} in Button.module.css is not renamed.
  • Performing "Find All References" on styles.button does not find its definition in Button.module.css.

It has been difficult to solve these issues because the TypeScript Language Server (tsserver) does not handle CSS files. Since tsserver does not hold information about CSS files, it cannot calculate jump destinations or determine which code should be renamed.

css-modules-kit addresses this by using a TypeScript Language Service Plugin. With this plugin, css-modules-kit extends tsserver to handle *.module.css files. As a result, many language features like code navigation and rename refactoring become available.

Additionally, css-modules-kit provides various development tools for CSS Modules, such as a stylelint plugin and a utility for generating *.d.ts files.

Supported Language Features

Go to Definition
2024-12-22.2.05.16.mov
Rename Symbol
2024-12-22.2.13.35.mov
Find all references
2024-12-22.2.10.01.mov
Definition Preview by Hover

You can preview the definition with Command + Hover on macOS and VS Code (key bindings may vary depending on your OS and editor).

2025-06-16.0.25.40.mov
Automatically update import statements when moving `*.module.css`
2024-12-26.20.24.48.mov
Create CSS Module file for current file.

If there is no CSS Module file corresponding to xxx.tsx, create one.

2025-02-02.19.07.06.mov
Complete `className={...}` instead of `className="..."`

In projects where CSS Modules are used, the element is styled with className={styles.xxx}. However, when you type className, className="..." is completed. This is annoying to the user.

So, instead of className="..." instead of className={...} instead of className="...".

2025-02-02.19.07.27.mov
Prioritize the `styles' import for the current component file

When you request styles completion, the CSS Module file styles will be suggested. If there are many CSS Module files in the project, more items will be suggested. This can be confusing to the user.

So I have made it so that the styles of the CSS Module file corresponding to the current file is shown first.

image
Add missing CSS rule

If you are trying to use a class name that is not defined, you can add it with Quick Fixes.

2025-02-02.19.24.36.mov

Get Started

Please read the Get Started guide.

How to try demo

  1. Open this repository with VS Code
  2. Open Run and Debug menu
  3. Select vscode (1-basic) configuration and start debugging

Configuration

css-modules-kit uses tsconfig.json as its configuration file.

include/exclude

In TypeScript, the include/exclude properties specify which *.ts files to compile. css-modules-kit reuses these options to determine which *.module.css files to handle with codegen and ts-plugin. Therefore, make sure your *.module.css files are included in the include or exclude settings.

{
  // For example, if your project's `*.module.css` files are in `src/`:
  "include": ["src"], // Default is ["**/*"], so it can be omitted
  "compilerOptions": {
    // ...
  },
}

cmkOptions.dtsOutDir

Type: string, Default: "generated"

Specifies the directory where *.d.ts files are output.

{
  "compilerOptions": {
    // ...
  },
  "cmkOptions": {
    "dtsOutDir": "generated/cmk",
  },
}

cmkOptions.arbitraryExtensions

Type: boolean, Default: false

Determines whether to generate *.module.d.css.ts instead of *.module.css.d.ts.

{
  "compilerOptions": {
    // ...
  },
  "cmkOptions": {
    "arbitraryExtensions": true,
  },
}

cmkOptions.namedExports

Type: boolean, Default: false

Determines whether to generate named exports in the d.ts file instead of a default export.

{
  "compilerOptions": {
    // ...
  },
  "cmkOptions": {
    "namedExports": true,
  },
}

cmkOptions.prioritizeNamedImports

Type: boolean, Default: false

Whether to prioritize named imports over namespace imports when adding import statements. This option only takes effect when cmkOptions.namedExports is true.

When this option is true, import { button } from '...' will be added. When this option is false, import button from '...' will be added.

{
  "compilerOptions": {
    // ...
  },
  "cmkOptions": {
    "namedExports": true,
    "prioritizeNamedImports": true,
  },
}

Limitations

To simplify the implementation, some features are not supported.

  • Sass/Less are not supported.
    • If you want to use Sass/Less, please use happy-css-modules. Although it does not offer as rich language features as css-modules-kit, it provides basic features such as code completion and Go to Definition.
  • The name of classes, @value, and @keyframes must be valid JavaScript identifiers.
    • For example, .fooBar and .foo_bar are supported, but .foo-bar is not supported.
    • See #176 for more details.
  • :local .foo {...} is not supported.
    • Use :local(.foo) {...} instead.
  • :global .foo {...} is not supported.
    • Use :global(.foo) {...} instead.
  • @keyframes :local(foo) {...} is not supported.
    • Use @keyframes foo {...} instead.
    • Meanwhile, @keyframes :global(foo) { ... } is supported.
  • css-modules-kit does not work on VS Code for Web.

History of this project

This project was created as a next-generation tool to replace happy-css-modules.

happy-css-modules was also a tool that provided language functionality for *.module.css. However, the tool was limited in the type of language features it could provide. To solve this limitation, css-modules-kit was created.

About

A toolkit for making CSS Modules useful.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Contributors 3

  •  
  •  
  •