Skip to content

Commit

Permalink
feat(bundler-webpack): enable css-modules for .module.css files (close
Browse files Browse the repository at this point in the history
…#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.
  • Loading branch information
meteorlxy authored May 17, 2024
1 parent 8b1f0fd commit 10378e1
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 64 deletions.
2 changes: 2 additions & 0 deletions e2e/docs/.vuepress/theme/client/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { defineClientConfig } from 'vuepress/client'
import RootComponentFromTheme from './components/RootComponentFromTheme.vue'
import CssModulesLayout from './layouts/CssModulesLayout.vue'
import CustomLayout from './layouts/CustomLayout.vue'
import Layout from './layouts/Layout.vue'
import NotFound from './layouts/NotFound.vue'
Expand All @@ -16,6 +17,7 @@ export default defineClientConfig({
},

layouts: {
CssModulesLayout,
CustomLayout,
Layout,
NotFound,
Expand Down
16 changes: 16 additions & 0 deletions e2e/docs/.vuepress/theme/client/layouts/CssModulesLayout.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script setup lang="ts">
import styles from '../styles/styles.module.css'
import variables from '../styles/variables.module.scss'
</script>

<template>
<div class="e2e-theme-css-modules-layout">
<main class="e2e-theme-css-modules-layout-content">
<div id="e2e-theme-css-modules-scss">{{ variables.fooScss }}</div>
<div id="e2e-theme-css-modules-css" :class="styles.greenText">
CSS modules green text
</div>
<Content />
</main>
</div>
</template>
3 changes: 3 additions & 0 deletions e2e/docs/.vuepress/theme/client/styles/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.greenText {
color: rgb(0, 129, 0);
}
3 changes: 3 additions & 0 deletions e2e/docs/.vuepress/theme/client/styles/variables.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:export {
fooScss: 234px;
}
3 changes: 3 additions & 0 deletions e2e/docs/styles/css-modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
layout: CssModulesLayout
---
10 changes: 10 additions & 0 deletions e2e/tests/styles/css-modules.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { expect, test } from '@playwright/test'

test('Should load CSS modules correctly', async ({ page }) => {
await page.goto('styles/css-modules.html')
await expect(page.locator('#e2e-theme-css-modules-scss')).toHaveText('234px')
await expect(page.locator('#e2e-theme-css-modules-css')).toHaveCSS(
'color',
'rgb(0, 129, 0)',
)
})
82 changes: 18 additions & 64 deletions packages/bundler-webpack/src/config/handleModuleStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import type {

const require = createRequire(import.meta.url)

type StyleRule = Config.Rule<Config.Rule<Config.Module>>

/**
* Set webpack module to handle style files
*/
Expand All @@ -29,36 +27,19 @@ export const handleModuleStyles = ({
isBuild: boolean
isServer: boolean
}): void => {
const createStyleRules = ({
const handleStyle = <T extends LoaderOptions = LoaderOptions>({
lang,
test,
loaderName,
loaderOptions,
}: {
lang: string
test: RegExp
}): {
modulesRule: StyleRule
normalRule: StyleRule
} => {
const baseRule = config.module.rule(lang).test(test)
const modulesRule = baseRule.oneOf('modules').resourceQuery(/module/)
const normalRule = baseRule.oneOf('normal')
return {
modulesRule,
normalRule,
}
}

const applyStyleHandlers = ({
rule,
cssModules,
loaderName,
loaderOptions = {},
}: {
rule: StyleRule
cssModules: boolean
loaderName?: string
loaderOptions?: LoaderOptions
loaderOptions?: T
}): void => {
const rule = config.module.rule(lang).test(test)

if (!isServer) {
if (isBuild) {
rule.use('extract-css-loader').loader(MiniCssExtractPlugin.loader)
Expand All @@ -72,13 +53,14 @@ export const handleModuleStyles = ({
.use('css-loader')
.loader(require.resolve('css-loader'))
.options({
modules: cssModules
? {
localIdentName: `[local]_[contenthash:base64:8]`,
exportOnlyLocals: isServer,
}
: false,
importLoaders: 1,
modules: {
auto: true,
exportLocalsConvention: 'as-is',
exportOnlyLocals: isServer,
localIdentName: `[local]_[contenthash:base64:8]`,
namedExport: false,
},
importLoaders: loaderName ? 2 : 1,
})

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

// use extra loader
if (loaderName) {
rule.use(loaderName).loader(loaderName).options(loaderOptions)
rule
.use(loaderName)
.loader(loaderName)
.options(loaderOptions ?? {})
}
}

const handleStyle = <T extends LoaderOptions = LoaderOptions>({
lang,
test,
loaderName,
loaderOptions,
}: {
lang: string
test: RegExp
loaderName?: string
loaderOptions?: T
}): void => {
const { modulesRule, normalRule } = createStyleRules({
lang,
test,
})

applyStyleHandlers({
rule: modulesRule,
cssModules: true,
loaderName,
loaderOptions,
})

applyStyleHandlers({
rule: normalRule,
cssModules: false,
loaderName,
loaderOptions,
})
}

handleStyle({
lang: 'css',
test: /\.css$/,
Expand Down

0 comments on commit 10378e1

Please sign in to comment.