Skip to content

Commit 996e931

Browse files
lianapachemrmckeb
authored andcommitted
Add LESS support (#21)
1 parent 5463b4f commit 996e931

File tree

9 files changed

+183
-26
lines changed

9 files changed

+183
-26
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
src/helpers/__tests__/fixtures/test.module.less

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@
4343
},
4444
"dependencies": {
4545
"icss-utils": "^4.1.0",
46+
"less": "^3.9.0",
4647
"lodash": "^4.17.11",
4748
"postcss": "^7.0.16",
4849
"postcss-icss-selectors": "^2.0.3",
4950
"sass": "^1.20.1"
5051
},
5152
"devDependencies": {
5253
"@types/jest": "^24.0.13",
54+
"@types/less": "^3.0.0",
5355
"@types/lodash": "^4.14.132",
5456
"@types/node": "^10.12.18",
5557
"@types/sass": "^1.16.0",

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

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`utils / cssSnapshots with file 'empty.module.less' createExports should create an exports file 1`] = `
4+
"declare const classes: {
5+
6+
};
7+
export default classes;
8+
"
9+
`;
10+
11+
exports[`utils / cssSnapshots with file 'empty.module.less' getClasses should return an object matching expected CSS 1`] = `Object {}`;
12+
313
exports[`utils / cssSnapshots with file 'empty.module.scss' createExports should create an exports file 1`] = `
414
"declare const classes: {
515
@@ -36,6 +46,38 @@ Object {
3646
}
3747
`;
3848

49+
exports[`utils / cssSnapshots with file 'test.module.less' createExports should create an exports file 1`] = `
50+
"declare const classes: {
51+
'nested-class-parent': string;
52+
'child-class': string;
53+
'selector-blue': string;
54+
'selector-green': string;
55+
'selector-red': string;
56+
'column-1': string;
57+
'column-2': string;
58+
'column-3': string;
59+
'column-4': string;
60+
'color-set': string;
61+
};
62+
export default classes;
63+
"
64+
`;
65+
66+
exports[`utils / cssSnapshots with file 'test.module.less' getClasses should return an object matching expected CSS 1`] = `
67+
Object {
68+
"child-class": "file__child-class---1mwoB",
69+
"color-set": "file__color-set---9sHH_",
70+
"column-1": "file__column-1---vHRb_",
71+
"column-2": "file__column-2---28y1r",
72+
"column-3": "file__column-3---1PsZw",
73+
"column-4": "file__column-4---2qaaI",
74+
"nested-class-parent": "file__nested-class-parent---_ft7G",
75+
"selector-blue": "file__selector-blue---3mslq",
76+
"selector-green": "file__selector-green---143xX",
77+
"selector-red": "file__selector-red---Gckob",
78+
}
79+
`;
80+
3981
exports[`utils / cssSnapshots with file 'test.module.scss' createExports should create an exports file 1`] = `
4082
"declare const classes: {
4183
'local-class-inside-global': string;
@@ -61,21 +103,21 @@ export default classes;
61103

62104
exports[`utils / cssSnapshots with file 'test.module.scss' getClasses should return an object matching expected CSS 1`] = `
63105
Object {
64-
"child-class": "file__child-class---1mwoB",
65-
"local-class": "file__local-class---3KegX",
66-
"local-class-2": "file__local-class-2---2h6qz",
67-
"local-class-inside-global": "file__local-class-inside-global---2xH_Y",
68-
"local-class-inside-local": "file__local-class-inside-local---QdL6b",
69-
"nested-class-parent": "file__nested-class-parent---_ft7G",
70-
"nested-class-parent--extended": "file__nested-class-parent--extended---1642l",
71-
"section-1": "file__section-1---2EiKX",
72-
"section-2": "file__section-2---2f4aZ",
73-
"section-3": "file__section-3---R_Ilj",
74-
"section-4": "file__section-4---3EjYO",
75-
"section-5": "file__section-5---1DSe8",
76-
"section-6": "file__section-6---1RoVP",
77-
"section-7": "file__section-7---l5yMj",
78-
"section-8": "file__section-8---3FEWv",
79-
"section-9": "file__section-9---1TFYE",
106+
"child-class": "file__child-class---1QWYM",
107+
"local-class": "file__local-class---3SW3k",
108+
"local-class-2": "file__local-class-2----c5z7",
109+
"local-class-inside-global": "file__local-class-inside-global---1T0um",
110+
"local-class-inside-local": "file__local-class-inside-local---1Z9pB",
111+
"nested-class-parent": "file__nested-class-parent---3qXdF",
112+
"nested-class-parent--extended": "file__nested-class-parent--extended---qsVau",
113+
"section-1": "file__section-1---1IHCS",
114+
"section-2": "file__section-2---cLFhf",
115+
"section-3": "file__section-3---1ldKa",
116+
"section-4": "file__section-4---2u0CG",
117+
"section-5": "file__section-5---1lAYL",
118+
"section-6": "file__section-6---2YZ9I",
119+
"section-7": "file__section-7---3w-OF",
120+
"section-8": "file__section-8---3RB8g",
121+
"section-9": "file__section-9---3_Mtj",
80122
}
81123
`;

src/helpers/__tests__/cssSnapshots.test.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
import { readFileSync } from 'fs';
22
import { IICSSExports } from 'icss-utils';
33
import { join } from 'path';
4-
import { createExports, getClasses } from '../cssSnapshots';
4+
import { createExports, getClasses, FileTypes } from '../cssSnapshots';
55

66
const testFileNames = [
77
'test.module.css',
8+
'test.module.less',
89
'test.module.scss',
10+
'empty.module.less',
911
'empty.module.scss',
1012
];
1113

1214
describe('utils / cssSnapshots', () => {
13-
testFileNames.map((filename) => {
15+
testFileNames.forEach((filename) => {
1416
let classes: IICSSExports;
17+
const isLess = filename.includes('less');
18+
const fileType = isLess ? FileTypes.less : FileTypes.css;
1519
const testFile = readFileSync(
1620
join(__dirname, 'fixtures', filename),
1721
'utf8',
1822
);
1923

2024
beforeAll(() => {
21-
classes = getClasses(testFile);
25+
classes = getClasses(testFile, fileType);
2226
});
2327

2428
describe(`with file '${filename}'`, () => {

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

Whitespace-only changes.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
.nested-class-parent {
2+
color: black;
3+
4+
.child-class {
5+
font-size: 12px;
6+
}
7+
}
8+
9+
@selectors: blue, green, red;
10+
11+
each(@selectors, {
12+
.selector-@{value} {
13+
color: b;
14+
}
15+
});
16+
17+
each(range(4), {
18+
.column-@{value} {
19+
height: (@value * 50px);
20+
}
21+
})
22+
23+
.color-set () {
24+
one: blue;
25+
two: green;
26+
three: red;
27+
}
28+
29+
.color-set {
30+
each(.color-set (), .(@v, @k, @i) {
31+
@{k}-@{i}: @v;
32+
});
33+
}

src/helpers/cssSnapshots.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as postcss from 'postcss';
33
import * as postcssIcssSelectors from 'postcss-icss-selectors';
44
import * as ts_module from 'typescript/lib/tsserverlibrary';
55
import * as sass from 'sass';
6+
import * as less from 'less';
67
import { transformClasses } from './classTransforms';
78
import { Options } from '../options';
89

@@ -15,15 +16,29 @@ const flattenClassNames = (
1516
currentValue: string[],
1617
) => previousValue.concat(currentValue);
1718

18-
export const getClasses = (css: string, isLess: boolean = false) => {
19+
export const enum FileTypes {
20+
css = 'css',
21+
sass = 'sass',
22+
less = 'less',
23+
}
24+
25+
export const getClasses = (
26+
css: string,
27+
fileType: FileTypes = FileTypes.css,
28+
) => {
1929
try {
20-
let transformedCss: string;
21-
if (isLess) {
22-
transformedCss = '';
30+
let transformedCss = '';
31+
32+
if (fileType === FileTypes.less) {
33+
less.render(css, { asyncImport: true } as any, (err, output) => {
34+
transformedCss = output.css.toString();
35+
});
2336
} else {
2437
transformedCss = sass.renderSync({ data: css }).css.toString();
2538
}
39+
2640
const processedCss = processor.process(transformedCss);
41+
2742
return extractICSS(processedCss.root).icssExports;
2843
} catch (e) {
2944
return {};

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"compilerOptions": {
33
"declaration": true,
44
"forceConsistentCasingInFileNames": true,
5-
"lib": ["esnext"],
5+
"lib": ["esnext", "dom"],
66
"module": "commonjs",
77
"moduleResolution": "node",
88
"noEmitOnError": true,

yarn.lock

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,11 @@
350350
dependencies:
351351
"@types/jest-diff" "*"
352352

353+
"@types/less@^3.0.0":
354+
version "3.0.0"
355+
resolved "https://registry.yarnpkg.com/@types/less/-/less-3.0.0.tgz#2b76e6a2fecf7108c1c2b701ad846b605d8f2c7e"
356+
integrity sha512-AUO7jdGrDi7x+7w2vYHNCom3NRjkspKSvamYp013Jyd/VYxpm0xtCupRZCdSX2IPx/W9C81Cj7nPXqQUj6MlQQ==
357+
353358
"@types/lodash@^4.14.132":
354359
version "4.14.132"
355360
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.132.tgz#8ce45ca8745ff2e004fac0de0ab46f61e390ffa0"
@@ -532,6 +537,11 @@ arrify@^1.0.1:
532537
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
533538
integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
534539

540+
asap@~2.0.3:
541+
version "2.0.6"
542+
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
543+
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
544+
535545
asn1@~0.2.3:
536546
version "0.2.4"
537547
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
@@ -843,6 +853,11 @@ cliui@^4.0.0:
843853
strip-ansi "^4.0.0"
844854
wrap-ansi "^2.0.0"
845855

856+
clone@^2.1.2:
857+
version "2.1.2"
858+
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
859+
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
860+
846861
co@^4.6.0:
847862
version "4.6.0"
848863
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -1114,6 +1129,13 @@ end-of-stream@^1.1.0:
11141129
dependencies:
11151130
once "^1.4.0"
11161131

1132+
errno@^0.1.1:
1133+
version "0.1.7"
1134+
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
1135+
integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==
1136+
dependencies:
1137+
prr "~1.0.1"
1138+
11171139
error-ex@^1.3.1:
11181140
version "1.3.2"
11191141
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
@@ -1641,6 +1663,11 @@ ignore@^3.3.7:
16411663
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
16421664
integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==
16431665

1666+
image-size@~0.5.0:
1667+
version "0.5.5"
1668+
resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c"
1669+
integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=
1670+
16441671
import-fresh@^2.0.0:
16451672
version "2.0.0"
16461673
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
@@ -2442,6 +2469,22 @@ left-pad@^1.3.0:
24422469
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
24432470
integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==
24442471

2472+
less@^3.9.0:
2473+
version "3.9.0"
2474+
resolved "https://registry.yarnpkg.com/less/-/less-3.9.0.tgz#b7511c43f37cf57dc87dffd9883ec121289b1474"
2475+
integrity sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==
2476+
dependencies:
2477+
clone "^2.1.2"
2478+
optionalDependencies:
2479+
errno "^0.1.1"
2480+
graceful-fs "^4.1.2"
2481+
image-size "~0.5.0"
2482+
mime "^1.4.1"
2483+
mkdirp "^0.5.0"
2484+
promise "^7.1.1"
2485+
request "^2.83.0"
2486+
source-map "~0.6.0"
2487+
24452488
leven@^2.1.0:
24462489
version "2.1.0"
24472490
resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
@@ -2609,6 +2652,11 @@ mime-types@^2.1.12, mime-types@~2.1.19:
26092652
dependencies:
26102653
mime-db "~1.37.0"
26112654

2655+
mime@^1.4.1:
2656+
version "1.6.0"
2657+
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
2658+
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
2659+
26122660
mimic-fn@^2.0.0:
26132661
version "2.1.0"
26142662
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
@@ -3201,6 +3249,13 @@ process-nextick-args@~2.0.0:
32013249
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
32023250
integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
32033251

3252+
promise@^7.1.1:
3253+
version "7.3.1"
3254+
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
3255+
integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
3256+
dependencies:
3257+
asap "~2.0.3"
3258+
32043259
prompts@^2.0.1:
32053260
version "2.1.0"
32063261
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.1.0.tgz#bf90bc71f6065d255ea2bdc0fe6520485c1b45db"
@@ -3209,6 +3264,11 @@ prompts@^2.0.1:
32093264
kleur "^3.0.2"
32103265
sisteransi "^1.0.0"
32113266

3267+
prr@~1.0.1:
3268+
version "1.0.1"
3269+
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
3270+
integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
3271+
32123272
pseudomap@^1.0.2:
32133273
version "1.0.2"
32143274
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
@@ -3378,7 +3438,7 @@ request-promise-native@^1.0.5:
33783438
stealthy-require "^1.1.0"
33793439
tough-cookie ">=2.3.3"
33803440

3381-
request@^2.87.0:
3441+
request@^2.83.0, request@^2.87.0:
33823442
version "2.88.0"
33833443
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
33843444
integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
@@ -3669,7 +3729,7 @@ source-map@^0.5.0, source-map@^0.5.6:
36693729
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
36703730
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
36713731

3672-
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
3732+
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
36733733
version "0.6.1"
36743734
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
36753735
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==

0 commit comments

Comments
 (0)