Skip to content

Commit 73bfce3

Browse files
committed
refactor: only rewrite css varaiable in <style scoped> when vars is present
1 parent f3cc41f commit 73bfce3

File tree

5 files changed

+66
-44
lines changed

5 files changed

+66
-44
lines changed

packages/compiler-sfc/__tests__/compileStyle.spec.ts

+18-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1-
import { compileStyle, compileStyleAsync } from '../src/compileStyle'
1+
import {
2+
compileStyle,
3+
compileStyleAsync,
4+
SFCStyleCompileOptions
5+
} from '../src/compileStyle'
26
import { mockWarn } from '@vue/shared'
37

48
describe('SFC scoped CSS', () => {
59
mockWarn()
610

7-
function compileScoped(source: string): string {
11+
function compileScoped(
12+
source: string,
13+
options?: Partial<SFCStyleCompileOptions>
14+
): string {
815
const res = compileStyle({
916
source,
1017
filename: 'test.css',
1118
id: 'test',
12-
scoped: true
19+
scoped: true,
20+
...options
1321
})
1422
if (res.errors.length) {
1523
res.errors.forEach(err => {
@@ -254,10 +262,15 @@ describe('SFC scoped CSS', () => {
254262

255263
describe('<style vars>', () => {
256264
test('should rewrite CSS vars in scoped mode', () => {
257-
const code = compileScoped(`.foo {
265+
const code = compileScoped(
266+
`.foo {
258267
color: var(--color);
259268
font-size: var(--global:font);
260-
}`)
269+
}`,
270+
{
271+
vars: true
272+
}
273+
)
261274
expect(code).toMatchInlineSnapshot(`
262275
".foo[test] {
263276
color: var(--test-color);

packages/compiler-sfc/src/compileScript.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ export function compileScript(
174174
}
175175

176176
// 2. check <script setup="xxx"> function signature
177-
const setupValue = scriptSetup.attrs.setup
177+
const setupValue = scriptSetup.setup
178178
const hasExplicitSignature = typeof setupValue === 'string'
179179

180180
let propsVar: string | undefined

packages/compiler-sfc/src/compileStyle.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface SFCStyleCompileOptions {
1515
id: string
1616
map?: RawSourceMap
1717
scoped?: boolean
18+
vars?: boolean
1819
trim?: boolean
1920
preprocessLang?: PreprocessLang
2021
preprocessOptions?: any
@@ -73,6 +74,7 @@ export function doCompileStyle(
7374
filename,
7475
id,
7576
scoped = false,
77+
vars = false,
7678
trim = true,
7779
modules = false,
7880
modulesOptions = {},
@@ -90,7 +92,7 @@ export function doCompileStyle(
9092
plugins.push(trimPlugin())
9193
}
9294
if (scoped) {
93-
plugins.push(scopedPlugin(id))
95+
plugins.push(scopedPlugin({ id, vars }))
9496
}
9597
let cssModules: Record<string, string> | undefined
9698
if (modules) {

packages/compiler-sfc/src/parse.ts

+6
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ export interface SFCTemplateBlock extends SFCBlock {
4040

4141
export interface SFCScriptBlock extends SFCBlock {
4242
type: 'script'
43+
setup?: string | boolean
4344
bindings?: BindingMetadata
4445
}
4546

4647
export interface SFCStyleBlock extends SFCBlock {
4748
type: 'style'
4849
scoped?: boolean
50+
vars?: string
4951
module?: string | boolean
5052
}
5153

@@ -266,11 +268,15 @@ function createBlock(
266268
} else if (type === 'style') {
267269
if (p.name === 'scoped') {
268270
;(block as SFCStyleBlock).scoped = true
271+
} else if (p.name === 'vars' && typeof attrs.vars === 'string') {
272+
;(block as SFCStyleBlock).vars = attrs.vars
269273
} else if (p.name === 'module') {
270274
;(block as SFCStyleBlock).module = attrs[p.name]
271275
}
272276
} else if (type === 'template' && p.name === 'functional') {
273277
;(block as SFCTemplateBlock).functional = true
278+
} else if (type === 'script' && p.name === 'setup') {
279+
;(block as SFCScriptBlock).setup = attrs.setup
274280
}
275281
}
276282
})

packages/compiler-sfc/src/stylePluginScoped.ts

+38-37
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const animationRE = /^(-\w+-)?animation$/
66
const cssVarRE = /\bvar\(--(global:)?([^)]+)\)/g
77

88
export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
9-
const id: string = options
9+
const { id, vars: hasInjectedVars } = options as { id: string; vars: boolean }
1010
const keyframes = Object.create(null)
1111

1212
root.each(function rewriteSelectors(node) {
@@ -135,44 +135,45 @@ export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
135135
})
136136

137137
const hasKeyframes = Object.keys(keyframes).length
138-
root.walkDecls(decl => {
139-
// If keyframes are found in this <style>, find and rewrite animation names
140-
// in declarations.
141-
// Caveat: this only works for keyframes and animation rules in the same
142-
// <style> element.
143-
if (hasKeyframes) {
144-
// individual animation-name declaration
145-
if (animationNameRE.test(decl.prop)) {
146-
decl.value = decl.value
147-
.split(',')
148-
.map(v => keyframes[v.trim()] || v.trim())
149-
.join(',')
150-
}
151-
// shorthand
152-
if (animationRE.test(decl.prop)) {
153-
decl.value = decl.value
154-
.split(',')
155-
.map(v => {
156-
const vals = v.trim().split(/\s+/)
157-
const i = vals.findIndex(val => keyframes[val])
158-
if (i !== -1) {
159-
vals.splice(i, 1, keyframes[vals[i]])
160-
return vals.join(' ')
161-
} else {
162-
return v
163-
}
164-
})
165-
.join(',')
138+
if (hasKeyframes || hasInjectedVars)
139+
root.walkDecls(decl => {
140+
// If keyframes are found in this <style>, find and rewrite animation names
141+
// in declarations.
142+
// Caveat: this only works for keyframes and animation rules in the same
143+
// <style> element.
144+
if (hasKeyframes) {
145+
// individual animation-name declaration
146+
if (animationNameRE.test(decl.prop)) {
147+
decl.value = decl.value
148+
.split(',')
149+
.map(v => keyframes[v.trim()] || v.trim())
150+
.join(',')
151+
}
152+
// shorthand
153+
if (animationRE.test(decl.prop)) {
154+
decl.value = decl.value
155+
.split(',')
156+
.map(v => {
157+
const vals = v.trim().split(/\s+/)
158+
const i = vals.findIndex(val => keyframes[val])
159+
if (i !== -1) {
160+
vals.splice(i, 1, keyframes[vals[i]])
161+
return vals.join(' ')
162+
} else {
163+
return v
164+
}
165+
})
166+
.join(',')
167+
}
166168
}
167-
}
168169

169-
// rewrite CSS variables
170-
if (cssVarRE.test(decl.value)) {
171-
decl.value = decl.value.replace(cssVarRE, (_, $1, $2) => {
172-
return $1 ? `var(--${$2})` : `var(--${id}-${$2})`
173-
})
174-
}
175-
})
170+
// rewrite CSS variables
171+
if (hasInjectedVars && cssVarRE.test(decl.value)) {
172+
decl.value = decl.value.replace(cssVarRE, (_, $1, $2) => {
173+
return $1 ? `var(--${$2})` : `var(--${id}-${$2})`
174+
})
175+
}
176+
})
176177
})
177178

178179
function isSpaceCombinator(node: Node) {

0 commit comments

Comments
 (0)