UNPKG

7.59 kBMarkdownView Raw
1# typed-css-modules [![github actions](https://github.com/Quramy/typed-css-modules/workflows/build/badge.svg)](https://github.com/Quramy/typed-css-modules/actions) [![npm version](https://badge.fury.io/js/typed-css-modules.svg)](http://badge.fury.io/js/typed-css-modules)
2
3Creates TypeScript definition files from [CSS Modules](https://github.com/css-modules/css-modules) .css files.
4
5If you have the following css,
6
7```css
8/* styles.css */
9
10@value primary: red;
11
12.myClass {
13 color: primary;
14}
15```
16
17typed-css-modules creates the following .d.ts files from the above css:
18
19```ts
20/* styles.css.d.ts */
21declare const styles: {
22 readonly primary: string;
23 readonly myClass: string;
24};
25export = styles;
26```
27
28So, you can import CSS modules' class or variable into your TypeScript sources:
29
30```ts
31/* app.ts */
32import styles from './styles.css';
33console.log(`<div class="${styles.myClass}"></div>`);
34console.log(`<div style="color: ${styles.primary}"></div>`);
35```
36
37## CLI
38
39```sh
40npm install -g typed-css-modules
41```
42
43And exec `tcm <input directory>` command.
44For example, if you have .css files under `src` directory, exec the following:
45
46```sh
47tcm src
48```
49
50Then, this creates `*.css.d.ts` files under the directory which has the original .css file.
51
52```text
53(your project root)
54- src/
55 | myStyle.css
56 | myStyle.css.d.ts [created]
57```
58
59#### output directory
60
61Use `-o` or `--outDir` option.
62
63For example:
64
65```sh
66tcm -o dist src
67```
68
69```text
70(your project root)
71- src/
72 | myStyle.css
73- dist/
74 | myStyle.css.d.ts [created]
75```
76
77#### file name pattern
78
79By default, this tool searches `**/*.css` files under `<input directory>`.
80If you can customize the glob pattern, you can use `--pattern` or `-p` option.
81Note the quotes around the glob to `-p` (they are required, so that your shell does not perform the expansion).
82
83```sh
84tcm -p 'src/**/*.css' .
85```
86
87#### watch
88
89With `-w` or `--watch`, this CLI watches files in the input directory.
90
91#### validating type files
92
93With `-l` or `--listDifferent`, list any files that are different than those that would be generated.
94If any are different, exit with a status code 1.
95
96#### camelize CSS token
97
98With `-c` or `--camelCase`, kebab-cased CSS classes(such as `.my-class {...}`) are exported as camelized TypeScript variable name(`export const myClass: string`).
99
100You can pass `--camelCase dashes` to only camelize dashes in the class name. Since version `0.27.1` in the
101webpack `css-loader`. This will keep upperCase class names intact, e.g.:
102
103```css
104.SomeComponent {
105 height: 10px;
106}
107```
108
109becomes
110
111```typescript
112declare const styles: {
113 readonly SomeComponent: string;
114};
115export = styles;
116```
117
118See also [webpack css-loader's camelCase option](https://github.com/webpack/css-loader#camelcase).
119
120#### named exports (enable tree shaking)
121
122With `-e` or `--namedExports`, types are exported as named exports as opposed to default exports.
123This enables support for the `namedExports` css-loader feature, required for webpack to tree shake the final CSS (learn more [here](https://webpack.js.org/loaders/css-loader/#namedexport)).
124
125Use this option in combination with https://webpack.js.org/loaders/css-loader/#namedexport and https://webpack.js.org/loaders/style-loader/#namedexport (if you use `style-loader`).
126
127When this option is enabled, the type definition changes to support named exports.
128
129_NOTE: this option enables camelcase by default._
130
131```css
132.SomeComponent {
133 height: 10px;
134}
135```
136
137**Standard output:**
138
139```typescript
140declare const styles: {
141 readonly SomeComponent: string;
142};
143export = styles;
144```
145
146**Named exports output:**
147
148```typescript
149export const someComponent: string;
150```
151
152#### arbitrary file extensions
153
154With `-a` or `--allowArbitraryExtensions`, output filenames will be compatible with the "arbitrary file extensions" feature that was introduce in TypeScript 5.0. See [the docs](https://www.typescriptlang.org/tsconfig#allowArbitraryExtensions) for more info.
155
156In essence, the `*.css.d.ts` extension now becomes `*.d.css.ts` so that you can import CSS modules in projects using ESM module resolution.
157
158## API
159
160```sh
161npm install typed-css-modules
162```
163
164```js
165import DtsCreator from 'typed-css-modules';
166let creator = new DtsCreator();
167creator.create('src/style.css').then(content => {
168 console.log(content.tokens); // ['myClass']
169 console.log(content.formatted); // 'export const myClass: string;'
170 content.writeFile(); // writes this content to "src/style.css.d.ts"
171});
172```
173
174### class DtsCreator
175
176DtsCreator instance processes the input CSS and creates TypeScript definition contents.
177
178#### `new DtsCreator(option)`
179
180You can set the following options:
181
182- `option.rootDir`: Project root directory(default: `process.cwd()`).
183- `option.searchDir`: Directory which includes target `*.css` files(default: `'./'`).
184- `option.outDir`: Output directory(default: `option.searchDir`).
185- `option.camelCase`: Camelize CSS class tokens.
186- `option.namedExports`: Use named exports as opposed to default exports to enable tree shaking. Requires `import * as style from './file.module.css';` (default: `false`)
187- `option.allowArbitraryExtensions`: Output filenames that will be compatible with the "arbitrary file extensions" TypeScript feature
188- `option.EOL`: EOL (end of line) for the generated `d.ts` files. Possible values `'\n'` or `'\r\n'`(default: `os.EOL`).
189
190#### `create(filepath, contents) => Promise(dtsContent)`
191
192Returns `DtsContent` instance.
193
194- `filepath`: path of target .css file.
195- `contents`(optional): the CSS content of the `filepath`. If set, DtsCreator uses the contents instead of the original contents of the `filepath`.
196
197### class DtsContent
198
199DtsContent instance has `*.d.ts` content, final output path, and function to write the file.
200
201#### `writeFile(postprocessor) => Promise(dtsContent)`
202
203Writes the DtsContent instance's content to a file. Returns the DtsContent instance.
204
205- `postprocessor` (optional): a function that takes the formatted definition string and returns a modified string that will be the final content written to the file.
206
207 You could use this, for example, to pass generated definitions through a formatter like Prettier, or to add a comment to the top of generated files:
208
209 ```js
210 dtsContent.writeFile(definition => `// Generated automatically, do not edit\n${definition}`);
211 ```
212
213#### `tokens`
214
215An array of tokens is retrieved from the input CSS file.
216e.g. `['myClass']`
217
218#### `contents`
219
220An array of TypeScript definition expressions.
221e.g. `['export const myClass: string;']`.
222
223#### `formatted`
224
225A string of TypeScript definition expressions.
226
227e.g.
228
229```ts
230export const myClass: string;
231```
232
233#### `messageList`
234
235An array of messages. The messages contain invalid token information.
236e.g. `['my-class is not valid TypeScript variable name.']`.
237
238#### `outputFilePath`
239
240Final output file path.
241
242## Remarks
243
244If your input CSS file has the following class names, these invalid tokens are not written to output `.d.ts` file.
245
246```css
247/* TypeScript reserved word */
248.while {
249 color: red;
250}
251
252/* invalid TypeScript variable */
253/* If camelCase option is set, this token will be converted to 'myClass' */
254.my-class {
255 color: red;
256}
257
258/* it's ok */
259.myClass {
260 color: red;
261}
262```
263
264## Example
265
266There is a minimum example in this repository `example` folder. Clone this repository and run `cd example; npm i; npm start`.
267
268Or please see [https://github.com/Quramy/typescript-css-modules-demo](https://github.com/Quramy/typescript-css-modules-demo). It's a working demonstration of CSS Modules with React and TypeScript.
269
270## License
271
272This software is released under the MIT License, see LICENSE.txt.