Quramy / typed-css-modules

Creates .d.ts files from CSS Modules .css files
MIT License
1.04k stars 69 forks source link

Allowing to target individual files for `lint-staged` integration #89

Open zaripych opened 4 years ago

zaripych commented 4 years ago

It is possible to potentially modify .module.css file without running the CLI tool and as a result - forget to update the .d.ts files and leave CSS files incompatible with the JavaScript code.

To solve that I've been playing with lint-staged and came-up with the following config:

const { basename, dirname, join } = require('path');

function customBaseName(filename) {
  return filename.endsWith('.module.css')
    ? basename(filename, '.module.css')
    : basename(filename, '.module.css.d.ts');
}

function dtsFileName(filename) {
  return `${join(dirname(filename), customBaseName(filename))}.module.css.d.ts`;
}

module.exports = {
  /**
   * @param {[string]} filenames
   */
  '*.{module.css,module.css.d.ts}': filenames => [
    ...new Set(filenames.map(filename => `tcm '${dirname(filename)}'`)),
    ...new Set(
      filenames.map(filename => `prettier --write '${dtsFileName(filename)}'`)
    ),
    ...new Set(filenames.map(filename => `git add '${dtsFileName(filename)}'`)),
  ],
  '*.{tsx,jsx,ts,js,json,md,yaml,yml,css,d.ts}': ['prettier --write'],
  'package.json': ['sort-package-json'],
};

It works really well, except it is not possible to run CLI tool for a single file only, so I have to run it against the directory with changed .css file.

Here is the output of the application given different parameters:

➜  dataset-viewer git:(master) ✗ yarn tcm /home/rz/projects/dataset-viewer/src/pages     
yarn run v1.21.1
$ /home/rz/projects/dataset-viewer/node_modules/.bin/tcm /home/rz/projects/dataset-viewer/src/pages
Wrote /home/rz/projects/dataset-viewer/src/pages/_app.module.css.d.ts
Done in 0.27s.

➜  dataset-viewer git:(master) ✗ yarn tcm /home/rz/projects/dataset-viewer/src/pages/_app.module.css
yarn run v1.21.1
$ /home/rz/projects/dataset-viewer/node_modules/.bin/tcm /home/rz/projects/dataset-viewer/src/pages/_app.module.css
Done in 0.26s.

As you can see, during second run, when given a file as target the application doesn't write .d.ts file.

Would it be ok for me to change the application to allow file input in addition to directory?

zaripych commented 4 years ago

I should have looked at the code first. It appears that yarn tcm --help doesn't produce all the options in the output, so I thought it to be very limited in terms of options:

➜  dataset-viewer git:(master) ✗ yarn tcm --help
yarn run v1.21.1
$ /home/rz/projects/dataset-viewer/node_modules/.bin/tcm --help
Options:
  --help     Show help                                                 [boolean]
  --version  Show version number                                       [boolean]
Done in 0.10s.

Apparently there --pattern option that I could set to the name of the file in directory. A little clumsy for my purpose, but it is exactly what I need.

If anybody interested, final config:

const { basename, dirname, join } = require('path');

function customBaseName(filename) {
  return filename.endsWith('.module.css')
    ? basename(filename, '.module.css')
    : basename(filename, '.module.css.d.ts');
}

function dtsFileName(filename) {
  return `${join(dirname(filename), customBaseName(filename))}.module.css.d.ts`;
}

function cssBaseName(filename) {
  return `${customBaseName(filename)}.module.css`;
}

module.exports = {
  /**
   * @param {[string]} filenames
   */
  '*.{module.css,module.css.d.ts}': filenames => [
    ...new Set(
      filenames.map(
        filename =>
          `tcm '${dirname(filename)}' --pattern '${cssBaseName(filename)}'`
      )
    ),
    ...new Set(
      filenames.map(filename => `prettier --write '${dtsFileName(filename)}'`)
    ),
    ...new Set(filenames.map(filename => `git add '${dtsFileName(filename)}'`)),
  ],
  '*.{tsx,jsx,ts,js,json,md,yaml,yml,css,d.ts}': ['prettier --write'],
  'package.json': ['sort-package-json'],
};