Skip to content

Commit

Permalink
Prevent accidental CSS inclusion in dev (#7381)
Browse files Browse the repository at this point in the history
* Prevent accidental CSS inclusion in dev

* Use ssrTransformResult.deps instead

* Fix types

* Get dynamic deps too

* Handle virtual module deps

* Fix test on windows
  • Loading branch information
matthewp authored Jun 22, 2023
1 parent 32bde96 commit f359d77
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/tiny-lemons-sit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Prevent accidental inclusion of page CSS in dev mode
4 changes: 4 additions & 0 deletions packages/astro/src/core/module-loader/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export interface ModuleNode {
id: string | null;
url: string;
ssrModule: Record<string, any> | null;
ssrTransformResult: {
deps?: string[];
dynamicDeps?: string[];
} | null;
ssrError: Error | null;
importedModules: Set<ModuleNode>;
}
Expand Down
19 changes: 18 additions & 1 deletion packages/astro/src/core/render/dev/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export async function* crawlGraph(
continue;
}
if (id === entry.id) {
const urlDeps = getDepsFromEntry(entry);
scanned.add(id);
const entryIsStyle = isCSSRequest(id);

Expand Down Expand Up @@ -82,7 +83,7 @@ export async function* crawlGraph(
}
}
}
if (!isPropagationStoppingPoint) {
if (urlDeps.includes(urlId(importedModule.url)) && !isPropagationStoppingPoint) {
importedModules.add(importedModule);
}
}
Expand All @@ -100,3 +101,19 @@ export async function* crawlGraph(
yield* crawlGraph(loader, importedModule.id, false, scanned);
}
}

// Virtual modules URL should start with /@id/ but do not
function urlId(url: string) {
if (url.startsWith('astro:scripts')) {
return '/@id/' + url;
}
return url;
}

function getDepsFromEntry(entry: ModuleNode) {
let deps = entry.ssrTransformResult?.deps ?? [];
if(entry.ssrTransformResult?.dynamicDeps) {
return deps.concat(entry.ssrTransformResult.dynamicDeps);
}
return deps;
}
63 changes: 63 additions & 0 deletions packages/astro/test/units/dev/styles.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { expect } from 'chai';
import { fileURLToPath } from 'url';

import {
getStylesForURL
} from '../../../dist/core/render/dev/css.js';
import { viteID } from '../../../dist/core/util.js';

const root = new URL('../../fixtures/alias/', import.meta.url);

class TestLoader {
constructor(modules) {
this.modules = new Map(modules.map(m => [m.id, m]))
}
getModuleById(id) {
return this.modules.get(id);
}
getModulesByFile(id) {
return this.modules.has(id) ? [this.modules.get(id)] : [];
}
}

describe('Crawling graph for CSS', () => {
let loader;
before(() => {
const indexId = viteID(new URL('./src/pages/index.astro', root));
const aboutId = viteID(new URL('./src/pages/about.astro', root));
loader = new TestLoader([
{
id: indexId,
importedModules: [{
id: aboutId,
url: aboutId,
}, {
id: indexId + '?astro&style.css',
url: indexId + '?astro&style.css',
ssrModule: {}
}],
ssrTransformResult: {
deps: [indexId + '?astro&style.css']
}
},
{
id: aboutId,
importedModules: [{
id: aboutId + '?astro&style.css',
url: aboutId + '?astro&style.css',
ssrModule: {}
}],
ssrTransformResult: {
deps: [aboutId + '?astro&style.css']
}
}
]);
})

it('importedModules is checked against the child\'s importers', async () => {
// In dev mode, HMR modules tracked are added to importedModules. We use `importers`
// to verify that they are true importers.
const res = await getStylesForURL(new URL('./src/pages/index.astro', root), loader, 'development')
expect(res.urls.size).to.equal(1);
})
})

0 comments on commit f359d77

Please sign in to comment.