happy-css-modules 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -45
- package/dist/cli.js +28 -1
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.js +11 -0
- package/dist/cli.test.js.map +1 -1
- package/dist/emitter/dts.js +9 -1
- package/dist/emitter/dts.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/loader/index.test.js +79 -1
- package/dist/loader/index.test.js.map +1 -1
- package/dist/loader/postcss.d.ts +5 -1
- package/dist/loader/postcss.js +26 -30
- package/dist/loader/postcss.js.map +1 -1
- package/dist/resolver/webpack-resolver.d.ts +12 -2
- package/dist/resolver/webpack-resolver.js +12 -3
- package/dist/resolver/webpack-resolver.js.map +1 -1
- package/dist/resolver/webpack-resolver.test.js +43 -7
- package/dist/resolver/webpack-resolver.test.js.map +1 -1
- package/dist/runner.d.ts +13 -0
- package/dist/runner.js +18 -6
- package/dist/runner.js.map +1 -1
- package/dist/runner.test.js +35 -8
- package/dist/runner.test.js.map +1 -1
- package/dist/test/util.d.ts +1 -1
- package/dist/test/util.js +15 -8
- package/dist/test/util.js.map +1 -1
- package/dist/transformer/index.d.ts +3 -1
- package/dist/transformer/index.js +7 -3
- package/dist/transformer/index.js.map +1 -1
- package/dist/transformer/index.test.d.ts +1 -0
- package/dist/transformer/index.test.js +66 -0
- package/dist/transformer/index.test.js.map +1 -0
- package/dist/transformer/less-transformer.test.js +6 -6
- package/dist/transformer/postcss-transformer.d.ts +12 -0
- package/dist/transformer/postcss-transformer.js +32 -0
- package/dist/transformer/postcss-transformer.js.map +1 -0
- package/dist/transformer/postcss-transformer.test.d.ts +1 -0
- package/dist/transformer/postcss-transformer.test.js +176 -0
- package/dist/transformer/postcss-transformer.test.js.map +1 -0
- package/dist/transformer/scss-transformer.js +19 -17
- package/dist/transformer/scss-transformer.js.map +1 -1
- package/dist/transformer/scss-transformer.test.js +8 -8
- package/package.json +6 -3
- package/src/cli.test.ts +15 -0
- package/src/cli.ts +27 -1
- package/src/emitter/dts.ts +10 -1
- package/src/index.ts +8 -2
- package/src/loader/index.test.ts +79 -1
- package/src/loader/postcss.ts +42 -40
- package/src/resolver/webpack-resolver.test.ts +63 -7
- package/src/resolver/webpack-resolver.ts +26 -5
- package/src/runner.test.ts +38 -8
- package/src/runner.ts +31 -7
- package/src/test/util.ts +15 -9
- package/src/transformer/index.test.ts +71 -0
- package/src/transformer/index.ts +11 -3
- package/src/transformer/less-transformer.test.ts +6 -6
- package/src/transformer/postcss-transformer.test.ts +188 -0
- package/src/transformer/postcss-transformer.ts +57 -0
- package/src/transformer/scss-transformer.test.ts +8 -8
- package/src/transformer/scss-transformer.ts +25 -27
|
@@ -41,37 +41,37 @@ test('handles less features', async () => {
|
|
|
41
41
|
{
|
|
42
42
|
name: "b_1",
|
|
43
43
|
originalLocations: [
|
|
44
|
-
{ filePath: "<fixtures>/test/2.less", start: { line: 1, column: 1 }, end: { line: 1, column:
|
|
44
|
+
{ filePath: "<fixtures>/test/2.less", start: { line: 1, column: 1 }, end: { line: 1, column: 4 } },
|
|
45
45
|
],
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
name: "a_1",
|
|
49
49
|
originalLocations: [
|
|
50
|
-
{ filePath: "<fixtures>/test/1.less", start: { line: 2, column: 1 }, end: { line: 2, column:
|
|
50
|
+
{ filePath: "<fixtures>/test/1.less", start: { line: 2, column: 1 }, end: { line: 2, column: 4 } },
|
|
51
51
|
],
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
name: "a_2",
|
|
55
55
|
originalLocations: [
|
|
56
|
-
{ filePath: "<fixtures>/test/1.less", start: { line: 3, column: 1 }, end: { line: 3, column:
|
|
56
|
+
{ filePath: "<fixtures>/test/1.less", start: { line: 3, column: 1 }, end: { line: 3, column: 4 } },
|
|
57
57
|
],
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
60
|
name: "a_2_1",
|
|
61
61
|
originalLocations: [
|
|
62
|
-
{ filePath: "<fixtures>/test/1.less", start: { line: 6, column: 3 }, end: { line: 6, column:
|
|
62
|
+
{ filePath: "<fixtures>/test/1.less", start: { line: 6, column: 3 }, end: { line: 6, column: 8 } },
|
|
63
63
|
],
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
name: "a_2_2",
|
|
67
67
|
originalLocations: [
|
|
68
|
-
{ filePath: "<fixtures>/test/1.less", start: { line: 7, column: 3 }, end: { line: 7, column:
|
|
68
|
+
{ filePath: "<fixtures>/test/1.less", start: { line: 7, column: 3 }, end: { line: 7, column: 8 } },
|
|
69
69
|
],
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
name: "c",
|
|
73
73
|
originalLocations: [
|
|
74
|
-
{ filePath: "<fixtures>/test/3.less", start: { line: 1, column: 1 }, end: { line: 1, column:
|
|
74
|
+
{ filePath: "<fixtures>/test/3.less", start: { line: 1, column: 1 }, end: { line: 1, column: 2 } },
|
|
75
75
|
],
|
|
76
76
|
},
|
|
77
77
|
],
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Transformer } from '../index.js';
|
|
2
|
+
export declare type PostcssTransformerOptions = {
|
|
3
|
+
cwd?: string | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* The option compatible with postcss's `--config`. It is a relative or absolute path.
|
|
6
|
+
* @example '.'
|
|
7
|
+
* @example 'postcss.config.js'
|
|
8
|
+
* @example '/home/user/repository/src'
|
|
9
|
+
*/
|
|
10
|
+
postcssConfig?: string | undefined;
|
|
11
|
+
};
|
|
12
|
+
export declare const createPostcssTransformer: (postcssTransformerOptions?: PostcssTransformerOptions) => Transformer;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { default as postcss } from 'postcss';
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
5
|
+
const postcssrc = require('postcss-load-config');
|
|
6
|
+
function isDependencyMessage(message) {
|
|
7
|
+
return message.type === 'dependency';
|
|
8
|
+
}
|
|
9
|
+
export const createPostcssTransformer = (postcssTransformerOptions) => {
|
|
10
|
+
const cwd = postcssTransformerOptions?.cwd ?? process.cwd();
|
|
11
|
+
const configSearchPath = postcssTransformerOptions?.postcssConfig
|
|
12
|
+
? resolve(cwd, postcssTransformerOptions?.postcssConfig)
|
|
13
|
+
: cwd;
|
|
14
|
+
return async (source, options) => {
|
|
15
|
+
// NOTE: postcss-load-config cache the configuration file so is is not reloaded.
|
|
16
|
+
const postcssConfig = await postcssrc({ cwd }, configSearchPath).catch((e) => {
|
|
17
|
+
if (e instanceof Error && e.message.includes('No PostCSS Config found'))
|
|
18
|
+
return undefined;
|
|
19
|
+
throw e;
|
|
20
|
+
});
|
|
21
|
+
if (postcssConfig === undefined)
|
|
22
|
+
return false;
|
|
23
|
+
const result = await postcss(postcssConfig.plugins).process(source, {
|
|
24
|
+
...postcssConfig.options,
|
|
25
|
+
from: options.from,
|
|
26
|
+
map: { inline: false, absolute: true },
|
|
27
|
+
});
|
|
28
|
+
const dependencies = result.messages.filter(isDependencyMessage).map((message) => message.file);
|
|
29
|
+
return { css: result.css, map: result.map, dependencies };
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=postcss-transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postcss-transformer.js","sourceRoot":"","sources":["../../src/transformer/postcss-transformer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAgB,MAAM,SAAS,CAAC;AAI3D,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,SAAS,GAAyC,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAQvF,SAAS,mBAAmB,CAAC,OAAgB;IAC3C,OAAO,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC;AACvC,CAAC;AAaD,MAAM,CAAC,MAAM,wBAAwB,GAA2E,CAC9G,yBAAyB,EACzB,EAAE;IACF,MAAM,GAAG,GAAG,yBAAyB,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC5D,MAAM,gBAAgB,GAAG,yBAAyB,EAAE,aAAa;QAC/D,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,yBAAyB,EAAE,aAAa,CAAC;QACxD,CAAC,CAAC,GAAG,CAAC;IACR,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;QAC/B,gFAAgF;QAChF,MAAM,aAAa,GAAuB,MAAM,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;YAC/F,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC1F,MAAM,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;QACH,IAAI,aAAa,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAE9C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE;YAClE,GAAG,aAAa,CAAC,OAAO;YACxB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;SACvC,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEhG,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,YAAY,EAAE,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { jest } from '@jest/globals';
|
|
4
|
+
import dedent from 'dedent';
|
|
5
|
+
import { Loader } from '../loader/index.js';
|
|
6
|
+
import { createFixtures, getFixturePath } from '../test/util.js';
|
|
7
|
+
import { createPostcssTransformer } from './postcss-transformer.js';
|
|
8
|
+
const cwd = getFixturePath('/');
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
// NOTE: postcss-load-config caches the configuration file using the path as a key.
|
|
11
|
+
// Therefore, change the path for each test case so that a new configuration file is always used.
|
|
12
|
+
test('handles postcss features', async () => {
|
|
13
|
+
const uuid = randomUUID();
|
|
14
|
+
const loader = new Loader({
|
|
15
|
+
transformer: createPostcssTransformer({
|
|
16
|
+
cwd,
|
|
17
|
+
postcssConfig: `${uuid}/postcss.config.js`,
|
|
18
|
+
}),
|
|
19
|
+
});
|
|
20
|
+
createFixtures({
|
|
21
|
+
[`/${uuid}/postcss.config.js`]: dedent `
|
|
22
|
+
module.exports = {
|
|
23
|
+
plugins: [
|
|
24
|
+
require('${require.resolve('postcss-simple-vars')}'),
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
`,
|
|
28
|
+
'/test/1.css': dedent `
|
|
29
|
+
$prefix: foo;
|
|
30
|
+
.$(prefix)_bar {}
|
|
31
|
+
`,
|
|
32
|
+
});
|
|
33
|
+
const result = await loader.load(getFixturePath('/test/1.css'));
|
|
34
|
+
expect(result).toMatchInlineSnapshot(`
|
|
35
|
+
{
|
|
36
|
+
dependencies: [],
|
|
37
|
+
tokens: [
|
|
38
|
+
{
|
|
39
|
+
name: "foo_bar",
|
|
40
|
+
originalLocations: [
|
|
41
|
+
{ filePath: "<fixtures>/test/1.css", start: { line: 2, column: 1 }, end: { line: 2, column: 8 } },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
}
|
|
46
|
+
`);
|
|
47
|
+
});
|
|
48
|
+
test('tracks dependencies that have been pre-bundled by postcss compiler', async () => {
|
|
49
|
+
const uuid = randomUUID();
|
|
50
|
+
const loader = new Loader({
|
|
51
|
+
transformer: createPostcssTransformer({
|
|
52
|
+
cwd,
|
|
53
|
+
postcssConfig: `${uuid}/postcss.config.js`,
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
const loadSpy = jest.spyOn(loader, 'load');
|
|
57
|
+
createFixtures({
|
|
58
|
+
[`/${uuid}/postcss.config.js`]: dedent `
|
|
59
|
+
module.exports = {
|
|
60
|
+
plugins: [
|
|
61
|
+
require('${require.resolve('postcss-import')}'),
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
`,
|
|
65
|
+
'/test/1.css': dedent `
|
|
66
|
+
@import './2.css';
|
|
67
|
+
@import './3.css';
|
|
68
|
+
`,
|
|
69
|
+
'/test/2.css': ``,
|
|
70
|
+
'/test/3.css': `@import './4.css'`,
|
|
71
|
+
'/test/4.css': ``,
|
|
72
|
+
});
|
|
73
|
+
const result = await loader.load(getFixturePath('/test/1.css'));
|
|
74
|
+
// The files imported using @import are pre-bundled by the compiler.
|
|
75
|
+
// Therefore, `Loader#load` is not called to process other files.
|
|
76
|
+
expect(loadSpy).toBeCalledTimes(1);
|
|
77
|
+
expect(loadSpy).toHaveBeenNthCalledWith(1, getFixturePath('/test/1.css'));
|
|
78
|
+
// The files pre-bundled by the compiler are also included in `result.dependencies`
|
|
79
|
+
expect(result.dependencies).toStrictEqual(['/test/2.css', '/test/3.css', '/test/4.css'].map(getFixturePath));
|
|
80
|
+
});
|
|
81
|
+
test('resolves specifier using resolver', async () => {
|
|
82
|
+
const uuid = randomUUID();
|
|
83
|
+
const loader = new Loader({
|
|
84
|
+
transformer: createPostcssTransformer({
|
|
85
|
+
cwd,
|
|
86
|
+
postcssConfig: `${uuid}/postcss.config.js`,
|
|
87
|
+
}),
|
|
88
|
+
});
|
|
89
|
+
createFixtures({
|
|
90
|
+
[`/${uuid}/postcss.config.js`]: dedent `
|
|
91
|
+
module.exports = {
|
|
92
|
+
plugins: [
|
|
93
|
+
// When using postcss-import, the resolver of happy-css-modules is ignored.
|
|
94
|
+
// Therefore, we test here without postcss-import.
|
|
95
|
+
// require('${require.resolve('postcss-import')}'),
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
`,
|
|
99
|
+
'/test/1.css': dedent `
|
|
100
|
+
@import 'package';
|
|
101
|
+
`,
|
|
102
|
+
'/node_modules/package/index.css': `.a {}`,
|
|
103
|
+
});
|
|
104
|
+
const result = await loader.load(getFixturePath('/test/1.css'));
|
|
105
|
+
expect(result.dependencies).toStrictEqual(['/node_modules/package/index.css'].map(getFixturePath));
|
|
106
|
+
});
|
|
107
|
+
test('ignores http(s) protocol file', async () => {
|
|
108
|
+
const uuid = randomUUID();
|
|
109
|
+
const loader = new Loader({
|
|
110
|
+
transformer: createPostcssTransformer({
|
|
111
|
+
cwd,
|
|
112
|
+
postcssConfig: `${uuid}/postcss.config.js`,
|
|
113
|
+
}),
|
|
114
|
+
});
|
|
115
|
+
createFixtures({
|
|
116
|
+
[`/${uuid}/postcss.config.js`]: dedent `
|
|
117
|
+
module.exports = {
|
|
118
|
+
plugins: [
|
|
119
|
+
// When using postcss-import, the resolver of happy-css-modules is ignored.
|
|
120
|
+
// Therefore, we test here without postcss-import.
|
|
121
|
+
// require('${require.resolve('postcss-import')}'),
|
|
122
|
+
],
|
|
123
|
+
};
|
|
124
|
+
`,
|
|
125
|
+
'/test/1.css': dedent `
|
|
126
|
+
@import 'http://example.com/path/http.css';
|
|
127
|
+
@import 'https://example.com/path/https.css';
|
|
128
|
+
`,
|
|
129
|
+
});
|
|
130
|
+
const result = await loader.load(getFixturePath('/test/1.css'));
|
|
131
|
+
expect(result.dependencies).toStrictEqual([]);
|
|
132
|
+
});
|
|
133
|
+
test('returns false if postcssrc is not found', async () => {
|
|
134
|
+
const uuid = randomUUID();
|
|
135
|
+
const transformer = createPostcssTransformer({
|
|
136
|
+
cwd,
|
|
137
|
+
postcssConfig: `${uuid}/postcss.config.js`,
|
|
138
|
+
});
|
|
139
|
+
createFixtures({
|
|
140
|
+
'/test/1.css': dedent `
|
|
141
|
+
@import 'http://example.com/path/http.css';
|
|
142
|
+
@import 'https://example.com/path/https.css';
|
|
143
|
+
`,
|
|
144
|
+
});
|
|
145
|
+
expect(await transformer('', {
|
|
146
|
+
from: getFixturePath('/test/1.css'),
|
|
147
|
+
isIgnoredSpecifier: () => false,
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
149
|
+
resolver: jest.fn(),
|
|
150
|
+
})).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
test('searches config from cwd if postcssConfig option is missing', async () => {
|
|
153
|
+
const uuid = randomUUID();
|
|
154
|
+
const cwd = `/${uuid}`;
|
|
155
|
+
const loader = new Loader({
|
|
156
|
+
transformer: createPostcssTransformer({
|
|
157
|
+
cwd: getFixturePath(cwd),
|
|
158
|
+
}),
|
|
159
|
+
});
|
|
160
|
+
createFixtures({
|
|
161
|
+
[`/${uuid}/postcss.config.js`]: dedent `
|
|
162
|
+
module.exports = {
|
|
163
|
+
plugins: [
|
|
164
|
+
require('${require.resolve('postcss-simple-vars')}'),
|
|
165
|
+
],
|
|
166
|
+
};
|
|
167
|
+
`,
|
|
168
|
+
'/test/1.css': dedent `
|
|
169
|
+
$prefix: foo;
|
|
170
|
+
.$(prefix)_bar {}
|
|
171
|
+
`,
|
|
172
|
+
});
|
|
173
|
+
const result = await loader.load(getFixturePath('/test/1.css'));
|
|
174
|
+
expect(result.tokens.map((token) => token.name)).toStrictEqual(['foo_bar']);
|
|
175
|
+
});
|
|
176
|
+
//# sourceMappingURL=postcss-transformer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postcss-transformer.test.js","sourceRoot":"","sources":["../../src/transformer/postcss-transformer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,9 +3,25 @@
|
|
|
3
3
|
// Therefore, the workaround is now disabled. See
|
|
4
4
|
// https://github.com/mizdra/happy-css-modules/issues/65#issuecomment-1229471950 for more information.
|
|
5
5
|
import { handleImportError } from './index.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
// For some reason, `util.promisify` does not work. Therefore, use the original promisify.
|
|
7
|
+
function promisifySassRender(sass) {
|
|
8
|
+
return async (options) => {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
sass.render(options, (exception, result) => {
|
|
11
|
+
if (exception)
|
|
12
|
+
reject(exception);
|
|
13
|
+
else
|
|
14
|
+
resolve(result);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export const createScssTransformer = () => {
|
|
20
|
+
let sass;
|
|
21
|
+
return async (source, options) => {
|
|
22
|
+
sass ??= (await import('sass').catch(handleImportError('sass'))).default;
|
|
23
|
+
const render = promisifySassRender(sass);
|
|
24
|
+
const result = await render({
|
|
9
25
|
data: source,
|
|
10
26
|
file: options.from,
|
|
11
27
|
outFile: 'DUMMY',
|
|
@@ -16,21 +32,7 @@ async function renderSass(sass, source, options) {
|
|
|
16
32
|
.then((resolved) => done({ file: resolved }))
|
|
17
33
|
.catch((e) => done(e));
|
|
18
34
|
},
|
|
19
|
-
}, (exception, result) => {
|
|
20
|
-
if (exception) {
|
|
21
|
-
reject(exception);
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
resolve(result);
|
|
25
|
-
}
|
|
26
35
|
});
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
export const createScssTransformer = () => {
|
|
30
|
-
let sass;
|
|
31
|
-
return async (source, options) => {
|
|
32
|
-
sass ??= (await import('sass').catch(handleImportError('sass'))).default;
|
|
33
|
-
const result = await renderSass(sass, source, options);
|
|
34
36
|
return { css: result.css.toString(), map: result.map.toString(), dependencies: result.stats.includedFiles };
|
|
35
37
|
};
|
|
36
38
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scss-transformer.js","sourceRoot":"","sources":["../../src/transformer/scss-transformer.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,8FAA8F;AAC9F,iDAAiD;AACjD,sGAAsG;AAItG,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,
|
|
1
|
+
{"version":3,"file":"scss-transformer.js","sourceRoot":"","sources":["../../src/transformer/scss-transformer.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,8FAA8F;AAC9F,iDAAiD;AACjD,sGAAsG;AAItG,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,0FAA0F;AAC1F,SAAS,mBAAmB,CAAC,IAA2B;IACtD,OAAO,KAAK,EAAE,OAA+B,EAAE,EAAE;QAC/C,OAAO,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;gBACzC,IAAI,SAAS;oBAAE,MAAM,CAAC,SAAS,CAAC,CAAC;;oBAC5B,OAAO,CAAC,MAAO,CAAC,CAAC;YACxB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAsB,GAAG,EAAE;IAC3D,IAAI,IAA2B,CAAC;IAChC,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;QAC/B,IAAI,KAAK,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACzE,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC;YAC1B,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;gBAC5B,OAAO;qBACJ,QAAQ,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;qBAChC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;qBAC5C,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,CAAC;SACF,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAI,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;IAC/G,CAAC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -46,44 +46,44 @@ test('handles sass features', async () => {
|
|
|
46
46
|
{
|
|
47
47
|
name: "b_1",
|
|
48
48
|
originalLocations: [
|
|
49
|
-
{ filePath: "<fixtures>/test/2.scss", start: { line: 1, column: 1 }, end: { line: 1, column:
|
|
49
|
+
{ filePath: "<fixtures>/test/2.scss", start: { line: 1, column: 1 }, end: { line: 1, column: 4 } },
|
|
50
50
|
],
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
name: "c",
|
|
54
54
|
originalLocations: [
|
|
55
|
-
{ filePath: "<fixtures>/test/3.scss", start: { line: 1, column: 1 }, end: { line: 1, column:
|
|
55
|
+
{ filePath: "<fixtures>/test/3.scss", start: { line: 1, column: 1 }, end: { line: 1, column: 2 } },
|
|
56
56
|
],
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
name: "a_1",
|
|
60
60
|
originalLocations: [
|
|
61
|
-
{ filePath: "<fixtures>/test/1.scss", start: { line: 3, column: 1 }, end: { line: 3, column:
|
|
61
|
+
{ filePath: "<fixtures>/test/1.scss", start: { line: 3, column: 1 }, end: { line: 3, column: 4 } },
|
|
62
62
|
],
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
name: "a_2",
|
|
66
66
|
originalLocations: [
|
|
67
|
-
{ filePath: "<fixtures>/test/1.scss", start: { line: 4, column: 1 }, end: { line: 4, column:
|
|
68
|
-
{ filePath: "<fixtures>/test/1.scss", start: { line: 7, column: 3 }, end: { line: 7, column:
|
|
67
|
+
{ filePath: "<fixtures>/test/1.scss", start: { line: 4, column: 1 }, end: { line: 4, column: 4 } },
|
|
68
|
+
{ filePath: "<fixtures>/test/1.scss", start: { line: 7, column: 3 }, end: { line: 7, column: 6 } },
|
|
69
69
|
],
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
name: "a_2_1",
|
|
73
73
|
originalLocations: [
|
|
74
|
-
{ filePath: "<fixtures>/test/1.scss", start: { line: 7, column: 3 }, end: { line: 7, column:
|
|
74
|
+
{ filePath: "<fixtures>/test/1.scss", start: { line: 7, column: 3 }, end: { line: 7, column: 8 } },
|
|
75
75
|
],
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
name: "a_2_2",
|
|
79
79
|
originalLocations: [
|
|
80
|
-
{ filePath: "<fixtures>/test/1.scss", start: { line: 8, column: 3 }, end: { line: 8, column:
|
|
80
|
+
{ filePath: "<fixtures>/test/1.scss", start: { line: 8, column: 3 }, end: { line: 8, column: 8 } },
|
|
81
81
|
],
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
name: "d",
|
|
85
85
|
originalLocations: [
|
|
86
|
-
{ filePath: "<fixtures>/test/4.scss", start: { line: 1, column: 1 }, end: { line: 1, column:
|
|
86
|
+
{ filePath: "<fixtures>/test/4.scss", start: { line: 1, column: 1 }, end: { line: 1, column: 2 } },
|
|
87
87
|
],
|
|
88
88
|
},
|
|
89
89
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "happy-css-modules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Creates .d.ts files from CSS Modules .css files",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"glob": "^8.0.3",
|
|
36
36
|
"import-meta-resolve": "^2.1.0",
|
|
37
37
|
"minimatch": "^5.1.0",
|
|
38
|
-
"postcss": "^8.4.
|
|
38
|
+
"postcss": "^8.4.17",
|
|
39
|
+
"postcss-load-config": "^4.0.1",
|
|
39
40
|
"postcss-modules": "^4.3.1",
|
|
40
41
|
"postcss-selector-parser": "^6.0.10",
|
|
41
42
|
"postcss-value-parser": "^4.2.0",
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
"@types/line-column": "^1.0.0",
|
|
59
60
|
"@types/minimatch": "^5.1.2",
|
|
60
61
|
"@types/node": "^18.0.6",
|
|
61
|
-
"@types/yargs": "^17.0.
|
|
62
|
+
"@types/yargs": "^17.0.13",
|
|
62
63
|
"@typescript-eslint/eslint-plugin": "^5.31.0",
|
|
63
64
|
"@typescript-eslint/parser": "^5.31.0",
|
|
64
65
|
"@typescript/server-harness": "^0.2.0",
|
|
@@ -71,6 +72,8 @@
|
|
|
71
72
|
"less": "^4.1.3",
|
|
72
73
|
"line-column": "^1.0.2",
|
|
73
74
|
"npm-run-all": "^4.1.5",
|
|
75
|
+
"postcss-import": "^15.0.0",
|
|
76
|
+
"postcss-simple-vars": "^7.0.0",
|
|
74
77
|
"prettier": "~2.7.1",
|
|
75
78
|
"sass": "^1.54.3",
|
|
76
79
|
"tsc-watch": "^5.0.3",
|
package/src/cli.test.ts
CHANGED
|
@@ -45,6 +45,21 @@ describe('parseArgv', () => {
|
|
|
45
45
|
// Passing a number is treated as a string
|
|
46
46
|
expect(parseArgv([...baseArgs, '1.css', '--lessIncludePaths', '1']).lessIncludePaths).toStrictEqual(['1']);
|
|
47
47
|
});
|
|
48
|
+
test('--webpackResolveAlias', () => {
|
|
49
|
+
expect(
|
|
50
|
+
parseArgv([...baseArgs, '1.css', '--webpackResolveAlias', '{ "key1": "value1", "key2": "value2" }'])
|
|
51
|
+
.webpackResolveAlias,
|
|
52
|
+
).toStrictEqual({
|
|
53
|
+
key1: 'value1',
|
|
54
|
+
key2: 'value2',
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
test('--postcssConfig', () => {
|
|
58
|
+
expect(parseArgv([...baseArgs, '1.css', '--postcssConfig', '.']).postcssConfig).toBe('.');
|
|
59
|
+
expect(parseArgv([...baseArgs, '1.css', '--postcssConfig', 'postcss.config.js']).postcssConfig).toBe(
|
|
60
|
+
'postcss.config.js',
|
|
61
|
+
);
|
|
62
|
+
});
|
|
48
63
|
test('--silent', () => {
|
|
49
64
|
expect(parseArgv([...baseArgs, '1.css', '--silent']).silent).toBe(true);
|
|
50
65
|
expect(parseArgv([...baseArgs, '1.css', '--no-silent']).silent).toBe(false);
|
package/src/cli.ts
CHANGED
|
@@ -13,7 +13,7 @@ const pkgJson = JSON.parse(readFileSync(resolve(dirname(fileURLToPath(import.met
|
|
|
13
13
|
*/
|
|
14
14
|
export function parseArgv(argv: string[]): RunnerOptions {
|
|
15
15
|
const parsedArgv = yargs(hideBin(argv))
|
|
16
|
-
.wrap(Math.min(
|
|
16
|
+
.wrap(Math.min(140, process.stdout.columns))
|
|
17
17
|
.scriptName('hcm')
|
|
18
18
|
.usage('Create .d.ts and .d.ts.map from CSS modules *.css files.\n\n$0 [options] <glob>')
|
|
19
19
|
.example("$0 'src/**/*.module.css'", 'Generate .d.ts and .d.ts.map.')
|
|
@@ -22,6 +22,7 @@ export function parseArgv(argv: string[]): RunnerOptions {
|
|
|
22
22
|
.example("$0 'src/**/*.module.css' --declarationMap=false", 'Generate .d.ts only.')
|
|
23
23
|
.example("$0 'src/**/*.module.css' --sassLoadPaths=src/style", "Run with sass's `--load-path`.")
|
|
24
24
|
.example("$0 'src/**/*.module.css' --lessIncludePaths=src/style", "Run with less's `--include-path`.")
|
|
25
|
+
.example('$0 \'src/**/*.module.css\' --webpackResolveAlias=\'{"@": "src"}\'', "Run with webpack's `resolve.alias`.")
|
|
25
26
|
.detectLocale(false)
|
|
26
27
|
.option('outDir', {
|
|
27
28
|
type: 'string',
|
|
@@ -52,6 +53,15 @@ export function parseArgv(argv: string[]): RunnerOptions {
|
|
|
52
53
|
nargs: 1,
|
|
53
54
|
describe: "The option compatible with less's `--include-path`.",
|
|
54
55
|
})
|
|
56
|
+
.option('webpackResolveAlias', {
|
|
57
|
+
string: true,
|
|
58
|
+
describe: "The option compatible with webpack's `resolve.alias`.",
|
|
59
|
+
})
|
|
60
|
+
// TODO: Support --noPostcssConfig option.
|
|
61
|
+
.option('postcssConfig', {
|
|
62
|
+
string: true,
|
|
63
|
+
describe: "The option compatible with postcss's `--config`.",
|
|
64
|
+
})
|
|
55
65
|
.option('silent', {
|
|
56
66
|
type: 'boolean',
|
|
57
67
|
default: false,
|
|
@@ -64,6 +74,20 @@ export function parseArgv(argv: string[]): RunnerOptions {
|
|
|
64
74
|
const patterns = argv._;
|
|
65
75
|
// TODO: support multiple patterns
|
|
66
76
|
if (patterns.length !== 1) throw new Error('Only one pattern is allowed.');
|
|
77
|
+
if (argv.webpackResolveAlias) {
|
|
78
|
+
let parsedWebpackResolveAlias: unknown;
|
|
79
|
+
try {
|
|
80
|
+
parsedWebpackResolveAlias = JSON.parse(argv.webpackResolveAlias);
|
|
81
|
+
} catch (e) {
|
|
82
|
+
throw new Error('--webpackResolveAlias must be a valid JSON string.');
|
|
83
|
+
}
|
|
84
|
+
if (typeof parsedWebpackResolveAlias !== 'object' || parsedWebpackResolveAlias === null)
|
|
85
|
+
throw new Error('--webpackResolveAlias must be an object');
|
|
86
|
+
if (!Object.keys(parsedWebpackResolveAlias).every((key) => typeof key === 'string'))
|
|
87
|
+
throw new Error('--webpackResolveAlias must be an object of string keys');
|
|
88
|
+
if (!Object.values(parsedWebpackResolveAlias).every((value) => typeof value === 'string'))
|
|
89
|
+
throw new Error('--webpackResolveAlias must be an object of string values');
|
|
90
|
+
}
|
|
67
91
|
return true;
|
|
68
92
|
})
|
|
69
93
|
.parseSync();
|
|
@@ -76,6 +100,8 @@ export function parseArgv(argv: string[]): RunnerOptions {
|
|
|
76
100
|
declarationMap: parsedArgv.declarationMap,
|
|
77
101
|
sassLoadPaths: parsedArgv.sassLoadPaths?.map((item) => item.toString()),
|
|
78
102
|
lessIncludePaths: parsedArgv.lessIncludePaths?.map((item) => item.toString()),
|
|
103
|
+
webpackResolveAlias: parsedArgv.webpackResolveAlias ? JSON.parse(parsedArgv.webpackResolveAlias) : undefined,
|
|
104
|
+
postcssConfig: parsedArgv.postcssConfig,
|
|
79
105
|
silent: parsedArgv.silent,
|
|
80
106
|
};
|
|
81
107
|
}
|
package/src/emitter/dts.ts
CHANGED
|
@@ -65,7 +65,16 @@ function generateTokenDeclarations(
|
|
|
65
65
|
// This is due to the sourcemap specification. Therefore, we output multiple type definitions
|
|
66
66
|
// with the same name and assign a separate original position to each.
|
|
67
67
|
|
|
68
|
-
for (
|
|
68
|
+
for (let originalLocation of token.originalLocations) {
|
|
69
|
+
if (originalLocation.filePath === undefined) {
|
|
70
|
+
// If the original location is not specified, fallback to the source file.
|
|
71
|
+
originalLocation = {
|
|
72
|
+
filePath: filePath,
|
|
73
|
+
start: { line: 1, column: 1 },
|
|
74
|
+
end: { line: 1, column: 1 },
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
69
78
|
result.push(
|
|
70
79
|
originalLocation.filePath === filePath || isExternalFile(originalLocation.filePath)
|
|
71
80
|
? new SourceNode(null, null, null, [
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
export { parseArgv } from './cli.js';
|
|
2
|
-
export { run } from './runner.js';
|
|
3
|
-
export {
|
|
2
|
+
export { run, type LocalsConvention } from './runner.js';
|
|
3
|
+
export {
|
|
4
|
+
type Transformer,
|
|
5
|
+
type TransformerOptions,
|
|
6
|
+
type TransformResult,
|
|
7
|
+
createDefaultTransformer,
|
|
8
|
+
} from './transformer/index.js';
|
|
9
|
+
export { type Resolver, type ResolverOptions, createDefaultResolver } from './resolver/index.js';
|
package/src/loader/index.test.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import fs, { readFile, writeFile } from 'fs/promises';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
2
3
|
import { jest } from '@jest/globals';
|
|
3
4
|
import dedent from 'dedent';
|
|
5
|
+
import { createDefaultTransformer } from '../index.js';
|
|
4
6
|
import { createFixtures, FIXTURE_DIR_PATH, getFixturePath } from '../test/util.js';
|
|
5
7
|
import { sleepSync } from '../util.js';
|
|
6
8
|
|
|
@@ -311,7 +313,83 @@ test('throws error the composition of non-existent file', async () => {
|
|
|
311
313
|
}).rejects.toThrowError(`Could not resolve './2.css' in '<fixtures>/test/1.css'`);
|
|
312
314
|
});
|
|
313
315
|
|
|
314
|
-
|
|
316
|
+
describe('supports sourcemap', () => {
|
|
317
|
+
test('restores original locations from sourcemap', async () => {
|
|
318
|
+
const transformer = createDefaultTransformer();
|
|
319
|
+
const loader = new Loader({ transformer });
|
|
320
|
+
createFixtures({
|
|
321
|
+
'/test/1.scss': dedent`
|
|
322
|
+
.nesting {
|
|
323
|
+
dummy: '';
|
|
324
|
+
.nesting_child {
|
|
325
|
+
dummy: '';
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
`,
|
|
329
|
+
});
|
|
330
|
+
const result = await loader.load(getFixturePath('/test/1.scss'));
|
|
331
|
+
expect(result).toMatchInlineSnapshot(`
|
|
332
|
+
{
|
|
333
|
+
dependencies: [],
|
|
334
|
+
tokens: [
|
|
335
|
+
{
|
|
336
|
+
name: "nesting",
|
|
337
|
+
originalLocations: [
|
|
338
|
+
{ filePath: "<fixtures>/test/1.scss", start: { line: 1, column: 1 }, end: { line: 1, column: 8 } },
|
|
339
|
+
{ filePath: "<fixtures>/test/1.scss", start: { line: 3, column: 3 }, end: { line: 3, column: 10 } },
|
|
340
|
+
],
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: "nesting_child",
|
|
344
|
+
originalLocations: [
|
|
345
|
+
{ filePath: "<fixtures>/test/1.scss", start: { line: 3, column: 3 }, end: { line: 3, column: 16 } },
|
|
346
|
+
],
|
|
347
|
+
},
|
|
348
|
+
],
|
|
349
|
+
}
|
|
350
|
+
`);
|
|
351
|
+
});
|
|
352
|
+
test('treats originalLocation as empty if sourcemap is broken', async () => {
|
|
353
|
+
const uuid = randomUUID();
|
|
354
|
+
createFixtures({
|
|
355
|
+
[`/${uuid}/postcss.config.js`]: dedent`
|
|
356
|
+
module.exports = {
|
|
357
|
+
plugins: [],
|
|
358
|
+
};
|
|
359
|
+
`,
|
|
360
|
+
'/test/1.css': dedent`
|
|
361
|
+
.selector_list_a_1, .selector_list_a_2 {}
|
|
362
|
+
/* In postcss, including newlines in the selector list breaks the sourcemap. */
|
|
363
|
+
.selector_list_b_1,
|
|
364
|
+
.selector_list_b_2 {}
|
|
365
|
+
`,
|
|
366
|
+
});
|
|
367
|
+
const transformer = createDefaultTransformer({ postcssConfig: getFixturePath(`/${uuid}/postcss.config.js`) });
|
|
368
|
+
const loader = new Loader({ transformer });
|
|
369
|
+
const result = await loader.load(getFixturePath('/test/1.css'));
|
|
370
|
+
expect(result).toMatchInlineSnapshot(`
|
|
371
|
+
{
|
|
372
|
+
dependencies: [],
|
|
373
|
+
tokens: [
|
|
374
|
+
{
|
|
375
|
+
name: "selector_list_a_1",
|
|
376
|
+
originalLocations: [
|
|
377
|
+
{ filePath: "<fixtures>/test/1.css", start: { line: 1, column: 1 }, end: { line: 1, column: 18 } },
|
|
378
|
+
],
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
name: "selector_list_a_2",
|
|
382
|
+
originalLocations: [
|
|
383
|
+
{ filePath: "<fixtures>/test/1.css", start: { line: 1, column: 1 }, end: { line: 1, column: 18 } },
|
|
384
|
+
],
|
|
385
|
+
},
|
|
386
|
+
{ name: "selector_list_b_1", originalLocations: [{}] },
|
|
387
|
+
{ name: "selector_list_b_2", originalLocations: [{}] },
|
|
388
|
+
],
|
|
389
|
+
}
|
|
390
|
+
`);
|
|
391
|
+
});
|
|
392
|
+
});
|
|
315
393
|
|
|
316
394
|
test('ignores http(s) protocol file', async () => {
|
|
317
395
|
createFixtures({
|