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 styleNodes: TemplateNode[] = []; // <style> tags to be updated
|
||||||
const styleTransformPromises: Promise<StyleTransformResult>[] = []; // async style transform results to be finished in finalize();
|
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 scopedClass = `astro-${hashFromFilename(fileID)}`; // this *should* generate same hash from fileID every time
|
||||||
|
const nodesToScope = new Set<TemplateNode>();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
visitors: {
|
visitors: {
|
||||||
|
@ -225,8 +226,7 @@ export default function transformStyles({ compileOptions, filename, fileID }: Tr
|
||||||
return; // only continue if this is NOT a <script> tag, etc.
|
return; // only continue if this is NOT a <script> tag, etc.
|
||||||
}
|
}
|
||||||
// Note: currently we _do_ scope web components/custom elements. This seems correct?
|
// Note: currently we _do_ scope web components/custom elements. This seems correct?
|
||||||
|
nodesToScope.add(node);
|
||||||
injectScopedClassAttribute(node, scopedClass);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -255,6 +255,14 @@ export default function transformStyles({ compileOptions, filename, fileID }: Tr
|
||||||
async finalize() {
|
async finalize() {
|
||||||
const styleTransforms = await Promise.all(styleTransformPromises);
|
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) => {
|
styleTransforms.forEach((result, n) => {
|
||||||
if (styleNodes[n].attributes) {
|
if (styleNodes[n].attributes) {
|
||||||
// 1. Replace with final CSS
|
// 1. Replace with final CSS
|
||||||
|
|
|
@ -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}`);
|
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();
|
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 AstroComponent from '../components/Astro.astro';
|
||||||
|
import AstroComponentNone from '../components/AstroNone.astro';
|
||||||
import ReactCSS from '../components/ReactCSS.jsx';
|
import ReactCSS from '../components/ReactCSS.jsx';
|
||||||
import ReactModules from '../components/ReactModules.jsx';
|
import ReactModules from '../components/ReactModules.jsx';
|
||||||
import VueCSS from '../components/VueCSS.vue';
|
import VueCSS from '../components/VueCSS.vue';
|
||||||
|
@ -22,6 +23,7 @@ import SvelteScoped from '../components/SvelteScoped.svelte';
|
||||||
<body>
|
<body>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<AstroComponent />
|
<AstroComponent />
|
||||||
|
<AstroComponentNone />
|
||||||
<ReactCSS />
|
<ReactCSS />
|
||||||
<ReactModules />
|
<ReactModules />
|
||||||
<VueCSS />
|
<VueCSS />
|
||||||
|
|
Loading…
Add table
Reference in a new issue