0
Fork 0
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:
Nate Moore 2021-06-18 19:56:14 -05:00 committed by GitHub
parent 348babc660
commit 2671b6f9cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 25 additions and 2 deletions

View 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

View file

@ -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) {

View file

@ -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();

View file

@ -0,0 +1 @@
<div id="no-scope">360</div>

View file

@ -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 />