aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/astro/src/core/app/index.ts23
-rw-r--r--packages/astro/src/core/app/types.ts8
-rw-r--r--packages/astro/src/core/build/generate.ts12
-rw-r--r--packages/astro/src/core/build/static-build.ts10
-rw-r--r--packages/astro/src/core/build/types.ts3
-rw-r--r--packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts21
-rw-r--r--packages/astro/src/core/build/vite-plugin-ssr.ts2
-rw-r--r--packages/astro/src/core/render/ssr-element.ts20
-rw-r--r--packages/astro/test/astro-scripts.test.js13
9 files changed, 79 insertions, 33 deletions
diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts
index 81cfe106a..3847a4589 100644
--- a/packages/astro/src/core/app/index.ts
+++ b/packages/astro/src/core/app/index.ts
@@ -3,6 +3,7 @@ import type {
EndpointHandler,
ManifestData,
RouteData,
+ SSRElement,
} from '../../@types/astro';
import type { LogOptions } from '../logger/core.js';
import type { RouteInfo, SSRManifest as Manifest } from './types';
@@ -16,6 +17,7 @@ import { RouteCache } from '../render/route-cache.js';
import {
createLinkStylesheetElementSet,
createModuleScriptElementWithSrcSet,
+ createModuleScriptElement,
} from '../render/ssr-element.js';
import { matchRoute } from '../routing/match.js';
export { deserializeManifest } from './common.js';
@@ -79,18 +81,17 @@ export class App {
const info = this.#routeDataToRouteInfo.get(routeData!)!;
const links = createLinkStylesheetElementSet(info.links, manifest.site);
- const filteredScripts = info.scripts.filter(
- (script) => typeof script === 'string' || script?.stage !== 'head-inline'
- ) as string[];
- const scripts = createModuleScriptElementWithSrcSet(filteredScripts, manifest.site);
-
- // Add all injected scripts to the page.
+ let scripts = new Set<SSRElement>();
for (const script of info.scripts) {
- if (typeof script !== 'string' && script.stage === 'head-inline') {
- scripts.add({
- props: {},
- children: script.children,
- });
+ if (('stage' in script)) {
+ if(script.stage === 'head-inline') {
+ scripts.add({
+ props: {},
+ children: script.children,
+ });
+ }
+ } else {
+ scripts.add(createModuleScriptElement(script, manifest.site));
}
}
diff --git a/packages/astro/src/core/app/types.ts b/packages/astro/src/core/app/types.ts
index 7410ad42a..1bbfe3511 100644
--- a/packages/astro/src/core/app/types.ts
+++ b/packages/astro/src/core/app/types.ts
@@ -12,7 +12,13 @@ export interface RouteInfo {
routeData: RouteData;
file: string;
links: string[];
- scripts: Array<string | { children: string; stage: string }>;
+ scripts:
+ (
+ // Integration injected
+ { children: string; stage: string } |
+ // Hoisted
+ { type: 'inline' | 'external'; value: string; }
+ )[];
}
export type SerializedRouteInfo = Omit<RouteInfo, 'routeData'> & {
diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts
index 65f3930dd..f06aa3858 100644
--- a/packages/astro/src/core/build/generate.ts
+++ b/packages/astro/src/core/build/generate.ts
@@ -18,7 +18,7 @@ import { debug, info } from '../logger/core.js';
import { render } from '../render/core.js';
import {
createLinkStylesheetElementSet,
- createModuleScriptElementWithSrcSet,
+ createModuleScriptsSet,
} from '../render/ssr-element.js';
import { createRequest } from '../request.js';
import { getOutputFilename, isBuildingToSSR } from '../util.js';
@@ -114,7 +114,7 @@ async function generatePage(
const pageInfo = getPageDataByComponent(internals, pageData.route.component);
const linkIds: string[] = Array.from(pageInfo?.css ?? []);
- const hoistedId = pageInfo?.hoistedScript ?? null;
+ const scripts = pageInfo?.hoistedScript ?? null;
const pageModule = ssrEntry.pageMap.get(pageData.component);
@@ -128,7 +128,7 @@ async function generatePage(
pageData,
internals,
linkIds,
- hoistedId,
+ scripts,
mod: pageModule,
renderers,
};
@@ -152,7 +152,7 @@ interface GeneratePathOptions {
pageData: PageBuildData;
internals: BuildInternals;
linkIds: string[];
- hoistedId: string | null;
+ scripts: { type: 'inline' | 'external', value: string } | null;
mod: ComponentInstance;
renderers: SSRLoadedRenderer[];
}
@@ -167,7 +167,7 @@ async function generatePath(
gopts: GeneratePathOptions
) {
const { astroConfig, logging, origin, routeCache } = opts;
- const { mod, internals, linkIds, hoistedId, pageData, renderers } = gopts;
+ const { mod, internals, linkIds, scripts: hoistedScripts, pageData, renderers } = gopts;
// This adds the page name to the array so it can be shown as part of stats.
if (pageData.route.type === 'page') {
@@ -183,7 +183,7 @@ async function generatePath(
? joinPaths(astroConfig.site?.toString() || 'http://localhost/', astroConfig.base)
: astroConfig.site;
const links = createLinkStylesheetElementSet(linkIds.reverse(), site);
- const scripts = createModuleScriptElementWithSrcSet(hoistedId ? [hoistedId] : [], site);
+ const scripts = createModuleScriptsSet(hoistedScripts ? [hoistedScripts] : [], site);
// Add all injected scripts to the page.
for (const script of astroConfig._ctx.scripts) {
diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts
index 2300c790a..ba35241a6 100644
--- a/packages/astro/src/core/build/static-build.ts
+++ b/packages/astro/src/core/build/static-build.ts
@@ -120,8 +120,8 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
output: {
format: 'esm',
entryFileNames: opts.buildConfig.serverEntry,
- chunkFileNames: 'chunks/chunk.[hash].mjs',
- assetFileNames: 'assets/asset.[hash][extname]',
+ chunkFileNames: 'chunks/[name].[hash].mjs',
+ assetFileNames: 'assets/[name].[hash][extname]',
...viteConfig.build?.rollupOptions?.output,
},
},
@@ -205,9 +205,9 @@ async function clientBuild(
input: Array.from(input),
output: {
format: 'esm',
- entryFileNames: 'entry.[hash].js',
- chunkFileNames: 'chunks/chunk.[hash].js',
- assetFileNames: 'assets/asset.[hash][extname]',
+ entryFileNames: '[name].[hash].js',
+ chunkFileNames: 'chunks/[name].[hash].js',
+ assetFileNames: 'assets/[name].[hash][extname]',
...viteConfig.build?.rollupOptions?.output,
},
preserveEntrySignatures: 'exports-only',
diff --git a/packages/astro/src/core/build/types.ts b/packages/astro/src/core/build/types.ts
index 0d018be7d..4342da32e 100644
--- a/packages/astro/src/core/build/types.ts
+++ b/packages/astro/src/core/build/types.ts
@@ -19,8 +19,7 @@ export interface PageBuildData {
route: RouteData;
moduleSpecifier: string;
css: Set<string>;
- hoistedScript: string | undefined;
- scripts: Set<string>;
+ hoistedScript: { type: 'inline' | 'external', value: string } | undefined;
}
export type AllPagesData = Record<ComponentPath, PageBuildData>;
diff --git a/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts b/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts
index 0ac874fba..94900ccbf 100644
--- a/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts
+++ b/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts
@@ -40,6 +40,8 @@ export function vitePluginHoistedScripts(
},
async generateBundle(_options, bundle) {
+ let assetInlineLimit = astroConfig.vite?.build?.assetsInlineLimit || 4096;
+
// Find all page entry points and create a map of the entry point to the hashed hoisted script.
// This is used when we render so that we can add the script to the head.
for (const [id, output] of Object.entries(bundle)) {
@@ -48,15 +50,32 @@ export function vitePluginHoistedScripts(
output.facadeModuleId &&
virtualHoistedEntry(output.facadeModuleId)
) {
+ let removeFromBundle = false;
const facadeId = output.facadeModuleId!;
const pages = internals.hoistedScriptIdToPagesMap.get(facadeId)!;
for (const pathname of pages) {
const vid = viteID(new URL('.' + pathname, astroConfig.root));
const pageInfo = getPageDataByViteID(internals, vid);
if (pageInfo) {
- pageInfo.hoistedScript = id;
+ if(Buffer.byteLength(output.code) <= assetInlineLimit) {
+ pageInfo.hoistedScript = {
+ type: 'inline',
+ value: output.code
+ };
+ removeFromBundle = true;
+ } else {
+ pageInfo.hoistedScript = {
+ type: 'external',
+ value: id
+ };
+ }
}
}
+
+ // Remove the bundle if it was inlined
+ if(removeFromBundle) {
+ delete bundle[id];
+ }
}
}
},
diff --git a/packages/astro/src/core/build/vite-plugin-ssr.ts b/packages/astro/src/core/build/vite-plugin-ssr.ts
index 4fc1274c7..d0ee16503 100644
--- a/packages/astro/src/core/build/vite-plugin-ssr.ts
+++ b/packages/astro/src/core/build/vite-plugin-ssr.ts
@@ -125,7 +125,7 @@ function buildManifest(
const routes: SerializedRouteInfo[] = [];
for (const pageData of eachPageData(internals)) {
- const scripts = Array.from(pageData.scripts);
+ const scripts: SerializedRouteInfo['scripts'] = [];
if (pageData.hoistedScript) {
scripts.unshift(pageData.hoistedScript);
}
diff --git a/packages/astro/src/core/render/ssr-element.ts b/packages/astro/src/core/render/ssr-element.ts
index 628294f44..2788fdace 100644
--- a/packages/astro/src/core/render/ssr-element.ts
+++ b/packages/astro/src/core/render/ssr-element.ts
@@ -25,6 +25,19 @@ export function createLinkStylesheetElementSet(hrefs: string[], site?: string) {
return new Set<SSRElement>(hrefs.map((href) => createLinkStylesheetElement(href, site)));
}
+export function createModuleScriptElement(script: { type: 'inline' | 'external'; value: string; }, site?: string): SSRElement {
+ if(script.type === 'external') {
+ return createModuleScriptElementWithSrc(script.value, site);
+ } else {
+ return {
+ props: {
+ type: 'module',
+ },
+ children: script.value,
+ };
+ }
+}
+
export function createModuleScriptElementWithSrc(src: string, site?: string): SSRElement {
return {
props: {
@@ -41,3 +54,10 @@ export function createModuleScriptElementWithSrcSet(
): Set<SSRElement> {
return new Set<SSRElement>(srces.map((src) => createModuleScriptElementWithSrc(src, site)));
}
+
+export function createModuleScriptsSet(
+ scripts: { type: 'inline' | 'external'; value: string; }[],
+ site?: string
+): Set<SSRElement> {
+ return new Set<SSRElement>(scripts.map(script => createModuleScriptElement(script, site)));
+}
diff --git a/packages/astro/test/astro-scripts.test.js b/packages/astro/test/astro-scripts.test.js
index 90dba2997..fa969cfed 100644
--- a/packages/astro/test/astro-scripts.test.js
+++ b/packages/astro/test/astro-scripts.test.js
@@ -37,15 +37,16 @@ describe('Scripts (hoisted and not)', () => {
// Inline page
let inline = await fixture.readFile('/inline/index.html');
let $ = cheerio.load(inline);
+ let $el = $('script');
// test 1: Just one entry module
- expect($('script')).to.have.lengthOf(1);
+ expect($el).to.have.lengthOf(1);
// test 2: attr removed
- expect($('script').attr('data-astro')).to.equal(undefined);
+ expect($el.attr('data-astro')).to.equal(undefined);
- const entryURL = $('script').attr('src');
- const inlineEntryJS = await fixture.readFile(entryURL);
+ expect($el.attr('src')).to.equal(undefined);
+ const inlineEntryJS = $el.text();
// test 3: the JS exists
expect(inlineEntryJS).to.be.ok;
@@ -65,8 +66,8 @@ describe('Scripts (hoisted and not)', () => {
expect($('script')).to.have.lengthOf(2);
let el = $('script').get(1);
- let entryURL = $(el).attr('src');
- let externalEntryJS = await fixture.readFile(entryURL);
+ expect($(el).attr('src')).to.equal(undefined, 'This should have been inlined');
+ let externalEntryJS = $(el).text();
// test 2: the JS exists
expect(externalEntryJS).to.be.ok;