Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS module prefix query parameter #18069

Open
4 tasks done
guoyunhe opened this issue Sep 10, 2024 · 3 comments
Open
4 tasks done

CSS module prefix query parameter #18069

guoyunhe opened this issue Sep 10, 2024 · 3 comments

Comments

@guoyunhe
Copy link

guoyunhe commented Sep 10, 2024

Description

In CSS module, we would like to write shorter class names:

/* ProductCard.module.css */
.root {}
.image {}
.button {}

However, when we monitoring online traffic and user interactions, we tends to record class names and ids. Short class names can be confusing. For example, many components may have .image:

.image_l2sjf {}
.image_xrfs1 {}
.image_xeqwk {}

It is hard to know which component the .image class name belongs to.

Suggested solution

I suggest to support a special query parameter prefix to add extra context for class names:

import styles from './ProductCard.module.css?prefix=ProductCard';

Which will generate css like this:

.ProductCard_root_af13s {}
.ProductCard_image_1irfj {}
.ProductCard_button_fseis {}

Alternative

According to this article, Create React App can automatically prefix css module class name with the file name:

image

Vite doesn't support this magic out-of-box, but you can achieve it by config:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc';
 
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  css: {
    modules: {
      generateScopedName: '[name]_[local]_[hash:base64:5]'
    }
  }
});

Additional context

No response

Validations

@sapphi-red
Copy link
Member

Why do you think having a query parameter is better than using generateScopedName?

@guoyunhe
Copy link
Author

guoyunhe commented Sep 10, 2024

Why do you think having a query parameter is better than using generateScopedName?

a query parameter allows you to handle complex situation, while generateScopedName is a static rule based on filepath etc. For example

// full path is src/order/product/index.module.css
import styles from './index.module.css?prefix=OrderProduct';

// full path is src/order/product/Cover.module.css
import styles from './Cover.module.css?prefix=OrderProductStatus';

Both query parameter and generateScopedName have their advantages.

@sapphi-red
Copy link
Member

while generateScopedName is a static rule based on filepath etc.

You can use pass a function to generateScopedName.

generateScopedName: function (name, filename, css) {
  const map = { 'src/order/product/index.module.css': 'OrderProduct' }
  const mapped = map[normalize(filename)]
  const line = css.substr(0, i).split(/[\r\n]/).length;
  const file = path.basename(filename, ".css");
  return "_" + map + "_" + line + "_" + name;
},

I noticed now that importing a same file with different query would be a problem.

// src/foo.js
import styles from './index.module.css?prefix=OrderProduct';
// src/bar.js
import styles from './index.module.css?prefix=OrderProductStatus';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants