summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fred K. Schott <fkschott@gmail.com> 2022-02-25 15:04:04 -0800
committerGravatar GitHub <noreply@github.com> 2022-02-25 17:04:04 -0600
commitfca6407318f7f189fb65f096f8166b85a322efda (patch)
tree87af95b908e49112583e178bd4f976a43fa115c2
parentba49d3efc2a69bf9a1f719469ac3097c72b11964 (diff)
downloadastro-fca6407318f7f189fb65f096f8166b85a322efda.tar.gz
astro-fca6407318f7f189fb65f096f8166b85a322efda.tar.zst
astro-fca6407318f7f189fb65f096f8166b85a322efda.zip
fix astro scoping of "@import" inside of style tags (#2656)
* fix astro scoping of "@import" inside of style tags * Create lovely-lies-dress.md * Update compile.ts * fix smoke test * Update package.json
-rw-r--r--.changeset/lovely-lies-dress.md5
-rw-r--r--examples/fast-build/package.json2
-rw-r--r--packages/astro/src/vite-plugin-astro/compile.ts34
3 files changed, 35 insertions, 6 deletions
diff --git a/.changeset/lovely-lies-dress.md b/.changeset/lovely-lies-dress.md
new file mode 100644
index 000000000..9e982c8ce
--- /dev/null
+++ b/.changeset/lovely-lies-dress.md
@@ -0,0 +1,5 @@
+---
+"astro": patch
+---
+
+fix astro scoping of "@import" inside of style tags
diff --git a/examples/fast-build/package.json b/examples/fast-build/package.json
index 26cc49b9b..a769fd1c7 100644
--- a/examples/fast-build/package.json
+++ b/examples/fast-build/package.json
@@ -4,7 +4,7 @@
"private": true,
"scripts": {
"dev": "astro dev --experimental-static-build",
- "start": "astro dev",
+ "start": "astro dev --experimental-static-build",
"build": "astro build --experimental-static-build",
"scan-build": "astro build",
"preview": "astro preview"
diff --git a/packages/astro/src/vite-plugin-astro/compile.ts b/packages/astro/src/vite-plugin-astro/compile.ts
index 7eb0eddc4..569392ceb 100644
--- a/packages/astro/src/vite-plugin-astro/compile.ts
+++ b/packages/astro/src/vite-plugin-astro/compile.ts
@@ -9,10 +9,28 @@ import { transform } from '@astrojs/compiler';
import { transformWithVite } from './styles.js';
type CompilationCache = Map<string, CompileResult>;
+type CompileResult = TransformResult & { rawCSSDeps: Set<string> };
-const configCache = new WeakMap<AstroConfig, CompilationCache>();
+/**
+ * Note: this is currently needed because Astro is directly using a Vite internal CSS transform. This gives us
+ * some nice features out of the box, but at the expense of also running Vite's CSS postprocessing build step,
+ * which does some things that we don't like, like resolving/handling `@import` too early. This function pulls
+ * out the `@import` tags to be added back later, and then finally handled correctly by Vite.
+ *
+ * In the future, we should remove this workaround and most likely implement our own Astro style handling without
+ * having to hook into Vite's internals.
+ */
+function createImportPlaceholder(spec: string) {
+ // Note: We keep this small so that we can attempt to exactly match the # of characters in the original @import.
+ // This keeps sourcemaps accurate (to the best of our ability) at the intermediate step where this appears.
+ // -> `@import '${spec}';`;
+ return `/*IMPORT:${spec}*/`;
+}
+function safelyReplaceImportPlaceholder(code: string) {
+ return code.replace(/\/\*IMPORT\:(.*?)\*\//g, `@import '$1';`);
+}
-type CompileResult = TransformResult & { rawCSSDeps: Set<string> };
+const configCache = new WeakMap<AstroConfig, CompilationCache>();
async function compile(config: AstroConfig, filename: string, source: string, viteTransform: TransformHook, opts: { ssr: boolean }): Promise<CompileResult> {
// pages and layouts should be transformed as full documents (implicit <head> <body> etc)
@@ -44,9 +62,15 @@ async function compile(config: AstroConfig, filename: string, source: string, vi
try {
// In the static build, grab any @import as CSS dependencies for HMR.
if (config.buildOptions.experimentalStaticBuild) {
- value.replace(/(?:@import)\s(?:url\()?\s?["\'](.*?)["\']\s?\)?(?:[^;]*);?/gi, (match, spec) => {
+ value = value.replace(/(?:@import)\s(?:url\()?\s?["\'](.*?)["\']\s?\)?(?:[^;]*);?/gi, (match, spec) => {
rawCSSDeps.add(spec);
- return match;
+ // If the language is CSS: prevent `@import` inlining to prevent scoping of imports.
+ // Otherwise: Sass, etc. need to see imports for variables, so leave in for their compiler to handle.
+ if (lang === '.css') {
+ return createImportPlaceholder(spec);
+ } else {
+ return match;
+ }
});
}
@@ -67,7 +91,7 @@ async function compile(config: AstroConfig, filename: string, source: string, vi
map = result.map.toString();
}
}
- const code = result.code;
+ const code = safelyReplaceImportPlaceholder(result.code);
return { code, map };
} catch (err) {
// save error to throw in plugin context