mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
Fix script injection during build (#12392)
Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
This commit is contained in:
parent
3b3bc9b8cd
commit
0462219612
5 changed files with 48 additions and 37 deletions
5
.changeset/slimy-pets-lick.md
Normal file
5
.changeset/slimy-pets-lick.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fixes an issue where scripts were not correctly injected during the build. The issue was triggered when there were injected routes with the same `entrypoint` and different `pattern`
|
|
@ -32,7 +32,7 @@ export function registerAllPlugins({ internals, options, register }: AstroBuildP
|
||||||
if (options.settings.config.experimental.directRenderScript) {
|
if (options.settings.config.experimental.directRenderScript) {
|
||||||
register(pluginScripts(internals));
|
register(pluginScripts(internals));
|
||||||
} else {
|
} else {
|
||||||
register(pluginHoistedScripts(options, internals));
|
register(pluginHoistedScripts(internals));
|
||||||
}
|
}
|
||||||
register(pluginSSR(options, internals));
|
register(pluginSSR(options, internals));
|
||||||
register(pluginSSRSplit(options, internals));
|
register(pluginSSRSplit(options, internals));
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import type { BuildOptions, Rollup, Plugin as VitePlugin } from 'vite';
|
import type { BuildOptions, Rollup, Plugin as VitePlugin } from 'vite';
|
||||||
import type { AstroSettings } from '../../../@types/astro.js';
|
|
||||||
import { viteID } from '../../util.js';
|
|
||||||
import type { BuildInternals } from '../internal.js';
|
import type { BuildInternals } from '../internal.js';
|
||||||
import { getPageDataByViteID } from '../internal.js';
|
import { getPageDatasByHoistedScriptId } from '../internal.js';
|
||||||
import type { AstroBuildPlugin } from '../plugin.js';
|
import type { AstroBuildPlugin } from '../plugin.js';
|
||||||
import type { StaticBuildOptions } from '../types.js';
|
|
||||||
import { shouldInlineAsset } from './util.js';
|
import { shouldInlineAsset } from './util.js';
|
||||||
|
|
||||||
function virtualHoistedEntry(id: string) {
|
function virtualHoistedEntry(id: string) {
|
||||||
|
@ -12,7 +9,6 @@ function virtualHoistedEntry(id: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function vitePluginHoistedScripts(
|
export function vitePluginHoistedScripts(
|
||||||
settings: AstroSettings,
|
|
||||||
internals: BuildInternals,
|
internals: BuildInternals,
|
||||||
): VitePlugin {
|
): VitePlugin {
|
||||||
let assetsInlineLimit: NonNullable<BuildOptions['assetsInlineLimit']>;
|
let assetsInlineLimit: NonNullable<BuildOptions['assetsInlineLimit']>;
|
||||||
|
@ -73,23 +69,18 @@ export function vitePluginHoistedScripts(
|
||||||
shouldInlineAsset(output.code, output.fileName, assetsInlineLimit);
|
shouldInlineAsset(output.code, output.fileName, assetsInlineLimit);
|
||||||
let removeFromBundle = false;
|
let removeFromBundle = false;
|
||||||
const facadeId = output.facadeModuleId!;
|
const facadeId = output.facadeModuleId!;
|
||||||
const pages = internals.hoistedScriptIdToPagesMap.get(facadeId)!;
|
for (const pageData of getPageDatasByHoistedScriptId(internals, facadeId)) {
|
||||||
for (const pathname of pages) {
|
if (canBeInlined) {
|
||||||
const vid = viteID(new URL('.' + pathname, settings.config.root));
|
pageData.hoistedScript = {
|
||||||
const pageInfo = getPageDataByViteID(internals, vid);
|
type: 'inline',
|
||||||
if (pageInfo) {
|
value: output.code,
|
||||||
if (canBeInlined) {
|
};
|
||||||
pageInfo.hoistedScript = {
|
removeFromBundle = true;
|
||||||
type: 'inline',
|
} else {
|
||||||
value: output.code,
|
pageData.hoistedScript = {
|
||||||
};
|
type: 'external',
|
||||||
removeFromBundle = true;
|
value: id,
|
||||||
} else {
|
};
|
||||||
pageInfo.hoistedScript = {
|
|
||||||
type: 'external',
|
|
||||||
value: id,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +94,6 @@ export function vitePluginHoistedScripts(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pluginHoistedScripts(
|
export function pluginHoistedScripts(
|
||||||
options: StaticBuildOptions,
|
|
||||||
internals: BuildInternals,
|
internals: BuildInternals,
|
||||||
): AstroBuildPlugin {
|
): AstroBuildPlugin {
|
||||||
return {
|
return {
|
||||||
|
@ -111,7 +101,7 @@ export function pluginHoistedScripts(
|
||||||
hooks: {
|
hooks: {
|
||||||
'build:before': () => {
|
'build:before': () => {
|
||||||
return {
|
return {
|
||||||
vitePlugin: vitePluginHoistedScripts(options.settings, internals),
|
vitePlugin: vitePluginHoistedScripts(internals),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
---
|
---
|
||||||
---
|
---
|
||||||
<html lang="en">
|
<h1>to-inject.astro</h1>
|
||||||
<head>
|
<script>
|
||||||
<meta charset="utf-8" />
|
console.log('to-inject.astro');
|
||||||
<meta name="viewport" content="width=device-width" />
|
</script>
|
||||||
<title>Routing</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>to-inject.astro</h1>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -13,11 +13,13 @@ const routes = [
|
||||||
description: 'matches /injected-a to to-inject.astro',
|
description: 'matches /injected-a to to-inject.astro',
|
||||||
url: '/injected-a',
|
url: '/injected-a',
|
||||||
h1: 'to-inject.astro',
|
h1: 'to-inject.astro',
|
||||||
|
scriptContent: 'console.log("to-inject.astro");',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: 'matches /injected-b to to-inject.astro',
|
description: 'matches /injected-b to to-inject.astro',
|
||||||
url: '/injected-b',
|
url: '/injected-b',
|
||||||
h1: 'to-inject.astro',
|
h1: 'to-inject.astro',
|
||||||
|
scriptContent: 'console.log("to-inject.astro");',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: 'matches /dynamic-a/id-1 to [id].astro',
|
description: 'matches /dynamic-a/id-1 to [id].astro',
|
||||||
|
@ -60,7 +62,7 @@ describe('Reuse injected entrypoint', () => {
|
||||||
await fixture.build();
|
await fixture.build();
|
||||||
});
|
});
|
||||||
|
|
||||||
routes.forEach(({ description, url, fourOhFour, h1, p, htmlMatch }) => {
|
routes.forEach(({ description, url, fourOhFour, h1, p, htmlMatch, scriptContent }) => {
|
||||||
const isEndpoint = htmlMatch && !h1 && !p;
|
const isEndpoint = htmlMatch && !h1 && !p;
|
||||||
|
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
|
@ -85,6 +87,15 @@ describe('Reuse injected entrypoint', () => {
|
||||||
if (htmlMatch) {
|
if (htmlMatch) {
|
||||||
assert.equal(html, htmlMatch);
|
assert.equal(html, htmlMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scriptContent) {
|
||||||
|
const scriptTags = $('script[type="module"]').toArray();
|
||||||
|
const scriptFound = scriptTags.some((script) => {
|
||||||
|
const scriptText = $(script).text();
|
||||||
|
return scriptText.includes(scriptContent.trim());
|
||||||
|
});
|
||||||
|
assert(scriptFound, `Expected script content to be injected in SSG ${url}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -105,7 +116,7 @@ describe('Reuse injected entrypoint', () => {
|
||||||
await devServer.stop();
|
await devServer.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
routes.forEach(({ description, url, fourOhFour, h1, p, htmlMatch }) => {
|
routes.forEach(({ description, url, fourOhFour, h1, p, htmlMatch, scriptContent }) => {
|
||||||
// checks URLs as written above
|
// checks URLs as written above
|
||||||
it(description, async () => {
|
it(description, async () => {
|
||||||
const html = await fixture.fetch(url).then((res) => res.text());
|
const html = await fixture.fetch(url).then((res) => res.text());
|
||||||
|
@ -127,6 +138,17 @@ describe('Reuse injected entrypoint', () => {
|
||||||
if (htmlMatch) {
|
if (htmlMatch) {
|
||||||
assert.equal(html, htmlMatch);
|
assert.equal(html, htmlMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scriptContent) {
|
||||||
|
const scriptTags = $('script[type="module"]').toArray();
|
||||||
|
const scriptFound = scriptTags.some((script) => {
|
||||||
|
const scriptSrc = $(script).attr('src');
|
||||||
|
return (
|
||||||
|
scriptSrc && scriptSrc.includes('/to-inject.astro?astro&type=script&index=0&lang.ts')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
assert(scriptFound, `Expected script content to be injected in dev ${url}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue