mirror of
https://github.com/withastro/astro.git
synced 2025-01-06 22:10:10 -05:00
fix(css): fix inline query injection for CSS inlining (#11917)
This commit is contained in:
parent
b9394fa70c
commit
8329d17968
3 changed files with 14 additions and 18 deletions
|
@ -9,6 +9,8 @@ interface ImportedStyle {
|
|||
content: string;
|
||||
}
|
||||
|
||||
const inlineQueryRE = /(?:\?|&)inline(?:$|&)/
|
||||
|
||||
/** Given a filePath URL, crawl Vite’s module graph to find all style imports. */
|
||||
export async function getStylesForURL(
|
||||
filePath: URL,
|
||||
|
@ -32,21 +34,20 @@ export async function getStylesForURL(
|
|||
}
|
||||
// Else try to load it
|
||||
else {
|
||||
const url = new URL(importedModule.url, 'http://localhost');
|
||||
let modId = importedModule.url
|
||||
// Mark url with ?inline so Vite will return the CSS as plain string, even for CSS modules
|
||||
url.searchParams.set('inline', '');
|
||||
const modId = `${decodeURI(url.pathname)}${url.search}`;
|
||||
|
||||
if (!inlineQueryRE.test(importedModule.url)) {
|
||||
if (importedModule.url.includes('?')) {
|
||||
modId = importedModule.url.replace('?', '?inline&');
|
||||
} else {
|
||||
modId += '?inline';
|
||||
}
|
||||
}
|
||||
try {
|
||||
// The SSR module is possibly not loaded. Load it if it's null.
|
||||
const ssrModule = await loader.import(modId);
|
||||
css = ssrModule.default;
|
||||
} catch {
|
||||
// Some CSS modules, e.g. from Vue files, may not work with the ?inline query.
|
||||
// If so, we fallback to a url instead
|
||||
if (modId.includes('.module.')) {
|
||||
importedCssUrls.add(importedModule.url);
|
||||
}
|
||||
// The module may not be inline-able, e.g. SCSS partials. Skip it as it may already
|
||||
// be inlined into other modules if it happens to be in the graph.
|
||||
continue;
|
||||
|
|
|
@ -225,7 +225,7 @@ describe('CSS', function () {
|
|||
it('<style module>', async () => {
|
||||
const el = $('#vue-modules');
|
||||
const classes = el.attr('class').split(' ');
|
||||
const moduleClass = classes.find((name) => /^_title_[\w-]+/.test(name));
|
||||
const moduleClass = classes.find((name) => /^_vueModules_[\w-]+/.test(name));
|
||||
|
||||
// 1. check HTML
|
||||
assert.equal(el.attr('class').includes(moduleClass), true);
|
||||
|
@ -405,18 +405,13 @@ describe('CSS', function () {
|
|||
});
|
||||
|
||||
it('resolves CSS from Vue', async () => {
|
||||
const styles = ['VueModules.vue?vue&type=style&index=0&lang.module.scss'];
|
||||
for (const style of styles) {
|
||||
const href = $(`link[href$="${style}"]`).attr('href');
|
||||
assert.equal((await fixture.fetch(href)).status, 200, style);
|
||||
}
|
||||
|
||||
const allInjectedStyles = $('style').text().replace(/\s*/g, '');
|
||||
|
||||
assert.equal(allInjectedStyles.includes('.vue-css{'), true);
|
||||
assert.equal(allInjectedStyles.includes('.vue-sass{'), true);
|
||||
assert.equal(allInjectedStyles.includes('.vue-scss{'), true);
|
||||
assert.equal(allInjectedStyles.includes('.vue-scoped[data-v-'), true);
|
||||
assert.equal(allInjectedStyles.includes('._vueModules_'), true);
|
||||
});
|
||||
|
||||
it('remove unused styles from client:load components', async () => {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<style module lang="scss">
|
||||
$type: cursive;
|
||||
.title {
|
||||
.vueModules {
|
||||
font-family: $type;
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<h1 id="vue-modules" :class="$style.title">Vue CSS Modules</h1>
|
||||
<h1 id="vue-modules" :class="$style.vueModules">Vue CSS Modules</h1>
|
||||
</template>
|
||||
|
|
Loading…
Reference in a new issue