Skip to content

Commit bb6decb

Browse files
wChenonlysxzz
andauthored
fix(css): use aliased exports for CSS module keys (#840)
Co-authored-by: Kevin Deng <sxzz@sxzz.moe>
1 parent af40e43 commit bb6decb

File tree

5 files changed

+87
-4
lines changed

5 files changed

+87
-4
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`modulesToEsm > exports arbitrary module keys via aliased bindings 1`] = `
4+
"const _key0 = "mod_title";
5+
export { _key0 as "title" };
6+
const _key1 = "mod_await";
7+
export { _key1 as "await" };
8+
const _key2 = "mod_foo_bar";
9+
export { _key2 as "foo-bar" };
10+
export default {"default":"mod_default","title":"mod_title","await":"mod_await","foo-bar":"mod_foo_bar"};"
11+
`;

packages/css/src/modules.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { describe, expect, test } from 'vitest'
2+
import { modulesToEsm } from './modules.ts'
3+
4+
describe('modulesToEsm', () => {
5+
test('exports arbitrary module keys via aliased bindings', () => {
6+
const code = modulesToEsm({
7+
default: 'mod_default',
8+
title: 'mod_title',
9+
await: 'mod_await',
10+
'foo-bar': 'mod_foo_bar',
11+
})
12+
13+
expect(code).matchSnapshot()
14+
expect(code).toContain('const _key0 = "mod_title";')
15+
expect(code).toContain('export { _key0 as "title" };')
16+
expect(code).not.toContain('const _default = "mod_default";')
17+
expect(code).not.toContain('export { _default as "default" };')
18+
expect(code).toContain('const _key1 = "mod_await";')
19+
expect(code).toContain('export { _key1 as "await" };')
20+
expect(code).toContain('const _key2 = "mod_foo_bar";')
21+
expect(code).toContain('export { _key2 as "foo-bar" };')
22+
expect(code).toContain(
23+
'export default {"default":"mod_default","title":"mod_title","await":"mod_await","foo-bar":"mod_foo_bar"};',
24+
)
25+
})
26+
})

packages/css/src/modules.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import type { CSSModuleExports } from 'lightningcss'
22

3-
const VALID_ID_RE = /^[$_a-z][$\w]*$/i
4-
53
export function modulesToEsm(modules: Record<string, string>): string {
64
const lines: string[] = []
5+
let index = 0
76
for (const [key, value] of Object.entries(modules)) {
8-
if (VALID_ID_RE.test(key)) {
9-
lines.push(`export const ${key} = ${JSON.stringify(value)};`)
7+
if (key === 'default') {
8+
continue
109
}
10+
const binding = `_key${index++}`
11+
lines.push(
12+
`const ${binding} = ${JSON.stringify(value)};`,
13+
`export { ${binding} as ${JSON.stringify(key)} };`,
14+
)
1115
}
1216
lines.push(`export default ${JSON.stringify(modules)};`)
1317
return lines.join('\n')
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
## index.mjs
2+
3+
```mjs
4+
//#endregion
5+
//#region index.ts
6+
console.log({ "default": "design-system-default" }.default);
7+
//#endregion
8+
export {};
9+
10+
```
11+
12+
## style.css
13+
14+
```css
15+
.design-system-default {
16+
color: red;
17+
}
18+
19+
```

tests/css.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,5 +1647,28 @@ describe('css', () => {
16471647
const js = fileMap['index.mjs']
16481648
expect(js).toContain('mod_title')
16491649
})
1650+
1651+
test('css module supports class named default', async (context) => {
1652+
const { fileMap } = await testBuild({
1653+
context,
1654+
files: {
1655+
'index.ts': `import styles from './app.module.css'\nconsole.log(styles.default)`,
1656+
'app.module.css': `.default { color: red }`,
1657+
},
1658+
options: {
1659+
css: {
1660+
modules: { generateScopedName: 'design-system-[local]' },
1661+
},
1662+
},
1663+
})
1664+
1665+
const js = fileMap['index.mjs']
1666+
const css = fileMap['style.css']
1667+
1668+
expect(js).not.toContain('export const default')
1669+
expect(js).toMatch(/"default"\s*:\s*"design-system-default"/)
1670+
expect(js).toContain('.default')
1671+
expect(css).toContain('.design-system-default')
1672+
})
16501673
})
16511674
})

0 commit comments

Comments
 (0)