From 9637014b1495a5a41cb384c7de4de410348f4cc0 Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Fri, 17 May 2024 18:11:32 +0800 Subject: [PATCH] Fix hoisted scripts propagation (#11084) --- .changeset/hungry-phones-melt.md | 5 +++++ .../src/core/build/plugins/plugin-analyzer.ts | 7 ++++++- .../astro/test/content-collections.test.js | 19 +++++++++++++++++ .../src/components/ScriptCompA.astro | 1 + .../src/components/ScriptCompB.astro | 1 + .../src/content/with-scripts/one.mdx | 7 +++++++ .../src/pages/with-scripts/[...slug].astro | 21 +++++++++++++++++++ 7 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 .changeset/hungry-phones-melt.md create mode 100644 packages/astro/test/fixtures/content-collections/src/components/ScriptCompA.astro create mode 100644 packages/astro/test/fixtures/content-collections/src/components/ScriptCompB.astro create mode 100644 packages/astro/test/fixtures/content-collections/src/content/with-scripts/one.mdx create mode 100644 packages/astro/test/fixtures/content-collections/src/pages/with-scripts/[...slug].astro diff --git a/.changeset/hungry-phones-melt.md b/.changeset/hungry-phones-melt.md new file mode 100644 index 000000000000..eb01a31f53b3 --- /dev/null +++ b/.changeset/hungry-phones-melt.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Fixes regression when handling hoisted scripts from content collections diff --git a/packages/astro/src/core/build/plugins/plugin-analyzer.ts b/packages/astro/src/core/build/plugins/plugin-analyzer.ts index e91820fb9315..83d8b9cdc3f4 100644 --- a/packages/astro/src/core/build/plugins/plugin-analyzer.ts +++ b/packages/astro/src/core/build/plugins/plugin-analyzer.ts @@ -54,7 +54,12 @@ export function vitePluginAnalyzer( if (hoistedScripts.size) { for (const parentInfo of getParentModuleInfos(from, this, isPropagatedAsset)) { if (isPropagatedAsset(parentInfo.id)) { - internals.propagatedScriptsMap.set(parentInfo.id, hoistedScripts); + for (const hid of hoistedScripts) { + if (!internals.propagatedScriptsMap.has(parentInfo.id)) { + internals.propagatedScriptsMap.set(parentInfo.id, new Set()); + } + internals.propagatedScriptsMap.get(parentInfo.id)?.add(hid); + } } else if (moduleIsTopLevelPage(parentInfo)) { for (const hid of hoistedScripts) { if (!pageScripts.has(parentInfo.id)) { diff --git a/packages/astro/test/content-collections.test.js b/packages/astro/test/content-collections.test.js index 29ad26a2f1d9..b7f5abb07cec 100644 --- a/packages/astro/test/content-collections.test.js +++ b/packages/astro/test/content-collections.test.js @@ -145,6 +145,25 @@ describe('Content Collections', () => { }); }); }); + + describe('Hoisted scripts', () => { + it('Contains all the scripts imported by components', async () => { + const html = await fixture.readFile('/with-scripts/one/index.html'); + const $ = cheerio.load(html); + // NOTE: Hoisted scripts have two tags currently but could be optimized as one. However, we're moving towards + // `experimental.directRenderScript` so this optimization isn't a priority at the moment. + assert.equal($('script').length, 2); + // Read the scripts' content + const scripts = $('script') + .map((_, el) => $(el).attr('src')) + .toArray(); + const scriptsCode = ( + await Promise.all(scripts.map(async (src) => await fixture.readFile(src))) + ).join('\n'); + assert.match(scriptsCode, /ScriptCompA/); + assert.match(scriptsCode, /ScriptCompB/); + }); + }); }); const blogSlugToContents = { diff --git a/packages/astro/test/fixtures/content-collections/src/components/ScriptCompA.astro b/packages/astro/test/fixtures/content-collections/src/components/ScriptCompA.astro new file mode 100644 index 000000000000..8b1e7dff1638 --- /dev/null +++ b/packages/astro/test/fixtures/content-collections/src/components/ScriptCompA.astro @@ -0,0 +1 @@ + diff --git a/packages/astro/test/fixtures/content-collections/src/components/ScriptCompB.astro b/packages/astro/test/fixtures/content-collections/src/components/ScriptCompB.astro new file mode 100644 index 000000000000..e133a2f51895 --- /dev/null +++ b/packages/astro/test/fixtures/content-collections/src/components/ScriptCompB.astro @@ -0,0 +1 @@ + diff --git a/packages/astro/test/fixtures/content-collections/src/content/with-scripts/one.mdx b/packages/astro/test/fixtures/content-collections/src/content/with-scripts/one.mdx new file mode 100644 index 000000000000..049a25a37791 --- /dev/null +++ b/packages/astro/test/fixtures/content-collections/src/content/with-scripts/one.mdx @@ -0,0 +1,7 @@ +import ScriptCompA from '../../components/ScriptCompA.astro' +import ScriptCompB from '../../components/ScriptCompB.astro' + +Both scripts should exist. + + + diff --git a/packages/astro/test/fixtures/content-collections/src/pages/with-scripts/[...slug].astro b/packages/astro/test/fixtures/content-collections/src/pages/with-scripts/[...slug].astro new file mode 100644 index 000000000000..893cbb9c61ff --- /dev/null +++ b/packages/astro/test/fixtures/content-collections/src/pages/with-scripts/[...slug].astro @@ -0,0 +1,21 @@ +--- +import { getCollection } from 'astro:content'; + +export async function getStaticPaths() { + const blogEntries = await getCollection('with-scripts'); + return blogEntries.map(entry => ({ + params: { slug: entry.slug }, props: { entry }, + })); +} + +const { entry } = Astro.props; + +const { Content } = await entry.render(); +const { title } = entry.data; +--- + +
+

This is a content collection post

+

{title}

+ +