diff --git a/.changeset/sour-chairs-compare.md b/.changeset/sour-chairs-compare.md new file mode 100644 index 000000000000..f11972309883 --- /dev/null +++ b/.changeset/sour-chairs-compare.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Prevents inlining scripts if used by other chunks when using the `experimental.directRenderScript` option diff --git a/packages/astro/src/core/build/plugins/plugin-scripts.ts b/packages/astro/src/core/build/plugins/plugin-scripts.ts index effbdb684270..52a2e3c4a3e3 100644 --- a/packages/astro/src/core/build/plugins/plugin-scripts.ts +++ b/packages/astro/src/core/build/plugins/plugin-scripts.ts @@ -17,18 +17,31 @@ export function vitePluginScripts(internals: BuildInternals): VitePlugin { }, async generateBundle(_options, bundle) { - for (const [id, output] of Object.entries(bundle)) { + const outputs = Object.values(bundle); + + // Track ids that are imported by chunks so we don't inline scripts that are imported + const importedIds = new Set(); + for (const output of outputs) { + if (output.type === 'chunk') { + for (const id of output.imports) { + importedIds.add(id); + } + } + } + + for (const output of outputs) { // Try to inline scripts that don't import anything as is within the inline limit if ( output.type === 'chunk' && output.facadeModuleId && internals.discoveredScripts.has(output.facadeModuleId) && + !importedIds.has(output.fileName) && output.imports.length === 0 && output.dynamicImports.length === 0 && shouldInlineAsset(output.code, output.fileName, assetInlineLimit) ) { internals.inlinedScripts.set(output.facadeModuleId, output.code.trim()); - delete bundle[id]; + delete bundle[output.fileName]; } } }, diff --git a/packages/astro/test/fixtures/hoisted-imports/src/components/shared-scripts/A.astro b/packages/astro/test/fixtures/hoisted-imports/src/components/shared-scripts/A.astro new file mode 100644 index 000000000000..c1161dd81f81 --- /dev/null +++ b/packages/astro/test/fixtures/hoisted-imports/src/components/shared-scripts/A.astro @@ -0,0 +1 @@ + diff --git a/packages/astro/test/fixtures/hoisted-imports/src/components/shared-scripts/B.astro b/packages/astro/test/fixtures/hoisted-imports/src/components/shared-scripts/B.astro new file mode 100644 index 000000000000..967a4e295ab8 --- /dev/null +++ b/packages/astro/test/fixtures/hoisted-imports/src/components/shared-scripts/B.astro @@ -0,0 +1,4 @@ + diff --git a/packages/astro/test/fixtures/hoisted-imports/src/components/shared-scripts/script.ts b/packages/astro/test/fixtures/hoisted-imports/src/components/shared-scripts/script.ts new file mode 100644 index 000000000000..a3d42c010835 --- /dev/null +++ b/packages/astro/test/fixtures/hoisted-imports/src/components/shared-scripts/script.ts @@ -0,0 +1 @@ +console.log('shared-scripts'); diff --git a/packages/astro/test/fixtures/hoisted-imports/src/pages/no-inline-if-shared.astro b/packages/astro/test/fixtures/hoisted-imports/src/pages/no-inline-if-shared.astro new file mode 100644 index 000000000000..a62f6d26b125 --- /dev/null +++ b/packages/astro/test/fixtures/hoisted-imports/src/pages/no-inline-if-shared.astro @@ -0,0 +1,7 @@ +--- +import A from '../components/shared-scripts/A.astro' +import B from '../components/shared-scripts/B.astro' +--- + + + diff --git a/packages/astro/test/hoisted-imports.test.js b/packages/astro/test/hoisted-imports.test.js index 37d1c56be783..fba5d4b5e630 100644 --- a/packages/astro/test/hoisted-imports.test.js +++ b/packages/astro/test/hoisted-imports.test.js @@ -71,12 +71,21 @@ describe('Hoisted Imports', () => { assert.equal($('script').length, 1); }); - it('inlines if script is larger than vite.assetInlineLimit: 100', async () => { + it('does not inline if script is larger than vite.assetInlineLimit: 100', async () => { const html = await fixture.readFile('/no-inline/index.html'); const $ = cheerio.load(html); const scripts = $('script'); assert.equal(scripts.length, 1); assert.ok(scripts[0].attribs.src); }); + + it('does not inline if script it has shared chunks', async () => { + const html = await fixture.readFile('/no-inline-if-shared/index.html'); + const $ = cheerio.load(html); + const scripts = $('script'); + assert.equal(scripts.length, 2); + assert.ok(scripts[0].attribs.src); + assert.ok(scripts[1].attribs.src); + }); }); });