Skip to content

Commit 866285a

Browse files
Replace internal cssScopeTo implementation to vite.cssScopeTo (#13668)
Co-authored-by: bluwy <[email protected]> Co-authored-by: ematipico <[email protected]>
1 parent 7036b05 commit 866285a

File tree

4 files changed

+15
-86
lines changed

4 files changed

+15
-86
lines changed

.changeset/three-cooks-drive.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Replaces internal CSS chunking behavior for Astro components' scoped styles to use Vite's `cssScopeTo` feature. The feature is a port of Astro's implementation so this should not change the behavior.

packages/astro/src/core/build/plugins/plugin-css.ts

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import type { GetModuleInfo } from 'rollup';
2-
import type { BuildOptions, ResolvedConfig, Rollup, Plugin as VitePlugin } from 'vite';
2+
import type { BuildOptions, ResolvedConfig, Plugin as VitePlugin } from 'vite';
33
import { isBuildableCSSRequest } from '../../../vite-plugin-astro-server/util.js';
44
import type { BuildInternals } from '../internal.js';
55
import type { AstroBuildPlugin, BuildTarget } from '../plugin.js';
66
import type { PageBuildData, StaticBuildOptions, StylesheetAsset } from '../types.js';
77

88
import { hasAssetPropagationFlag } from '../../../content/index.js';
9-
import type { AstroPluginCssMetadata } from '../../../vite-plugin-astro/index.js';
109
import * as assetName from '../css-asset-name.js';
1110
import {
1211
getParentExtendedModuleInfos,
@@ -156,32 +155,6 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
156155
},
157156
};
158157

159-
/**
160-
* This plugin is a port of https://github.com/vitejs/vite/pull/16058. It enables removing unused
161-
* scoped CSS from the bundle if the scoped target (e.g. Astro files) were not bundled.
162-
* Once/If that PR is merged, we can refactor this away, renaming `meta.astroCss` to `meta.vite`.
163-
*/
164-
const cssScopeToPlugin: VitePlugin = {
165-
name: 'astro:rollup-plugin-css-scope-to',
166-
renderChunk(_, chunk, __, meta) {
167-
for (const id in chunk.modules) {
168-
// If this CSS is scoped to its importers exports, check if those importers exports
169-
// are rendered in the chunks. If they are not, we can skip bundling this CSS.
170-
const modMeta = this.getModuleInfo(id)?.meta as AstroPluginCssMetadata | undefined;
171-
const cssScopeTo = modMeta?.astroCss?.cssScopeTo;
172-
if (cssScopeTo && !isCssScopeToRendered(cssScopeTo, Object.values(meta.chunks))) {
173-
// If this CSS is not used, delete it from the chunk modules so that Vite is unable
174-
// to trace that it's used
175-
delete chunk.modules[id];
176-
const moduleIdsIndex = chunk.moduleIds.indexOf(id);
177-
if (moduleIdsIndex > -1) {
178-
chunk.moduleIds.splice(moduleIdsIndex, 1);
179-
}
180-
}
181-
}
182-
},
183-
};
184-
185158
const singleCssPlugin: VitePlugin = {
186159
name: 'astro:rollup-plugin-single-css',
187160
enforce: 'post',
@@ -273,7 +246,7 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
273246
},
274247
};
275248

276-
return [cssBuildPlugin, cssScopeToPlugin, singleCssPlugin, inlineStylesheetsPlugin];
249+
return [cssBuildPlugin, singleCssPlugin, inlineStylesheetsPlugin];
277250
}
278251

279252
/***** UTILITY FUNCTIONS *****/
@@ -321,25 +294,3 @@ function appendCSSToPage(
321294
}
322295
}
323296
}
324-
325-
/**
326-
* `cssScopeTo` is a map of `importer`s to its `export`s. This function iterate each `cssScopeTo` entries
327-
* and check if the `importer` and its `export`s exists in the final chunks. If at least one matches,
328-
* `cssScopeTo` is considered "rendered" by Rollup and we return true.
329-
*/
330-
function isCssScopeToRendered(
331-
cssScopeTo: Record<string, string[]>,
332-
chunks: Rollup.RenderedChunk[],
333-
) {
334-
for (const moduleId in cssScopeTo) {
335-
const exports = cssScopeTo[moduleId];
336-
// Find the chunk that renders this `moduleId` and get the rendered module
337-
const renderedModule = chunks.find((c) => c.moduleIds.includes(moduleId))?.modules[moduleId];
338-
// Return true if `renderedModule` exists and one of its exports is rendered
339-
if (renderedModule?.renderedExports.some((e) => exports.includes(e))) {
340-
return true;
341-
}
342-
}
343-
344-
return false;
345-
}

packages/astro/src/vite-plugin-astro/index.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ import type { SourceDescription } from 'rollup';
22
import type * as vite from 'vite';
33
import type { Logger } from '../core/logger/core.js';
44
import type { AstroSettings } from '../types/astro.js';
5-
import type {
6-
PluginCssMetadata as AstroPluginCssMetadata,
7-
PluginMetadata as AstroPluginMetadata,
8-
CompileMetadata,
9-
} from './types.js';
5+
import type { PluginMetadata as AstroPluginMetadata, CompileMetadata } from './types.js';
106

117
import { defaultClientConditions, defaultServerConditions, normalizePath } from 'vite';
128
import type { AstroConfig } from '../types/public/config.js';
@@ -16,7 +12,7 @@ import { handleHotUpdate } from './hmr.js';
1612
import { parseAstroRequest } from './query.js';
1713
import { loadId } from './utils.js';
1814
export { getAstroMetadata } from './metadata.js';
19-
export type { AstroPluginMetadata, AstroPluginCssMetadata };
15+
export type { AstroPluginMetadata };
2016

2117
interface AstroPluginOptions {
2218
settings: AstroSettings;
@@ -138,17 +134,15 @@ export default function astro({ settings, logger }: AstroPluginOptions): vite.Pl
138134

139135
return {
140136
code: result.code,
141-
// This metadata is used by `cssScopeToPlugin` to remove this module from the bundle
142-
// if the `filename` default export (the Astro component) is unused.
137+
// `vite.cssScopeTo` is a Vite feature that allows this CSS to be treeshaken
138+
// if the Astro component's default export is not used
143139
meta: result.isGlobal
144140
? undefined
145-
: ({
146-
astroCss: {
147-
cssScopeTo: {
148-
[filename]: ['default'],
149-
},
141+
: {
142+
vite: {
143+
cssScopeTo: [filename, 'default'],
150144
},
151-
} satisfies AstroPluginCssMetadata),
145+
},
152146
};
153147
}
154148
case 'script': {

packages/astro/src/vite-plugin-astro/types.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,6 @@ export interface PluginMetadata {
1818
};
1919
}
2020

21-
export interface PluginCssMetadata {
22-
astroCss: {
23-
/**
24-
* For Astro CSS virtual modules, it can scope to the main Astro module's default export
25-
* so that if those exports are treeshaken away, the CSS module will also be treeshaken.
26-
*
27-
* Example config if the CSS id is `/src/Foo.astro?astro&type=style&lang.css`:
28-
* ```js
29-
* cssScopeTo: {
30-
* '/src/Foo.astro': ['default']
31-
* }
32-
* ```
33-
*
34-
* The above is the only config we use today, but we're exposing as a `Record` to follow the
35-
* upstream Vite implementation: https://github.com/vitejs/vite/pull/16058. When/If that lands,
36-
* we can also remove our custom implementation.
37-
*/
38-
cssScopeTo: Record<string, string[]>;
39-
};
40-
}
41-
4221
export interface CompileMetadata {
4322
/** Used for HMR to compare code changes */
4423
originalCode: string;

0 commit comments

Comments
 (0)