Skip to content

Commit 10378e1

Browse files
authoredMay 17, 2024··
feat(bundler-webpack): enable css-modules for .module.css files (close #1557) (#1560)
BREAKING CHANGE: For webpack bundler, css-modules will be enabled for `*.module.[ext]` files. The previous `*.[ext]?module` usage is no longer supported.
1 parent 8b1f0fd commit 10378e1

File tree

7 files changed

+55
-64
lines changed

7 files changed

+55
-64
lines changed
 

‎e2e/docs/.vuepress/theme/client/config.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { defineClientConfig } from 'vuepress/client'
22
import RootComponentFromTheme from './components/RootComponentFromTheme.vue'
3+
import CssModulesLayout from './layouts/CssModulesLayout.vue'
34
import CustomLayout from './layouts/CustomLayout.vue'
45
import Layout from './layouts/Layout.vue'
56
import NotFound from './layouts/NotFound.vue'
@@ -16,6 +17,7 @@ export default defineClientConfig({
1617
},
1718

1819
layouts: {
20+
CssModulesLayout,
1921
CustomLayout,
2022
Layout,
2123
NotFound,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script setup lang="ts">
2+
import styles from '../styles/styles.module.css'
3+
import variables from '../styles/variables.module.scss'
4+
</script>
5+
6+
<template>
7+
<div class="e2e-theme-css-modules-layout">
8+
<main class="e2e-theme-css-modules-layout-content">
9+
<div id="e2e-theme-css-modules-scss">{{ variables.fooScss }}</div>
10+
<div id="e2e-theme-css-modules-css" :class="styles.greenText">
11+
CSS modules green text
12+
</div>
13+
<Content />
14+
</main>
15+
</div>
16+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.greenText {
2+
color: rgb(0, 129, 0);
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:export {
2+
fooScss: 234px;
3+
}

‎e2e/docs/styles/css-modules.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
layout: CssModulesLayout
3+
---

‎e2e/tests/styles/css-modules.spec.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { expect, test } from '@playwright/test'
2+
3+
test('Should load CSS modules correctly', async ({ page }) => {
4+
await page.goto('styles/css-modules.html')
5+
await expect(page.locator('#e2e-theme-css-modules-scss')).toHaveText('234px')
6+
await expect(page.locator('#e2e-theme-css-modules-css')).toHaveCSS(
7+
'color',
8+
'rgb(0, 129, 0)',
9+
)
10+
})

‎packages/bundler-webpack/src/config/handleModuleStyles.ts

+18-64
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ import type {
1313

1414
const require = createRequire(import.meta.url)
1515

16-
type StyleRule = Config.Rule<Config.Rule<Config.Module>>
17-
1816
/**
1917
* Set webpack module to handle style files
2018
*/
@@ -29,36 +27,19 @@ export const handleModuleStyles = ({
2927
isBuild: boolean
3028
isServer: boolean
3129
}): void => {
32-
const createStyleRules = ({
30+
const handleStyle = <T extends LoaderOptions = LoaderOptions>({
3331
lang,
3432
test,
33+
loaderName,
34+
loaderOptions,
3535
}: {
3636
lang: string
3737
test: RegExp
38-
}): {
39-
modulesRule: StyleRule
40-
normalRule: StyleRule
41-
} => {
42-
const baseRule = config.module.rule(lang).test(test)
43-
const modulesRule = baseRule.oneOf('modules').resourceQuery(/module/)
44-
const normalRule = baseRule.oneOf('normal')
45-
return {
46-
modulesRule,
47-
normalRule,
48-
}
49-
}
50-
51-
const applyStyleHandlers = ({
52-
rule,
53-
cssModules,
54-
loaderName,
55-
loaderOptions = {},
56-
}: {
57-
rule: StyleRule
58-
cssModules: boolean
5938
loaderName?: string
60-
loaderOptions?: LoaderOptions
39+
loaderOptions?: T
6140
}): void => {
41+
const rule = config.module.rule(lang).test(test)
42+
6243
if (!isServer) {
6344
if (isBuild) {
6445
rule.use('extract-css-loader').loader(MiniCssExtractPlugin.loader)
@@ -72,13 +53,14 @@ export const handleModuleStyles = ({
7253
.use('css-loader')
7354
.loader(require.resolve('css-loader'))
7455
.options({
75-
modules: cssModules
76-
? {
77-
localIdentName: `[local]_[contenthash:base64:8]`,
78-
exportOnlyLocals: isServer,
79-
}
80-
: false,
81-
importLoaders: 1,
56+
modules: {
57+
auto: true,
58+
exportLocalsConvention: 'as-is',
59+
exportOnlyLocals: isServer,
60+
localIdentName: `[local]_[contenthash:base64:8]`,
61+
namedExport: false,
62+
},
63+
importLoaders: loaderName ? 2 : 1,
8264
})
8365

8466
// use postcss-loader
@@ -94,41 +76,13 @@ export const handleModuleStyles = ({
9476

9577
// use extra loader
9678
if (loaderName) {
97-
rule.use(loaderName).loader(loaderName).options(loaderOptions)
79+
rule
80+
.use(loaderName)
81+
.loader(loaderName)
82+
.options(loaderOptions ?? {})
9883
}
9984
}
10085

101-
const handleStyle = <T extends LoaderOptions = LoaderOptions>({
102-
lang,
103-
test,
104-
loaderName,
105-
loaderOptions,
106-
}: {
107-
lang: string
108-
test: RegExp
109-
loaderName?: string
110-
loaderOptions?: T
111-
}): void => {
112-
const { modulesRule, normalRule } = createStyleRules({
113-
lang,
114-
test,
115-
})
116-
117-
applyStyleHandlers({
118-
rule: modulesRule,
119-
cssModules: true,
120-
loaderName,
121-
loaderOptions,
122-
})
123-
124-
applyStyleHandlers({
125-
rule: normalRule,
126-
cssModules: false,
127-
loaderName,
128-
loaderOptions,
129-
})
130-
}
131-
13286
handleStyle({
13387
lang: 'css',
13488
test: /\.css$/,

0 commit comments

Comments
 (0)
Please sign in to comment.