Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 48 additions & 36 deletions packages/astro/src/assets/vite-plugin-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,32 +117,35 @@ export default function assets({ settings }: { settings: AstroSettings }): vite.
},
load(id) {
if (id === resolvedVirtualModuleId) {
return /* ts */ `
export { getConfiguredImageService, isLocalService } from "astro/assets";
import { getImage as getImageInternal } from "astro/assets";
export { default as Image } from "astro/components/${imageComponentPrefix}Image.astro";
export { default as Picture } from "astro/components/${imageComponentPrefix}Picture.astro";
export { inferRemoteSize } from "astro/assets/utils/inferRemoteSize.js";

export const imageConfig = ${JSON.stringify({ ...settings.config.image, experimentalResponsiveImages: settings.config.experimental.responsiveImages })};
// 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(
settings.buildOutput === 'server'
? settings.config.build.client
: settings.config.outDir,
),
)});
export const assetsDir = /* #__PURE__ */ new URL(${JSON.stringify(
settings.config.build.assets,
)}, outDir);
export const getImage = async (options) => await getImageInternal(options, imageConfig);
`;
return {
code: /* ts */ `
export { getConfiguredImageService, isLocalService } from "astro/assets";
import { getImage as getImageInternal } from "astro/assets";
export { default as Image } from "astro/components/${imageComponentPrefix}Image.astro";
export { default as Picture } from "astro/components/${imageComponentPrefix}Picture.astro";
export { inferRemoteSize } from "astro/assets/utils/inferRemoteSize.js";

export const imageConfig = ${JSON.stringify({ ...settings.config.image, experimentalResponsiveImages: settings.config.experimental.responsiveImages })};
// 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(
settings.buildOutput === 'server'
? settings.config.build.client
: settings.config.outDir,
),
)});
export const assetsDir = /* #__PURE__ */ new URL(${JSON.stringify(
settings.config.build.assets,
)}, outDir);
export const getImage = async (options) => await getImageInternal(options, imageConfig);
`,
moduleType: 'js',
};
}
},
buildStart() {
Expand All @@ -151,7 +154,7 @@ export default function assets({ settings }: { settings: AstroSettings }): vite.
},
// In build, rewrite paths to ESM imported images in code to their final location
async renderChunk(code) {
const assetUrlRE = /__ASTRO_ASSET_IMAGE__([\w$]{8})__(?:_(.*?)__)?/g;
const assetUrlRE = /__ASTRO_ASSET_IMAGE__([\w$]+)__(?:_(.*?)__)?/g;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In rolldown hashes are not exactly 8 long


let match;
let s;
Expand Down Expand Up @@ -205,7 +208,7 @@ export default function assets({ settings }: { settings: AstroSettings }): vite.
return;
}

const emitFile = shouldEmitFile ? this.emitFile : undefined;
const emitFile = shouldEmitFile ? this.emitFile.bind(this) : undefined;
const imageMetadata = await emitESMImage(
id,
this.meta.watchMode,
Expand All @@ -223,22 +226,31 @@ export default function assets({ settings }: { settings: AstroSettings }): vite.
if (settings.config.experimental.svg && /\.svg$/.test(id)) {
const { contents, ...metadata } = imageMetadata;
// We know that the contents are present, as we only emit this property for SVG files
return makeSvgComponent(metadata, contents!, {
mode: settings.config.experimental.svg.mode,
});
return {
code: makeSvgComponent(metadata, contents!, {
mode: settings.config.experimental.svg.mode,
}),
moduleType: 'js',
};
}

// We can only reliably determine if an image is used on the server, as we need to track its usage throughout the entire build.
// Since you cannot use image optimization on the client anyway, it's safe to assume that if the user imported
// an image on the client, it should be present in the final build.
if (options?.ssr) {
return `export default ${getProxyCode(
imageMetadata,
settings.buildOutput === 'server',
)}`;
return {
code: `export default ${getProxyCode(
imageMetadata,
settings.buildOutput === 'server',
)}`,
moduleType: 'js',
};
} else {
globalThis.astroAsset.referencedImages.add(imageMetadata.fsPath);
return `export default ${JSON.stringify(imageMetadata)}`;
return {
code: `export default ${JSON.stringify(imageMetadata)}`,
moduleType: 'js',
};
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions packages/astro/src/core/build/plugins/plugin-prerender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ function getNonPrerenderOnlyChunks(bundle: Rollup.OutputBundle, internals: Build

nonPrerenderOnlyEntryChunks.add(chunk);
}
if (chunk.type === 'chunk' && chunk.isDynamicEntry) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a bug in Astro according to the patch file

nonPrerenderOnlyEntryChunks.add(chunk);
}
}

// From the `nonPrerenderedEntryChunks`, we crawl all the imports/dynamicImports to find all
Expand Down