diff --git a/.changeset/thin-impalas-cry.md b/.changeset/thin-impalas-cry.md new file mode 100644 index 000000000000..be591d72b3db --- /dev/null +++ b/.changeset/thin-impalas-cry.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Fixes bug where server builds would include unneeded assets in SSR Function, potentially leading to upload errors on Vercel, Netlify because of size limits diff --git a/packages/astro/src/assets/vite-plugin-assets.ts b/packages/astro/src/assets/vite-plugin-assets.ts index db1a6e705d7a..563874a56183 100644 --- a/packages/astro/src/assets/vite-plugin-assets.ts +++ b/packages/astro/src/assets/vite-plugin-assets.ts @@ -68,14 +68,20 @@ export default function assets({ export { default as Picture } from "astro/components/Picture.astro"; export const imageConfig = ${JSON.stringify(settings.config.image)}; - export const outDir = new URL(${JSON.stringify( + // This is used by the @astrojs/node integration to locate images. + // It's unused on other platforms, but on some platforms like Netlify (and presumably also Vercel) + // new URL("dist/...") is interpreted by the bundler as a signal to include that directory + // in the Lambda bundle, which would bloat the bundle with images. + // To prevent this, we mark the URL construction as pure, + // so that it's tree-shaken away for all platforms that don't need it. + export const outDir = /* #__PURE__ */ new URL(${JSON.stringify( new URL( isServerLikeOutput(settings.config) ? settings.config.build.client : settings.config.outDir ) )}); - export const assetsDir = new URL(${JSON.stringify(settings.config.build.assets)}, outDir); + export const assetsDir = /* #__PURE__ */ new URL(${JSON.stringify(settings.config.build.assets)}, outDir); export const getImage = async (options) => await getImageInternal(options, imageConfig); `; } diff --git a/packages/integrations/vercel/test/serverless-prerender.test.js b/packages/integrations/vercel/test/serverless-prerender.test.js index 475df477fe50..36feed021b63 100644 --- a/packages/integrations/vercel/test/serverless-prerender.test.js +++ b/packages/integrations/vercel/test/serverless-prerender.test.js @@ -18,6 +18,18 @@ describe('Serverless prerender', () => { assert.ok(await fixture.readFile('../.vercel/output/static/index.html')); }); + it('outDir is tree-shaken if not needed', async () => { + const [file] = await fixture.glob( + '../.vercel/output/functions/_render.func/packages/integrations/vercel/test/fixtures/serverless-prerender/.vercel/output/_functions/chunks/pages/generic_*.mjs' + ); + const contents = await fixture.readFile(file); + console.log(contents) + assert.ok( + !contents.includes('const outDir ='), + "outDir is tree-shaken if it's not imported" + ); + }); + // TODO: The path here seems to be inconsistent? it.skip('includeFiles work', async () => { assert.ok(