mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
Skip scoped astro-*
class if Astro component has no <style>
(#497)
* feat(#472): do not inject `astro-xxx` class for components without styles * test: add test for skipped scoped classes * chore: add changeset * Update happy-cougars-scream.md
This commit is contained in:
parent
348babc660
commit
2671b6f9cc
5 changed files with 25 additions and 2 deletions
5
.changeset/happy-cougars-scream.md
Normal file
5
.changeset/happy-cougars-scream.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fix [472](https://github.com/snowpackjs/astro/issues/472) by not injecting `astro-*` scoped class unless it is actually used
|
|
@ -189,6 +189,7 @@ export default function transformStyles({ compileOptions, filename, fileID }: Tr
|
|||
const styleNodes: TemplateNode[] = []; // <style> tags to be updated
|
||||
const styleTransformPromises: Promise<StyleTransformResult>[] = []; // async style transform results to be finished in finalize();
|
||||
const scopedClass = `astro-${hashFromFilename(fileID)}`; // this *should* generate same hash from fileID every time
|
||||
const nodesToScope = new Set<TemplateNode>();
|
||||
|
||||
return {
|
||||
visitors: {
|
||||
|
@ -225,8 +226,7 @@ export default function transformStyles({ compileOptions, filename, fileID }: Tr
|
|||
return; // only continue if this is NOT a <script> tag, etc.
|
||||
}
|
||||
// Note: currently we _do_ scope web components/custom elements. This seems correct?
|
||||
|
||||
injectScopedClassAttribute(node, scopedClass);
|
||||
nodesToScope.add(node);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -254,6 +254,14 @@ export default function transformStyles({ compileOptions, filename, fileID }: Tr
|
|||
},
|
||||
async finalize() {
|
||||
const styleTransforms = await Promise.all(styleTransformPromises);
|
||||
|
||||
// If we DO have styles, let's inject the scoped `class` attribute
|
||||
// Otherwise, our final optimization is easier if we skip this
|
||||
if (styleTransforms.length > 0) {
|
||||
for (const node of nodesToScope.values()) {
|
||||
injectScopedClassAttribute(node, scopedClass);
|
||||
}
|
||||
}
|
||||
|
||||
styleTransforms.forEach((result, n) => {
|
||||
if (styleNodes[n].attributes) {
|
||||
|
|
|
@ -126,4 +126,11 @@ StylesSSR('Astro scoped styles', async ({ runtime }) => {
|
|||
assert.match(cssMinify(css.toString()), `.blue.${scopedClass}{color:powderblue}.color\\:blue.${scopedClass}{color:powderblue}.visible.${scopedClass}{display:block}`);
|
||||
});
|
||||
|
||||
StylesSSR('Astro scoped styles skipped without <style>', async ({ runtime }) => {
|
||||
const result = await runtime.load('/');
|
||||
const $ = doc(result.contents);
|
||||
|
||||
assert.type($('#no-scope').attr('class'), 'undefined', `Astro component without <style> should not include scoped class`)
|
||||
});
|
||||
|
||||
StylesSSR.run();
|
||||
|
|
1
packages/astro/test/fixtures/astro-styles-ssr/src/components/AstroNone.astro
vendored
Normal file
1
packages/astro/test/fixtures/astro-styles-ssr/src/components/AstroNone.astro
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<div id="no-scope">360</div>
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
import AstroComponent from '../components/Astro.astro';
|
||||
import AstroComponentNone from '../components/AstroNone.astro';
|
||||
import ReactCSS from '../components/ReactCSS.jsx';
|
||||
import ReactModules from '../components/ReactModules.jsx';
|
||||
import VueCSS from '../components/VueCSS.vue';
|
||||
|
@ -22,6 +23,7 @@ import SvelteScoped from '../components/SvelteScoped.svelte';
|
|||
<body>
|
||||
<div class="wrapper">
|
||||
<AstroComponent />
|
||||
<AstroComponentNone />
|
||||
<ReactCSS />
|
||||
<ReactModules />
|
||||
<VueCSS />
|
||||
|
|
Loading…
Reference in a new issue