activeguild / vite-plugin-sass-dts

This is a plugin that automatically creates a type file when using the CSS module type-safely.
MIT License
116 stars 18 forks source link

Classes in the common stylesheet are duplicated for every component #95

Open iPapatsoris opened 4 months ago

iPapatsoris commented 4 months ago

Hi,

In the example react-sass, I notice that for the common styles file (src/assets/styles/_index.scss), a different css module class is generated for every component that imports styles. For example, 2 different css module classes are generated for the .row class, because there are 2 files that import styles (App.tsx and User.tsx). This happens even if we don't directly use the .row class within User.tsx. In a larger project, it means that all the classes within the common stylesheet will be duplicated for every component that uses styles, even though we only need 1 instance of each common class.

Is it possible to generate only 1 class for .row, and reuse the same one across different files, while maintaining type safety? Or is there some other workaround to get the desired behavior?

Thanks!

activeguild commented 4 months ago

@iPapatsoris

Hi.

This may be achieved by combining the additinalData and global options.

https://github.com/activeguild/vite-plugin-sass-dts/blob/ff0f07b14b687107a2f61eec525cc58c9de8e989/example/react-sass/vite.config.ts#L13

https://github.com/activeguild/vite-plugin-sass-dts/blob/ff0f07b14b687107a2f61eec525cc58c9de8e989/example/react-sass/vite.config.ts#L37-L40

iPapatsoris commented 4 months ago

I already have these options enabled (I haven't changed anything from the original react-sass example). The problem persists, it's that if we inspect the final css file that is generated on production, we see two different generated classes for .row (for instance ._row_aki7x_1 and ._row_es2g2_1), whereas we only need 1.

activeguild commented 4 months ago

@iPapatsoris

I think we can achieve confirmation by doing the following. https://github.com/activeguild/vite-plugin-sass-dts/commit/dd447487171a66d7f236f850974e7a381f186d0c

iPapatsoris commented 4 months ago

Thanks, it works great!

One small downside that I noticed, is that if we switch the index.css file to index.scss (and update the import in main.tsx), then in the final production stylesheet we get the following:

:global .row { display: flex } .row { display: flex }

I'm not sure how to get rid of the :global .row rule and just keep the second rule, but maybe that's an unrelated issue. Nevertheless, the common classes are duplicated only once (and not for each component), so it shouldn't increase the code size by a lot.

activeguild commented 4 months ago

@iPapatsoris

I didn't understand the problem. What is the reason for leaving the second class?

.row {
display: flex
}
iPapatsoris commented 3 months ago

The problem is that after building for production, we see a compiled CSS file with the following code

:global .row { display: flex } .row { display: flex }

whereas we only need

.row { display: flex }

It's not a real problem, but more of an unnecessary rule that I was wondering how to get rid of. The :global .row doesn't serve any purpose in the final compiled CSS.