Skip to content

Commit 333094f

Browse files
feat(css): tree shake scoped styles (#533)
Co-authored-by: edison <daiwei521@126.com>
1 parent 906cebb commit 333094f

File tree

8 files changed

+47
-9
lines changed

8 files changed

+47
-9
lines changed

packages/plugin-vue/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { version } from '../package.json'
1313
import { resolveCompiler } from './compiler'
1414
import { parseVueRequest } from './utils/query'
1515
import {
16+
type ExtendedSFCDescriptor,
1617
getDescriptor,
1718
getSrcDescriptor,
1819
getTempSrcDescriptor,
@@ -412,7 +413,7 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin<Api> {
412413
)
413414
} else {
414415
// sub block request
415-
const descriptor = query.src
416+
const descriptor: ExtendedSFCDescriptor = query.src
416417
? getSrcDescriptor(filename, query) ||
417418
getTempSrcDescriptor(filename, query)
418419
: getDescriptor(filename, options.value)!

packages/plugin-vue/src/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,9 @@ export async function transformMain(
275275

276276
return {
277277
code: resolvedCode,
278-
map: resolvedMap || {
278+
map: (resolvedMap || {
279279
mappings: '',
280-
},
280+
}) as any,
281281
meta: {
282282
vite: {
283283
lang: descriptor.script?.lang || descriptor.scriptSetup?.lang || 'js',

packages/plugin-vue/src/style.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import type { SFCDescriptor } from 'vue/compiler-sfc'
21
import type { ExistingRawSourceMap, TransformPluginContext } from 'rollup'
32
import type { RawSourceMap } from 'source-map-js'
43
import { formatPostcssSourceMap } from 'vite'
4+
import type { ExtendedSFCDescriptor } from './utils/descriptorCache'
55
import type { ResolvedOptions } from './index'
66

77
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
88
export async function transformStyle(
99
code: string,
10-
descriptor: SFCDescriptor,
10+
descriptor: ExtendedSFCDescriptor,
1111
index: number,
1212
options: ResolvedOptions,
1313
pluginContext: TransformPluginContext,
@@ -62,5 +62,13 @@ export async function transformStyle(
6262
return {
6363
code: result.code,
6464
map: map,
65+
meta:
66+
block.scoped && !descriptor.isTemp
67+
? {
68+
vite: {
69+
cssScopeTo: [descriptor.filename, 'default'],
70+
},
71+
}
72+
: undefined,
6573
}
6674
}

packages/plugin-vue/src/utils/descriptorCache.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ export function invalidateDescriptor(filename: string, hmr = false): void {
7575
}
7676
}
7777

78+
export interface ExtendedSFCDescriptor extends SFCDescriptor {
79+
isTemp?: boolean
80+
}
81+
7882
export function getDescriptor(
7983
filename: string,
8084
options: ResolvedOptions,
@@ -113,7 +117,7 @@ export function getSrcDescriptor(
113117
export function getTempSrcDescriptor(
114118
filename: string,
115119
query: VueQuery,
116-
): SFCDescriptor {
120+
): ExtendedSFCDescriptor {
117121
// this is only used for pre-compiled <style src> with scoped flag
118122
return {
119123
filename,
@@ -124,9 +128,10 @@ export function getTempSrcDescriptor(
124128
loc: {
125129
start: { line: 0, column: 0 },
126130
},
127-
},
131+
} as any,
128132
],
129-
} as SFCDescriptor
133+
isTemp: true,
134+
} as ExtendedSFCDescriptor
130135
}
131136

132137
export function setSrcDescriptor(

playground/ssr-vue/vite.config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ export default defineConfig(({ command, ssrBuild, isSsrBuild }) => ({
9393
) {
9494
return {
9595
code:
96-
`import { __ssr_vue_processAssetPath } from '${virtualId}';__ssr_vue_processAssetPath;` +
96+
`import { __ssr_vue_processAssetPath } from '${virtualId}';` +
97+
// make `__ssr_vue_processAssetPath` not to be tree-shaken (`globalThis.__ssr_vue` doesn't exist)
98+
`globalThis.__ssr_vue?.(__ssr_vue_processAssetPath);` +
9799
code,
98100
sourcemap: null, // no sourcemap support to speed up CI
99101
}

playground/vue/Main.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ import PreCompiledExternalScoped from './pre-compiled/external-scoped.vue'
6868
import PreCompiledExternalCssModules from './pre-compiled/external-cssmodules.vue'
6969
import ParserOptions from './ParserOptions.vue'
7070
import HmrCircularReference from './HmrCircularReference.vue'
71+
import TreeShakeScopedStyle from './TreeShakeScopedStyle.vue'
72+
73+
// NOTE: this function is not used intentionally
74+
function foo() {
75+
console.log(TreeShakeScopedStyle)
76+
}
77+
7178
import ExportTypeProps1 from './ExportTypeProps1.vue'
7279
import ExportTypeProps2 from './ExportTypeProps2.vue'
7380
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<template>
2+
<div>tree shake scoped style</div>
3+
</template>
4+
5+
<style scoped>
6+
.tree-shake-scoped-style {
7+
color: red;
8+
}
9+
</style>

playground/vue/__tests__/vue.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { version } from 'vue'
33
import {
44
browserLogs,
55
editFile,
6+
findAssetFile,
67
getBg,
78
getColor,
89
isBuild,
@@ -455,3 +456,8 @@ describe('template parse options', () => {
455456
)
456457
})
457458
})
459+
460+
test.runIf(isBuild)('scoped style should be tree-shakeable', async () => {
461+
const indexCss = findAssetFile(/index-[\w-]+\.css/)
462+
expect(indexCss).not.toContain('.tree-shake-scoped-style')
463+
})

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy