happy-css-modules 0.3.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 -48
- package/dist/cli.js +42 -4
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.js +21 -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/integration-test/go-to-definition.test.js +9 -8
- package/dist/integration-test/go-to-definition.test.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/index.d.ts +3 -1
- package/dist/resolver/index.js +17 -14
- package/dist/resolver/index.js.map +1 -1
- package/dist/resolver/webpack-resolver.d.ts +23 -1
- package/dist/resolver/webpack-resolver.js +82 -59
- package/dist/resolver/webpack-resolver.js.map +1 -1
- package/dist/resolver/webpack-resolver.test.js +70 -7
- package/dist/resolver/webpack-resolver.test.js.map +1 -1
- package/dist/runner.d.ts +25 -0
- package/dist/runner.js +30 -12
- package/dist/runner.js.map +1 -1
- package/dist/runner.test.js +62 -11
- package/dist/runner.test.js.map +1 -1
- package/dist/test/tsserver.d.ts +10 -6
- package/dist/test/tsserver.js +94 -85
- package/dist/test/tsserver.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 +15 -9
- 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.js +1 -2
- package/dist/transformer/less-transformer.js.map +1 -1
- 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 -64
- 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 +29 -0
- package/src/cli.ts +41 -4
- package/src/emitter/dts.ts +10 -1
- package/src/index.ts +8 -2
- package/src/integration-test/go-to-definition.test.ts +10 -8
- package/src/loader/index.test.ts +79 -1
- package/src/loader/postcss.ts +42 -40
- package/src/resolver/index.ts +21 -12
- package/src/resolver/webpack-resolver.test.ts +100 -8
- package/src/resolver/webpack-resolver.ts +111 -57
- package/src/runner.test.ts +67 -11
- package/src/runner.ts +56 -13
- package/src/test/tsserver.ts +106 -129
- package/src/test/util.ts +15 -9
- package/src/transformer/index.test.ts +71 -0
- package/src/transformer/index.ts +18 -8
- package/src/transformer/less-transformer.test.ts +6 -6
- package/src/transformer/less-transformer.ts +1 -2
- 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 -78
|
@@ -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,48 +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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// const createImporterForJest: (from: string) => Importer<'async'> = (from) => ({
|
|
26
|
-
// canonicalize(url) {
|
|
27
|
-
// // NOTE: The format of `url` changes depending on the import source.
|
|
28
|
-
// //
|
|
29
|
-
// // - When `from === '/test/1.scss'` and `@import './2.scss'` in `/test/1.scss` is resolved, `url === '2.scss'`.
|
|
30
|
-
// // - When `from === '/test/1.scss'` and `@import './3.scss'` in `/test/2.scss` is resolved, `url === 'file:///test/3.scss'`.
|
|
31
|
-
// //
|
|
32
|
-
// // That is, the paths of @import statements written to the `from` file is passed through unresolved,
|
|
33
|
-
// // but paths written to other files is passed through resolved to absolute paths.
|
|
34
|
-
// return new URL(url, pathToFileURL(from));
|
|
35
|
-
// },
|
|
36
|
-
// async load(canonicalUrl) {
|
|
37
|
-
// return {
|
|
38
|
-
// contents: await readFile(fileURLToPath(canonicalUrl.href), 'utf8'),
|
|
39
|
-
// syntax: 'scss',
|
|
40
|
-
// sourceMapUrl: canonicalUrl,
|
|
41
|
-
// };
|
|
42
|
-
// },
|
|
43
|
-
// });
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
45
|
-
async function renderSass(sass, source, options) {
|
|
46
|
-
return new Promise((resolve, reject) => {
|
|
47
|
-
sass.render({
|
|
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({
|
|
48
25
|
data: source,
|
|
49
26
|
file: options.from,
|
|
50
27
|
outFile: 'DUMMY',
|
|
@@ -55,30 +32,8 @@ async function renderSass(sass, source, options) {
|
|
|
55
32
|
.then((resolved) => done({ file: resolved }))
|
|
56
33
|
.catch((e) => done(e));
|
|
57
34
|
},
|
|
58
|
-
}, (exception, result) => {
|
|
59
|
-
if (exception) {
|
|
60
|
-
reject(exception);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
resolve(result);
|
|
64
|
-
}
|
|
65
35
|
});
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
export const createScssTransformer = () => {
|
|
69
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
70
|
-
let sass;
|
|
71
|
-
return async (source, options) => {
|
|
72
|
-
sass ??= (await import('sass').catch(handleImportError('sass'))).default;
|
|
73
|
-
const result = await renderSass(sass, source, options);
|
|
74
36
|
return { css: result.css.toString(), map: result.map.toString(), dependencies: result.stats.includedFiles };
|
|
75
|
-
// if (IS_JEST_ENVIRONMENT) verifyJestEnvironment();
|
|
76
|
-
// const result = await sass.default.compileStringAsync(source, {
|
|
77
|
-
// url: pathToFileURL(from),
|
|
78
|
-
// sourceMap: true,
|
|
79
|
-
// importers: IS_JEST_ENVIRONMENT ? [createImporterForJest(from)] : [],
|
|
80
|
-
// });
|
|
81
|
-
// return { css: result.css, map: result.sourceMap!, dependencies: result.loadedUrls };
|
|
82
37
|
};
|
|
83
38
|
};
|
|
84
39
|
//# sourceMappingURL=scss-transformer.js.map
|
|
@@ -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
|
@@ -31,6 +31,35 @@ describe('parseArgv', () => {
|
|
|
31
31
|
expect(parseArgv([...baseArgs, '1.css', '--declarationMap']).declarationMap).toBe(true);
|
|
32
32
|
expect(parseArgv([...baseArgs, '1.css', '--no-declarationMap']).declarationMap).toBe(false);
|
|
33
33
|
});
|
|
34
|
+
test('--sassLoadPaths', () => {
|
|
35
|
+
expect(
|
|
36
|
+
parseArgv([...baseArgs, '1.css', '--sassLoadPaths', 'dir1', '--sassLoadPaths', 'dir2']).sassLoadPaths,
|
|
37
|
+
).toStrictEqual(['dir1', 'dir2']);
|
|
38
|
+
// Passing a number is treated as a string
|
|
39
|
+
expect(parseArgv([...baseArgs, '1.css', '--sassLoadPaths', '1']).sassLoadPaths).toStrictEqual(['1']);
|
|
40
|
+
});
|
|
41
|
+
test('--lessIncludePaths', () => {
|
|
42
|
+
expect(
|
|
43
|
+
parseArgv([...baseArgs, '1.css', '--lessIncludePaths', 'dir1', '--lessIncludePaths', 'dir2']).lessIncludePaths,
|
|
44
|
+
).toStrictEqual(['dir1', 'dir2']);
|
|
45
|
+
// Passing a number is treated as a string
|
|
46
|
+
expect(parseArgv([...baseArgs, '1.css', '--lessIncludePaths', '1']).lessIncludePaths).toStrictEqual(['1']);
|
|
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
|
+
});
|
|
34
63
|
test('--silent', () => {
|
|
35
64
|
expect(parseArgv([...baseArgs, '1.css', '--silent']).silent).toBe(true);
|
|
36
65
|
expect(parseArgv([...baseArgs, '1.css', '--no-silent']).silent).toBe(false);
|
package/src/cli.ts
CHANGED
|
@@ -13,16 +13,16 @@ 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
|
-
.
|
|
17
|
-
// workaround for https://github.com/yargs/yargs/issues/1318
|
|
18
|
-
'duplicate-arguments-array': false,
|
|
19
|
-
})
|
|
16
|
+
.wrap(Math.min(140, process.stdout.columns))
|
|
20
17
|
.scriptName('hcm')
|
|
21
18
|
.usage('Create .d.ts and .d.ts.map from CSS modules *.css files.\n\n$0 [options] <glob>')
|
|
22
19
|
.example("$0 'src/**/*.module.css'", 'Generate .d.ts and .d.ts.map.')
|
|
23
20
|
.example("$0 'src/**/*.module.{css,scss,less}'", 'Also generate files for sass and less.')
|
|
24
21
|
.example("$0 'src/**/*.module.css' --watch", 'Watch for changes and generate .d.ts and .d.ts.map.')
|
|
25
22
|
.example("$0 'src/**/*.module.css' --declarationMap=false", 'Generate .d.ts only.')
|
|
23
|
+
.example("$0 'src/**/*.module.css' --sassLoadPaths=src/style", "Run with sass's `--load-path`.")
|
|
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`.")
|
|
26
26
|
.detectLocale(false)
|
|
27
27
|
.option('outDir', {
|
|
28
28
|
type: 'string',
|
|
@@ -43,6 +43,25 @@ export function parseArgv(argv: string[]): RunnerOptions {
|
|
|
43
43
|
default: true,
|
|
44
44
|
describe: 'Create sourcemaps for d.ts files',
|
|
45
45
|
})
|
|
46
|
+
.option('sassLoadPaths', {
|
|
47
|
+
array: true,
|
|
48
|
+
nargs: 1,
|
|
49
|
+
describe: "The option compatible with sass's `--load-path`.",
|
|
50
|
+
})
|
|
51
|
+
.option('lessIncludePaths', {
|
|
52
|
+
array: true,
|
|
53
|
+
nargs: 1,
|
|
54
|
+
describe: "The option compatible with less's `--include-path`.",
|
|
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
|
+
})
|
|
46
65
|
.option('silent', {
|
|
47
66
|
type: 'boolean',
|
|
48
67
|
default: false,
|
|
@@ -55,6 +74,20 @@ export function parseArgv(argv: string[]): RunnerOptions {
|
|
|
55
74
|
const patterns = argv._;
|
|
56
75
|
// TODO: support multiple patterns
|
|
57
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
|
+
}
|
|
58
91
|
return true;
|
|
59
92
|
})
|
|
60
93
|
.parseSync();
|
|
@@ -65,6 +98,10 @@ export function parseArgv(argv: string[]): RunnerOptions {
|
|
|
65
98
|
watch: parsedArgv.watch,
|
|
66
99
|
localsConvention: parsedArgv.localsConvention,
|
|
67
100
|
declarationMap: parsedArgv.declarationMap,
|
|
101
|
+
sassLoadPaths: parsedArgv.sassLoadPaths?.map((item) => item.toString()),
|
|
102
|
+
lessIncludePaths: parsedArgv.lessIncludePaths?.map((item) => item.toString()),
|
|
103
|
+
webpackResolveAlias: parsedArgv.webpackResolveAlias ? JSON.parse(parsedArgv.webpackResolveAlias) : undefined,
|
|
104
|
+
postcssConfig: parsedArgv.postcssConfig,
|
|
68
105
|
silent: parsedArgv.silent,
|
|
69
106
|
};
|
|
70
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';
|