diff --git a/e2e/docs/.vuepress/theme/client/config.ts b/e2e/docs/.vuepress/theme/client/config.ts index 8bc9a299db..8d35748afe 100644 --- a/e2e/docs/.vuepress/theme/client/config.ts +++ b/e2e/docs/.vuepress/theme/client/config.ts @@ -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' @@ -16,6 +17,7 @@ export default defineClientConfig({ }, layouts: { + CssModulesLayout, CustomLayout, Layout, NotFound, diff --git a/e2e/docs/.vuepress/theme/client/layouts/CssModulesLayout.vue b/e2e/docs/.vuepress/theme/client/layouts/CssModulesLayout.vue new file mode 100644 index 0000000000..d704c89214 --- /dev/null +++ b/e2e/docs/.vuepress/theme/client/layouts/CssModulesLayout.vue @@ -0,0 +1,16 @@ + + + diff --git a/e2e/docs/.vuepress/theme/client/styles/styles.module.css b/e2e/docs/.vuepress/theme/client/styles/styles.module.css new file mode 100644 index 0000000000..0e5179bc90 --- /dev/null +++ b/e2e/docs/.vuepress/theme/client/styles/styles.module.css @@ -0,0 +1,3 @@ +.greenText { + color: rgb(0, 129, 0); +} diff --git a/e2e/docs/.vuepress/theme/client/styles/variables.module.scss b/e2e/docs/.vuepress/theme/client/styles/variables.module.scss new file mode 100644 index 0000000000..ece375ebbe --- /dev/null +++ b/e2e/docs/.vuepress/theme/client/styles/variables.module.scss @@ -0,0 +1,3 @@ +:export { + fooScss: 234px; +} diff --git a/e2e/docs/styles/css-modules.md b/e2e/docs/styles/css-modules.md new file mode 100644 index 0000000000..c7eb942a8a --- /dev/null +++ b/e2e/docs/styles/css-modules.md @@ -0,0 +1,3 @@ +--- +layout: CssModulesLayout +--- diff --git a/e2e/tests/styles/css-modules.spec.ts b/e2e/tests/styles/css-modules.spec.ts new file mode 100644 index 0000000000..403057abfe --- /dev/null +++ b/e2e/tests/styles/css-modules.spec.ts @@ -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)', + ) +}) diff --git a/packages/bundler-webpack/src/config/handleModuleStyles.ts b/packages/bundler-webpack/src/config/handleModuleStyles.ts index 67425a3208..40eea28655 100644 --- a/packages/bundler-webpack/src/config/handleModuleStyles.ts +++ b/packages/bundler-webpack/src/config/handleModuleStyles.ts @@ -13,8 +13,6 @@ import type { const require = createRequire(import.meta.url) -type StyleRule = Config.Rule> - /** * Set webpack module to handle style files */ @@ -29,36 +27,19 @@ export const handleModuleStyles = ({ isBuild: boolean isServer: boolean }): void => { - const createStyleRules = ({ + const handleStyle = ({ 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) @@ -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 @@ -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 = ({ - 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$/,