From 627aec3f04de424ec144cefac4a5a3b70d9ba0fb Mon Sep 17 00:00:00 2001
From: Matt Kane
Date: Fri, 17 Jan 2025 12:34:06 +0000
Subject: [PATCH] fix: do not inject env vars into non-source files (#13001)
---
.changeset/warm-pandas-lick.md | 5 ++++
.../src/env/vite-plugin-import-meta-env.ts | 12 +++++++--
packages/astro/test/astro-envs.test.js | 9 +++++++
packages/astro/test/fixtures/astro-envs/.env | 1 +
.../test/fixtures/astro-envs/astro.config.mjs | 14 ++++++++++
.../fixtures/astro-envs/src/data/cats.json | 27 +++++++++++++++++++
.../fixtures/astro-envs/src/data/hello.css | 4 +++
.../test/fixtures/astro-envs/src/data/hi.md | 7 +++++
.../fixtures/astro-envs/src/pages/index.astro | 5 ++++
.../fixtures/astro-envs/src/pages/info.html | 14 ++++++++++
10 files changed, 96 insertions(+), 2 deletions(-)
create mode 100644 .changeset/warm-pandas-lick.md
create mode 100644 packages/astro/test/fixtures/astro-envs/src/data/cats.json
create mode 100644 packages/astro/test/fixtures/astro-envs/src/data/hello.css
create mode 100644 packages/astro/test/fixtures/astro-envs/src/data/hi.md
create mode 100644 packages/astro/test/fixtures/astro-envs/src/pages/info.html
diff --git a/.changeset/warm-pandas-lick.md b/.changeset/warm-pandas-lick.md
new file mode 100644
index 000000000000..e3d4c5af339f
--- /dev/null
+++ b/.changeset/warm-pandas-lick.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fixes a bug that caused Astro to attempt to inject environment variables into non-source files, causing performance problems and broken builds
diff --git a/packages/astro/src/env/vite-plugin-import-meta-env.ts b/packages/astro/src/env/vite-plugin-import-meta-env.ts
index 0740f7cb4498..bfc032897a37 100644
--- a/packages/astro/src/env/vite-plugin-import-meta-env.ts
+++ b/packages/astro/src/env/vite-plugin-import-meta-env.ts
@@ -1,6 +1,7 @@
import { transform } from 'esbuild';
import MagicString from 'magic-string';
import type * as vite from 'vite';
+import { createFilter, isCSSRequest } from 'vite';
import type { EnvLoader } from './env-loader.js';
interface EnvPluginOptions {
@@ -71,6 +72,7 @@ export function importMetaEnv({ envLoader }: EnvPluginOptions): vite.Plugin {
let isDev: boolean;
let devImportMetaEnvPrepend: string;
let viteConfig: vite.ResolvedConfig;
+ const filter = createFilter(null, ['**/*.html', '**/*.htm', '**/*.json']);
return {
name: 'astro:vite-plugin-env',
config(_, { command }) {
@@ -96,11 +98,17 @@ export function importMetaEnv({ envLoader }: EnvPluginOptions): vite.Plugin {
}
}
},
+
transform(source, id, options) {
- if (!options?.ssr || !source.includes('import.meta.env')) {
+ if (
+ !options?.ssr ||
+ !source.includes('import.meta.env') ||
+ !filter(id) ||
+ isCSSRequest(id) ||
+ viteConfig.assetsInclude(id)
+ ) {
return;
}
-
// Find matches for *private* env and do our own replacement.
// Env is retrieved before process.env is populated by astro:env
// so that import.meta.env is first replaced by values, not process.env
diff --git a/packages/astro/test/astro-envs.test.js b/packages/astro/test/astro-envs.test.js
index 94844fd54134..f1992ccb223f 100644
--- a/packages/astro/test/astro-envs.test.js
+++ b/packages/astro/test/astro-envs.test.js
@@ -120,5 +120,14 @@ describe('Environment Variables', () => {
let $ = cheerio.load(indexHtml);
assert.equal($('#base-url').text(), '/blog');
});
+
+ it('does not inject env into imported asset files', async () => {
+ let res = await fixture.fetch('/blog/');
+ assert.equal(res.status, 200);
+ let indexHtml = await res.text();
+ let $ = cheerio.load(indexHtml);
+ assert.equal($('#env').text(), 'A MYSTERY');
+ assert.equal($('#css').text(), 'good');
+ });
});
});
diff --git a/packages/astro/test/fixtures/astro-envs/.env b/packages/astro/test/fixtures/astro-envs/.env
index e0587fe3f785..ebdb27b14a97 100644
--- a/packages/astro/test/fixtures/astro-envs/.env
+++ b/packages/astro/test/fixtures/astro-envs/.env
@@ -1,2 +1,3 @@
SECRET_PLACE=CLUB_33
PUBLIC_PLACE=BLUE_BAYOU
+KITTY=CHESHIRE
diff --git a/packages/astro/test/fixtures/astro-envs/astro.config.mjs b/packages/astro/test/fixtures/astro-envs/astro.config.mjs
index 23862320116a..4b59505bc25c 100644
--- a/packages/astro/test/fixtures/astro-envs/astro.config.mjs
+++ b/packages/astro/test/fixtures/astro-envs/astro.config.mjs
@@ -6,4 +6,18 @@ export default defineConfig({
site: 'http://example.com',
base: '/blog',
integrations: [vue()],
+ vite: {
+ plugins: [
+ {
+ // Plugin so that we can see in the tests whether the env has been injected
+ name: 'export-env-plugin',
+ enforce: 'post',
+ transform(code, id) {
+ if (id.endsWith('.json')) {
+ return `${code}\n export const env = ${JSON.stringify(code.includes('CHESHIRE') || code.includes('process.env.KITTY') ? 'CHESHIRE' : 'A MYSTERY')}`;
+ }
+ },
+ },
+ ],
+ },
});
diff --git a/packages/astro/test/fixtures/astro-envs/src/data/cats.json b/packages/astro/test/fixtures/astro-envs/src/data/cats.json
new file mode 100644
index 000000000000..ef66d452bf1e
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-envs/src/data/cats.json
@@ -0,0 +1,27 @@
+{
+ "tiddles": {
+ "name": "Tiddles",
+ "age": 3,
+ "colour": "black"
+ },
+ "mittens": {
+ "name": "Mittens",
+ "age": 5,
+ "colour": "white"
+ },
+ "fluffy": {
+ "name": "Fluffy",
+ "age": 2,
+ "colour": "grey"
+ },
+ "whiskers": {
+ "name": "Whiskers",
+ "age": 4,
+ "colour": "tabby"
+ },
+ "bobby-env": {
+ "name": "import.meta.env.KITTY",
+ "age": 1,
+ "colour": "calico"
+ }
+}
diff --git a/packages/astro/test/fixtures/astro-envs/src/data/hello.css b/packages/astro/test/fixtures/astro-envs/src/data/hello.css
new file mode 100644
index 000000000000..090345a443b3
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-envs/src/data/hello.css
@@ -0,0 +1,4 @@
+/* Just mentioning import.meta.env is enough to trigger this */
+body {
+ background-color: red;
+}
diff --git a/packages/astro/test/fixtures/astro-envs/src/data/hi.md b/packages/astro/test/fixtures/astro-envs/src/data/hi.md
new file mode 100644
index 000000000000..44f75f692fbe
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-envs/src/data/hi.md
@@ -0,0 +1,7 @@
+---
+---
+import.meta.env.KITTEN
+
+```js
+console.log(import.meta.env.KITTEN)
+```
diff --git a/packages/astro/test/fixtures/astro-envs/src/pages/index.astro b/packages/astro/test/fixtures/astro-envs/src/pages/index.astro
index f56c3cbc135a..973686360d40 100644
--- a/packages/astro/test/fixtures/astro-envs/src/pages/index.astro
+++ b/packages/astro/test/fixtures/astro-envs/src/pages/index.astro
@@ -1,8 +1,13 @@
---
import Client from '../components/Client.vue';
+import css from '../data/hello.css?inline';
+const {env} = await import('../data/cats.json');
---
+
{import.meta.env.PUBLIC_PLACE}
{import.meta.env.SECRET_PLACE}
{import.meta.env.SITE}
{import.meta.env.BASE_URL}
+{env}
+{css.includes('SECRET_PLACE') ? 'bad' : 'good' }
diff --git a/packages/astro/test/fixtures/astro-envs/src/pages/info.html b/packages/astro/test/fixtures/astro-envs/src/pages/info.html
new file mode 100644
index 000000000000..400f3fd6c8a9
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-envs/src/pages/info.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Document
+
+
+
+ Did you know import.meta.env is a magic word?
+
+
+
\ No newline at end of file