activeguild / vite-plugin-sass-dts

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

Problems with :export in sass modules and custom name mapping #70

Closed pschyma closed 1 year ago

pschyma commented 1 year ago

I'm having problems generating .d.ts files for modules like:

@import '../../common/_colors';

.Select {
  background-color: $dialogBackgroundColor;
  color: $dialogFontColor;
  height: var(--standardInputHeight);
}

:export {
  backgroundColor: $dialogBackgroundColor;
  focusedColor: $selectFocusColor;
  disabledColor: $color3;
  placeholderColor: $color4;
  valueColor: $dialogFontColor;
}

The vite css plugin generates the following object:

{
  "backgroundColor": "#ffffff",
  "focusedColor": "#deebff",
  "disabledColor": "#e0e0e0",
  "placeholderColor": "#bcbcbc",
  "valueColor": "#999999",
  "Select": "_Select_17bht_27"
}

But the generated .d.ts file is:

declare const classNames: {
  readonly Select: 'Select';
  readonly backgroundcolor: 'backgroundcolor';
  readonly focusedcolor: 'focusedcolor';
  readonly disabledcolor: 'disabledcolor';
  readonly placeholdercolor: 'placeholdercolor';
  readonly valuecolor: 'valuecolor';
};
export = classNames;

As this is a legacy project being moved to vite, I'd like to generate files that match the ones "generated" by CRA.

In our vite.config.ts we have:

import { viteCommonjs } from '@originjs/vite-plugin-commonjs';
import react from '@vitejs/plugin-react';
import eslintPlugin from 'vite-plugin-eslint';
import sassDts from 'vite-plugin-sass-dts';
import path from 'path';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
  css: {
    modules: {
      scopeBehaviour: 'local',
      localsConvention: (originalClassName) => originalClassName,
    },
  },
  plugins: [
    eslintPlugin(),
    react({
      jsxImportSource: '@welldone-software/why-did-you-render',
    }),
    viteCommonjs(),
    sassDts({ enabledMode: ['development'] }),
  ],
  resolve: {
    alias: {
      'react-redux': process.env.NODE_ENV === 'development' ? 'react-redux/lib' : 'react-redux',
      '~': path.resolve(__dirname, 'src/'),
    },
  },
  server: {
    preTransformRequests: true,
    port: 3000,
    hmr: {
      protocol: 'ws',
      host: 'localhost',
      port: 3000,
    },
  },
  define: {
    'process.env': process.env,
  },
});

We needed to use the custom localsConvention to achieve the match for class names (as the code base has inconsistent class names, e.g. FirstClass, second-class or thirdClass ).

activeguild commented 1 year ago

@pschyma

Thank you for the issue!!

We believe it can be corrected by referring to the following. https://github.com/vitejs/vite/blob/7a97a04b2a39e2c50aff8fe4ef3ca2e82fca6184/packages/vite/src/node/plugins/css.ts#L929-L952

activeguild commented 1 year ago

The final css output from the vite has nothing to do with the type, so it did not need to be taken into account when creating the type.