Skip to content

Commit eec08e4

Browse files
committed
feat: support multiple css-modules imports
1 parent 6986365 commit eec08e4

File tree

4 files changed

+70
-6
lines changed

4 files changed

+70
-6
lines changed

src/cssModules.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
export function genInitCSSModulesCode() {
2+
return `
3+
const cssModules = {}
4+
const cssModulesStore = {}
5+
const getCssModules = (name) => {
6+
return Object.values(cssModulesStore[name]).reduce((acc, style) => Object.assign(acc, style), {})
7+
}
8+
`
9+
}
10+
111
export function genCSSModulesCode(
212
id: string,
313
index: number,
@@ -6,17 +16,24 @@ export function genCSSModulesCode(
616
needsHotReload: boolean
717
): string {
818
const styleVar = `style${index}`
9-
let code = `\nimport ${styleVar} from ${request}`
10-
1119
// inject variable
1220
const name = typeof moduleName === 'string' ? moduleName : '$style'
13-
code += `\ncssModules["${name}"] = ${styleVar}`
21+
let code = `
22+
import ${styleVar} from ${request}
23+
24+
if (!cssModulesStore["${name}"]) {
25+
cssModulesStore["${name}"] = {}
26+
}
27+
cssModulesStore["${name}"]["${styleVar}"] = ${styleVar}
28+
cssModules["${name}"] = getCssModules("${name}")
29+
`
1430

1531
if (needsHotReload) {
1632
code += `
1733
if (module.hot) {
1834
module.hot.accept(${request}, () => {
19-
cssModules["${name}"] = ${styleVar}
35+
cssModulesStore["${name}"]["${styleVar}"] = ${styleVar}
36+
cssModules["${name}"] = getCssModules("${name}")
2037
__VUE_HMR_RUNTIME__.rerender("${id}")
2138
})
2239
}`

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import type {
1313
} from 'vue/compiler-sfc'
1414
import { selectBlock } from './select'
1515
import { genHotReloadCode } from './hotReload'
16-
import { genCSSModulesCode } from './cssModules'
16+
import { genCSSModulesCode, genInitCSSModulesCode } from './cssModules'
1717
import { formatError } from './formatError'
1818

1919
import VueLoaderPlugin from './plugin'
@@ -273,7 +273,7 @@ export default function loader(
273273
)
274274
}
275275
if (!hasCSSModules) {
276-
stylesCode += `\nconst cssModules = {}`
276+
stylesCode += genInitCSSModulesCode()
277277
propsToAttach.push([`__cssModules`, `cssModules`])
278278
hasCSSModules = true
279279
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<style module>
2+
.red {
3+
color: red;
4+
}
5+
</style>
6+
<style module>
7+
.green {
8+
color: green;
9+
}
10+
</style>
11+
12+
<script>
13+
export default {}
14+
</script>

test/style.spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,39 @@ test('CSS Modules Extend', async () => {
204204
expect(style).toContain(`.${escapedClassName} {\n color: #FF0000;\n}`)
205205
})
206206

207+
test('Multiple CSS Modules', async () => {
208+
const baseLoaders = [
209+
'style-loader',
210+
{
211+
loader: 'css-loader',
212+
options: {
213+
modules: true,
214+
},
215+
},
216+
]
217+
218+
const { instance } = await mockBundleAndRun({
219+
entry: 'css-modules-multiple.vue',
220+
modify: (config: any) => {
221+
config!.module!.rules = [
222+
{
223+
test: /\.vue$/,
224+
use: [DEFAULT_VUE_USE],
225+
},
226+
{
227+
test: /\.css$/,
228+
use: baseLoaders,
229+
},
230+
]
231+
},
232+
})
233+
234+
console.log(instance.$style)
235+
236+
expect(instance.$style.red).toBeDefined()
237+
expect(instance.$style.green).toBeDefined()
238+
})
239+
207240
test('v-bind() in CSS', async () => {
208241
const { window, instance } = await mockBundleAndRun({
209242
entry: 'style-v-bind.vue',

0 commit comments

Comments
 (0)