From 3891d0558bbebd39355445ecbcfd69346fe42985 Mon Sep 17 00:00:00 2001 From: Adam Hines Date: Tue, 15 Aug 2023 10:56:49 -0600 Subject: [PATCH] fix(css): don't mock css-module if inline is specified (#3952) Co-authored-by: Adam Hines --- .../vitest/src/node/plugins/cssEnabler.ts | 9 ++++++++- test/css/test/process-inline.spec.ts | 20 +++++++++++++++++++ test/css/testing.mjs | 5 +++-- 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 test/css/test/process-inline.spec.ts diff --git a/packages/vitest/src/node/plugins/cssEnabler.ts b/packages/vitest/src/node/plugins/cssEnabler.ts index 8a85f1783acd..4bf464fc298f 100644 --- a/packages/vitest/src/node/plugins/cssEnabler.ts +++ b/packages/vitest/src/node/plugins/cssEnabler.ts @@ -7,6 +7,7 @@ import { toArray } from '../../utils' const cssLangs = '\\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\\?)' const cssLangRE = new RegExp(cssLangs) const cssModuleRE = new RegExp(`\\.module${cssLangs}`) +const cssInlineRE = /[?&]inline(&|$)/ function isCSS(id: string) { return cssLangRE.test(id) @@ -16,6 +17,12 @@ function isCSSModule(id: string) { return cssModuleRE.test(id) } +// inline css requests are expected to just return the +// string content directly and not the proxy module +function isInline(id: string) { + return cssInlineRE.test(id) +} + function getCSSModuleProxyReturn(strategy: CSSModuleScopeStrategy, filename: string) { if (strategy === 'non-scoped') return 'style' @@ -55,7 +62,7 @@ export function CSSEnablerPlugin(ctx: { config: ResolvedConfig }): VitePlugin[] if (!isCSS(id) || shouldProcessCSS(id)) return - if (isCSSModule(id)) { + if (isCSSModule(id) && !isInline(id)) { // return proxy for css modules, so that imported module has names: // styles.foo returns a "foo" instead of "undefined" // we don't use code content to generate hash for "scoped", because it's empty diff --git a/test/css/test/process-inline.spec.ts b/test/css/test/process-inline.spec.ts new file mode 100644 index 000000000000..35ff2e7474e4 --- /dev/null +++ b/test/css/test/process-inline.spec.ts @@ -0,0 +1,20 @@ +import { describe, expect, test } from 'vitest' +import { useRemoveStyles } from './utils' + +describe('processing inline css', () => { + useRemoveStyles() + + test('doesn\'t apply css', async () => { + await import('../src/App.module.css?inline') + + const element = document.createElement('div') + element.className = 'main' + const computed = window.getComputedStyle(element) + expect(computed.display, 'css is not processed').toBe('block') + }) + + test('returns a string', async () => { + const { default: style } = await import('../src/App.module.css?inline') + expect(typeof style).toBe('string') + }) +}) diff --git a/test/css/testing.mjs b/test/css/testing.mjs index 3a4f58b0ee89..0a1872737ce6 100644 --- a/test/css/testing.mjs +++ b/test/css/testing.mjs @@ -3,14 +3,15 @@ import { startVitest } from 'vitest/node' const configs = [ ['test/default-css', {}], ['test/process-css', { include: [/App\.css/] }], - ['test/process-module', { include: [/App\.module\.css/] }], + [['test/process-module', 'test/process-inline'], { include: [/App\.module\.css/] }], ['test/scope-module', { include: [/App\.module\.css/], modules: { classNameStrategy: 'scoped' } }], ['test/non-scope-module', { include: [/App\.module\.css/], modules: { classNameStrategy: 'non-scoped' } }], ] async function runTests() { for (const [name, config] of configs) { - await startVitest('test', [name], { + const names = Array.isArray(name) ? name : [name]; + await startVitest('test', names, { run: true, css: config, update: false,