Skip to content

Commit 86af6ed

Browse files
committed
Merge branch 'release/2.4.0'
2 parents 72daeb8 + 9f7bac8 commit 86af6ed

14 files changed

+330
-13
lines changed

README.md

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ for [CSS Modules](https://github.com/css-modules/css-modules).
1212
## Table of contents
1313

1414
- [typescript-plugin-css-modules](#typescript-plugin-css-modules)
15-
- [Table of contents](#table-of-contents)
15+
- [Table of contents](#about-this-plugin)
16+
- [About this plugin](#table-of-contents)
1617
- [Installation](#installation)
1718
- [Importing CSS](#importing-css)
1819
- [Options](#options)
@@ -28,6 +29,22 @@ for [CSS Modules](https://github.com/css-modules/css-modules).
2829
- [Troubleshooting](#troubleshooting)
2930
- [About this project](#about-this-project)
3031

32+
## About this plugin
33+
34+
This plugin provides type information to IDEs and any other tools that work with [TypeScript language service plugins](https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin#whats-a-language-service-plugin).
35+
36+
At this time, TypeScript does not support plugins during compilation. This means that this plugin cannot:
37+
38+
- provide errors during compilation, or
39+
- add CSS module support to your project.
40+
41+
For more information, and/or to add support for this feature, see: https://github.com/microsoft/TypeScript/issues/16607.
42+
43+
If you need a different solution, these projects might help:
44+
45+
- For Jest support, see https://www.npmjs.com/package/jest-css-modules-transform (one of a few options).
46+
- For Webpack configuration, see https://webpack.js.org/loaders/css-loader/#pure-css-css-modules-and-postcss for an example.
47+
3148
## Installation
3249

3350
To install with Yarn:
@@ -54,6 +71,8 @@ Once installed, add this plugin to your `tsconfig.json`:
5471

5572
If you're using Visual Studio Code, please also follow these [instructions](#visual-studio-code).
5673

74+
As Webpack configurations vary, you may need to provide additional [options](#options) to this plugin to match your project configuration. For Create React App users, this plugin will work without additional configuration.
75+
5776
### Importing CSS
5877

5978
A default export is always provided for your CSS module.
@@ -179,10 +198,11 @@ The `classes` object represents all the classnames extracted from the CSS Module
179198

180199
#### `rendererOptions`
181200

182-
| Option | Default value | Description |
183-
| ------ | ------------- | ------------------------------------------------------------------------------------ |
184-
| `less` | `{}` | Set [renderer options for Less](http://lesscss.org/usage/#less-options). |
185-
| `sass` | `{}` | Set [renderer options for Sass](https://sass-lang.com/documentation/js-api#options). |
201+
| Option | Default value | Description |
202+
| -------- | ------------- | ------------------------------------------------------------------------------------ |
203+
| `less` | `{}` | Set [renderer options for Less](http://lesscss.org/usage/#less-options). |
204+
| `sass` | `{}` | Set [renderer options for Sass](https://sass-lang.com/documentation/js-api#options). |
205+
| `stylus` | `{}` | Set [renderer options for Stylus](https://stylus.bootcss.com/docs/js.html). |
186206

187207
> For convenience, `includePaths` for Sass are extended, not replaced. The defaults are the path of the current file, and `'node_modules'`.
188208
@@ -212,7 +232,7 @@ If your project doesn't already have global declarations for CSS Modules, you wi
212232

213233
Where you store global declarations is up to you. An example might look like: `./src/custom.d.ts`.
214234

215-
The below is an example that you can copy or modify. If you use a `customMatcher`, you'll need to modify this.
235+
The below is an example that you can copy or modify (you only declarations for exensions used in your project). If you use a `customMatcher`, you'll need to modify this.
216236

217237
```ts
218238
declare module '*.module.css' {
@@ -234,6 +254,11 @@ declare module '*.module.less' {
234254
const classes: { [key: string]: string };
235255
export default classes;
236256
}
257+
258+
declare module '*.module.styl' {
259+
const classes: { [key: string]: string };
260+
export default classes;
261+
}
237262
```
238263

239264
## Troubleshooting

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "typescript-plugin-css-modules",
3-
"version": "2.3.0",
3+
"version": "2.4.0",
44
"main": "lib/index.js",
55
"author": "Brody McKee <[email protected]>",
66
"license": "MIT",
@@ -15,6 +15,7 @@
1515
"scss",
1616
"sass",
1717
"less",
18+
"stylus",
1819
"modules",
1920
"plugin",
2021
"postcss",
@@ -73,7 +74,8 @@
7374
"postcss-icss-selectors": "^2.0.3",
7475
"postcss-load-config": "^2.1.0",
7576
"reserved-words": "^0.1.2",
76-
"sass": "^1.26.5"
77+
"sass": "^1.26.5",
78+
"stylus": "^0.54.7"
7779
},
7880
"devDependencies": {
7981
"@types/icss-utils": "^4.1.0",
@@ -85,6 +87,7 @@
8587
"@types/postcss-nested": "^4.1.0",
8688
"@types/reserved-words": "^0.1.0",
8789
"@types/sass": "^1.16.0",
90+
"@types/stylus": "^0.48.33",
8891
"@typescript-eslint/eslint-plugin": "^2.29.0",
8992
"@typescript-eslint/parser": "^2.29.0",
9093
"bootstrap": "4.4.1",

src/helpers/__tests__/__snapshots__/getDtsSnapshot.test.ts.snap

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,27 @@ export const __cssModule: true;
7272
export type AllClassNames = '';"
7373
`;
7474

75+
exports[`utils / cssSnapshots with file 'empty.module.styl' createExports should create an exports file 1`] = `
76+
"declare const classes: {
77+
78+
};
79+
export default classes;
80+
"
81+
`;
82+
83+
exports[`utils / cssSnapshots with file 'empty.module.styl' getClasses should return an object matching expected CSS 1`] = `Object {}`;
84+
85+
exports[`utils / cssSnapshots with file 'empty.module.styl' with a custom template should transform the generated dts 1`] = `
86+
"/* eslint-disable */
87+
declare const classes: {
88+
89+
};
90+
export default classes;
91+
92+
export const __cssModule: true;
93+
export type AllClassNames = '';"
94+
`;
95+
7596
exports[`utils / cssSnapshots with file 'import.module.css' createExports should create an exports file 1`] = `
7697
"declare const classes: {
7798
'classA': string;
@@ -182,6 +203,64 @@ export const __cssModule: true;
182203
export type AllClassNames = 'nested-class-parent' | 'child-class' | 'selector-blue' | 'selector-green' | 'selector-red' | 'column-1' | 'column-2' | 'column-3' | 'column-4' | 'color-set';"
183204
`;
184205

206+
exports[`utils / cssSnapshots with file 'import.module.styl' createExports should create an exports file 1`] = `
207+
"declare const classes: {
208+
'foo': string;
209+
'bar': string;
210+
'baz': string;
211+
'col-1': string;
212+
'col-2': string;
213+
'col-3': string;
214+
'local-class-1': string;
215+
'inside-local': string;
216+
'inside-1-name-2': string;
217+
'inside-2-name-1': string;
218+
};
219+
export default classes;
220+
export const foo: string;
221+
export const bar: string;
222+
export const baz: string;
223+
"
224+
`;
225+
226+
exports[`utils / cssSnapshots with file 'import.module.styl' getClasses should return an object matching expected CSS 1`] = `
227+
Object {
228+
"bar": "import-module__bar---2N4cR",
229+
"baz": "import-module__baz---6mQbB",
230+
"col-1": "import-module__col-1---2QW7j",
231+
"col-2": "import-module__col-2---2CRRS",
232+
"col-3": "import-module__col-3---17Luq",
233+
"foo": "import-module__foo---FJflO",
234+
"inside-1-name-2": "import-module__inside-1-name-2---wLnoq",
235+
"inside-2-name-1": "import-module__inside-2-name-1---1GRhn",
236+
"inside-local": "import-module__inside-local---1JuOc",
237+
"local-class-1": "import-module__local-class-1---3QupT",
238+
}
239+
`;
240+
241+
exports[`utils / cssSnapshots with file 'import.module.styl' with a custom template should transform the generated dts 1`] = `
242+
"/* eslint-disable */
243+
declare const classes: {
244+
'foo': string;
245+
'bar': string;
246+
'baz': string;
247+
'col-1': string;
248+
'col-2': string;
249+
'col-3': string;
250+
'local-class-1': string;
251+
'inside-local': string;
252+
'inside-1-name-2': string;
253+
'inside-2-name-1': string;
254+
};
255+
export default classes;
256+
export const foo: string;
257+
export const bar: string;
258+
export const baz: string;
259+
260+
export const __cssModule: true;
261+
export type AllClassNames = 'foo' | 'bar' | 'baz' | 'col-1' | 'col-2' | 'col-3' | 'local-class-1' | 'inside-local' | 'inside-1-name-2' | 'inside-2-name-1';"
262+
`;
263+
185264
exports[`utils / cssSnapshots with file 'test.module.css' createExports should create an exports file 1`] = `
186265
"declare const classes: {
187266
'classA': string;
@@ -456,9 +535,74 @@ export const __cssModule: true;
456535
export type AllClassNames = 'local-class-inside-global' | 'local-class' | 'local-class-2' | 'local-class-inside-local' | 'reserved-words' | 'default' | 'const' | 'nested-class-parent' | 'child-class' | 'nested-class-parent--extended' | 'section-1' | 'section-2' | 'section-3' | 'section-4' | 'section-5' | 'section-6' | 'section-7' | 'section-8' | 'section-9' | 'class-with-mixin';"
457536
`;
458537

538+
exports[`utils / cssSnapshots with file 'test.module.styl' createExports should create an exports file 1`] = `
539+
"declare const classes: {
540+
'foo': string;
541+
'bar': string;
542+
'baz': string;
543+
'col-1': string;
544+
'col-2': string;
545+
'col-3': string;
546+
'local-class-1': string;
547+
'inside-local': string;
548+
'inside-1-name-2': string;
549+
'inside-2-name-1': string;
550+
};
551+
export default classes;
552+
export const foo: string;
553+
export const bar: string;
554+
export const baz: string;
555+
"
556+
`;
557+
558+
exports[`utils / cssSnapshots with file 'test.module.styl' getClasses should return an object matching expected CSS 1`] = `
559+
Object {
560+
"bar": "test-module__bar---2WWom",
561+
"baz": "test-module__baz---1Rs9U",
562+
"col-1": "test-module__col-1---1XP3K",
563+
"col-2": "test-module__col-2---2nPwS",
564+
"col-3": "test-module__col-3---3CSSb",
565+
"foo": "test-module__foo---2pGaO",
566+
"inside-1-name-2": "test-module__inside-1-name-2---3Zdgw",
567+
"inside-2-name-1": "test-module__inside-2-name-1---3PYHl",
568+
"inside-local": "test-module__inside-local---2KzUE",
569+
"local-class-1": "test-module__local-class-1---3piX9",
570+
}
571+
`;
572+
573+
exports[`utils / cssSnapshots with file 'test.module.styl' with a custom template should transform the generated dts 1`] = `
574+
"/* eslint-disable */
575+
declare const classes: {
576+
'foo': string;
577+
'bar': string;
578+
'baz': string;
579+
'col-1': string;
580+
'col-2': string;
581+
'col-3': string;
582+
'local-class-1': string;
583+
'inside-local': string;
584+
'inside-1-name-2': string;
585+
'inside-2-name-1': string;
586+
};
587+
export default classes;
588+
export const foo: string;
589+
export const bar: string;
590+
export const baz: string;
591+
592+
export const __cssModule: true;
593+
export type AllClassNames = 'foo' | 'bar' | 'baz' | 'col-1' | 'col-2' | 'col-3' | 'local-class-1' | 'inside-local' | 'inside-1-name-2' | 'inside-2-name-1';"
594+
`;
595+
459596
exports[`utils / cssSnapshots with includePaths in sass options should find external file from includePaths 1`] = `
460597
Object {
461598
"big-font": "include-path-module__big-font---Td7hY",
462599
"class-with-mixin": "include-path-module__class-with-mixin---1u87_",
463600
}
464601
`;
602+
603+
exports[`utils / cssSnapshots with includePaths in stylus options should find external file from includePaths 1`] = `
604+
Object {
605+
"external-class": "include-path-module__external-class---ecH0A",
606+
"include-path": "include-path-module__include-path---2f2uR",
607+
}
608+
`;

src/helpers/__tests__/cssExtensions.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@ describe('utils / cssExtensions', () => {
77
it('should match CSS module extensions', () => {
88
expect(isCSS('./myfile.module.scss')).toBe(true);
99
expect(isCSS('./myfile.module.sass')).toBe(true);
10+
expect(isCSS('./myfile.module.less')).toBe(true);
11+
expect(isCSS('./myfile.module.styl')).toBe(true);
1012
expect(isCSS('./myfile.module.css')).toBe(true);
1113
});
1214

1315
it('should not match non-CSS module extensions', () => {
1416
expect(isCSS('./myfile.module.s')).toBe(false);
1517
expect(isCSS('./myfile.scss')).toBe(false);
1618
expect(isCSS('./myfile.sass')).toBe(false);
19+
expect(isCSS('./myfile.less')).toBe(false);
20+
expect(isCSS('./myfile.styl')).toBe(false);
1721
expect(isCSS('./myfile.css')).toBe(false);
1822
});
1923
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.include-path
2+
display inline
3+
4+
.external-class
5+
display inline

src/helpers/__tests__/fixtures/empty.module.styl

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import 'test.module.styl';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import 'package/_external.module.styl';
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
mySelectors = '.foo,.bar,.baz'
2+
3+
{mySelectors}
4+
background: #000
5+
6+
for row in 1 2 3
7+
.col-{row}
8+
height: 10px * row
9+
10+
:local(.local-class-1)
11+
.inside-local
12+
color rebeccapurple
13+
14+
inside(name1, name2, indent, outside)
15+
.inside-1-{name1}
16+
outside(indent)
17+
18+
.inside-2-{name2}
19+
outside(indent)
20+
21+
inside('name-2', 'name-1', 24px, @(indent) {
22+
margin-left indent
23+
margin-right indent
24+
})

src/helpers/__tests__/getDtsSnapshot.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ import { Options } from '../../options';
1313
const testFileNames = [
1414
'test.module.css',
1515
'test.module.less',
16+
'test.module.styl',
1617
'test.module.scss',
1718
'test.module.sass',
1819
'empty.module.less',
1920
'empty.module.sass',
2021
'empty.module.scss',
22+
'empty.module.styl',
2123
'import.module.css',
2224
'import.module.less',
25+
'import.module.styl',
2326
];
2427

2528
const logger: Logger = {
@@ -157,4 +160,30 @@ describe('utils / cssSnapshots', () => {
157160
expect(classes).toMatchSnapshot();
158161
});
159162
});
163+
164+
describe('with includePaths in stylus options', () => {
165+
const fileName = join(__dirname, 'fixtures', 'include-path.module.styl');
166+
const css = readFileSync(fileName, 'utf8');
167+
168+
const options: Options = {
169+
rendererOptions: {
170+
stylus: {
171+
paths: [join(__dirname, 'external')],
172+
},
173+
},
174+
};
175+
176+
it('should find external file from includePaths', () => {
177+
const classes = getClasses({
178+
css,
179+
fileName,
180+
logger,
181+
options,
182+
processor,
183+
compilerOptions,
184+
});
185+
186+
expect(classes).toMatchSnapshot();
187+
});
188+
});
160189
});

src/helpers/cssExtensions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export type isCSSFn = (fileName: string) => boolean;
2-
const DEFAULT_REGEXP = /\.module\.(c|le|sa|sc)ss$/;
2+
const DEFAULT_REGEXP = /\.module\.(((c|le|sa|sc)ss)|styl)$/;
33

44
const isRelative = (fileName: string) => /^\.\.?($|[\\/])/.test(fileName);
55

0 commit comments

Comments
 (0)