diff --git a/packages/plugin-vue/src/index.ts b/packages/plugin-vue/src/index.ts index 3fce93c9..d1882880 100644 --- a/packages/plugin-vue/src/index.ts +++ b/packages/plugin-vue/src/index.ts @@ -13,6 +13,7 @@ import { version } from '../package.json' import { resolveCompiler } from './compiler' import { parseVueRequest } from './utils/query' import { + type ExtendedSFCDescriptor, getDescriptor, getSrcDescriptor, getTempSrcDescriptor, @@ -399,7 +400,7 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { ) } else { // sub block request - const descriptor = query.src + const descriptor: ExtendedSFCDescriptor = query.src ? getSrcDescriptor(filename, query) || getTempSrcDescriptor(filename, query) : getDescriptor(filename, options.value)! diff --git a/packages/plugin-vue/src/main.ts b/packages/plugin-vue/src/main.ts index 31a0a58b..3b8496b9 100644 --- a/packages/plugin-vue/src/main.ts +++ b/packages/plugin-vue/src/main.ts @@ -275,9 +275,9 @@ export async function transformMain( return { code: resolvedCode, - map: resolvedMap || { + map: (resolvedMap || { mappings: '', - }, + }) as any, meta: { vite: { lang: descriptor.script?.lang || descriptor.scriptSetup?.lang || 'js', diff --git a/packages/plugin-vue/src/style.ts b/packages/plugin-vue/src/style.ts index 0fdbfbc1..01b393fa 100644 --- a/packages/plugin-vue/src/style.ts +++ b/packages/plugin-vue/src/style.ts @@ -1,13 +1,13 @@ -import type { SFCDescriptor } from 'vue/compiler-sfc' import type { ExistingRawSourceMap, TransformPluginContext } from 'rollup' import type { RawSourceMap } from 'source-map-js' import { formatPostcssSourceMap } from 'vite' +import type { ExtendedSFCDescriptor } from './utils/descriptorCache' import type { ResolvedOptions } from './index' // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export async function transformStyle( code: string, - descriptor: SFCDescriptor, + descriptor: ExtendedSFCDescriptor, index: number, options: ResolvedOptions, pluginContext: TransformPluginContext, @@ -62,5 +62,13 @@ export async function transformStyle( return { code: result.code, map: map, + meta: + block.scoped && !descriptor.isTemp + ? { + vite: { + cssScopeTo: [descriptor.filename, 'default'], + }, + } + : undefined, } } diff --git a/packages/plugin-vue/src/utils/descriptorCache.ts b/packages/plugin-vue/src/utils/descriptorCache.ts index 2ba6553b..7e9cb2b0 100644 --- a/packages/plugin-vue/src/utils/descriptorCache.ts +++ b/packages/plugin-vue/src/utils/descriptorCache.ts @@ -75,6 +75,10 @@ export function invalidateDescriptor(filename: string, hmr = false): void { } } +export interface ExtendedSFCDescriptor extends SFCDescriptor { + isTemp?: boolean +} + export function getDescriptor( filename: string, options: ResolvedOptions, @@ -113,7 +117,7 @@ export function getSrcDescriptor( export function getTempSrcDescriptor( filename: string, query: VueQuery, -): SFCDescriptor { +): ExtendedSFCDescriptor { // this is only used for pre-compiled diff --git a/playground/vue/__tests__/vue.spec.ts b/playground/vue/__tests__/vue.spec.ts index 9bfc9248..898d5123 100644 --- a/playground/vue/__tests__/vue.spec.ts +++ b/playground/vue/__tests__/vue.spec.ts @@ -3,6 +3,7 @@ import { version } from 'vue' import { browserLogs, editFile, + findAssetFile, getBg, getColor, isBuild, @@ -455,3 +456,8 @@ describe('template parse options', () => { ) }) }) + +test.runIf(isBuild)('scoped style should be tree-shakeable', async () => { + const indexCss = findAssetFile(/index-[\w-]+\.css/) + expect(indexCss).not.toContain('.tree-shake-scoped-style') +})