Skip to content
79 changes: 42 additions & 37 deletions packages/astro/src/content/vite-plugin-content-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,44 +80,48 @@ export function astroContentAssetPropagationPlugin({
server.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr] as RunnableDevEnvironment,
);
},
async transform(_, id) {
if (hasContentFlag(id, PROPAGATED_ASSET_FLAG)) {
const basePath = id.split('?')[0];
let stringifiedLinks: string, stringifiedStyles: string;
transform: {
filter: {
id: new RegExp(`(?:\\?|&)${PROPAGATED_ASSET_FLAG}(?:&|=|$)`),
},
async handler(_, id) {
if (hasContentFlag(id, PROPAGATED_ASSET_FLAG)) {
const basePath = id.split('?')[0];
let stringifiedLinks: string, stringifiedStyles: string;

// We can access the server in dev,
// so resolve collected styles and scripts here.
if (isAstroServerEnvironment(this.environment) && devModuleLoader) {
if (!devModuleLoader.getModuleById(basePath)?.ssrModule) {
await devModuleLoader.import(basePath);
}
const {
styles,
urls,
crawledFiles: styleCrawledFiles,
} = await getStylesForURL(basePath, devModuleLoader.getSSREnvironment());
// We can access the server in dev,
// so resolve collected styles and scripts here.
if (isAstroServerEnvironment(this.environment) && devModuleLoader) {
if (!devModuleLoader.getModuleById(basePath)?.ssrModule) {
await devModuleLoader.import(basePath);
}
const {
styles,
urls,
crawledFiles: styleCrawledFiles,
} = await getStylesForURL(basePath, devModuleLoader.getSSREnvironment());

// Register files we crawled to be able to retrieve the rendered styles and scripts,
// as when they get updated, we need to re-transform ourselves.
// We also only watch files within the user source code, as changes in node_modules
// are usually also ignored by Vite.
for (const file of styleCrawledFiles) {
if (!file.includes('node_modules')) {
this.addWatchFile(file);
// Register files we crawled to be able to retrieve the rendered styles and scripts,
// as when they get updated, we need to re-transform ourselves.
// We also only watch files within the user source code, as changes in node_modules
// are usually also ignored by Vite.
for (const file of styleCrawledFiles) {
if (!file.includes('node_modules')) {
this.addWatchFile(file);
}
}
}

stringifiedLinks = JSON.stringify([...urls]);
stringifiedStyles = JSON.stringify(styles.map((s) => s.content));
} else {
// Otherwise, use placeholders to inject styles and scripts
// during the production bundle step.
// @see the `astro:content-build-plugin` below.
stringifiedLinks = JSON.stringify(LINKS_PLACEHOLDER);
stringifiedStyles = JSON.stringify(STYLES_PLACEHOLDER);
}
stringifiedLinks = JSON.stringify([...urls]);
stringifiedStyles = JSON.stringify(styles.map((s) => s.content));
} else {
// Otherwise, use placeholders to inject styles and scripts
// during the production bundle step.
// @see the `astro:content-build-plugin` below.
stringifiedLinks = JSON.stringify(LINKS_PLACEHOLDER);
stringifiedStyles = JSON.stringify(STYLES_PLACEHOLDER);
}

const code = `
const code = `
async function getMod() {
return import(${JSON.stringify(basePath)});
}
Expand All @@ -126,10 +130,11 @@ export function astroContentAssetPropagationPlugin({
const defaultMod = { __astroPropagation: true, getMod, collectedLinks, collectedStyles, collectedScripts: [] };
export default defaultMod;
`;
// ^ Use a default export for tools like Markdoc
// to catch the `__astroPropagation` identifier
return { code, map: { mappings: '' } };
}
// ^ Use a default export for tools like Markdoc
// to catch the `__astroPropagation` identifier
return { code, map: { mappings: '' } };
}
},
},
};
}
Expand Down
102 changes: 58 additions & 44 deletions packages/astro/src/content/vite-plugin-content-imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,28 +91,32 @@ export function astroContentImportPlugin({
// Get symlinks once at build start
symlinks = await getSymlinkedContentCollections({ contentDir, logger, fs });
},
async transform(_, viteId) {
if (hasContentFlag(viteId, DATA_FLAG)) {
// By default, Vite will resolve symlinks to their targets. We need to reverse this for
// content entries, so we can get the path relative to the content directory.
const fileId = reverseSymlink({
entry: viteId.split('?')[0] ?? viteId,
contentDir,
symlinks,
});
// Data collections don't need to rely on the module cache.
// This cache only exists for the `render()` function specific to content.
const { id, data, collection, _internal } = await getDataEntryModule({
fileId,
entryConfigByExt: dataEntryConfigByExt,
contentDir,
config: settings.config,
fs,
pluginContext: this,
shouldEmitFile,
});

const code = `
transform: {
filter: {
id: new RegExp(`(?:\\?|&)(?:${DATA_FLAG}|${CONTENT_FLAG})(?:&|=|$)`),
},
async handler(_, viteId) {
if (hasContentFlag(viteId, DATA_FLAG)) {
// By default, Vite will resolve symlinks to their targets. We need to reverse this for
// content entries, so we can get the path relative to the content directory.
const fileId = reverseSymlink({
entry: viteId.split('?')[0] ?? viteId,
contentDir,
symlinks,
});
// Data collections don't need to rely on the module cache.
// This cache only exists for the `render()` function specific to content.
const { id, data, collection, _internal } = await getDataEntryModule({
fileId,
entryConfigByExt: dataEntryConfigByExt,
contentDir,
config: settings.config,
fs,
pluginContext: this,
shouldEmitFile,
});

const code = `
export const id = ${JSON.stringify(id)};
export const collection = ${JSON.stringify(collection)};
export const data = ${stringifyEntryData(data, settings.buildOutput === 'server')};
Expand All @@ -122,20 +126,20 @@ export const _internal = {
rawData: ${JSON.stringify(_internal.rawData)},
};
`;
return code;
} else if (hasContentFlag(viteId, CONTENT_FLAG)) {
const fileId = reverseSymlink({ entry: viteId.split('?')[0], contentDir, symlinks });
const { id, slug, collection, body, data, _internal } = await getContentEntryModule({
fileId,
entryConfigByExt: contentEntryConfigByExt,
contentDir,
config: settings.config,
fs,
pluginContext: this,
shouldEmitFile,
});

const code = `
return code;
} else if (hasContentFlag(viteId, CONTENT_FLAG)) {
const fileId = reverseSymlink({ entry: viteId.split('?')[0], contentDir, symlinks });
const { id, slug, collection, body, data, _internal } = await getContentEntryModule({
fileId,
entryConfigByExt: contentEntryConfigByExt,
contentDir,
config: settings.config,
fs,
pluginContext: this,
shouldEmitFile,
});

const code = `
export const id = ${JSON.stringify(id)};
export const collection = ${JSON.stringify(collection)};
export const slug = ${JSON.stringify(slug)};
Expand All @@ -147,8 +151,9 @@ export const _internal = {
rawData: ${JSON.stringify(_internal.rawData)},
};`;

return { code, map: { mappings: '' } };
}
return { code, map: { mappings: '' } };
}
},
},
configureServer(viteServer) {
viteServer.watcher.on('all', async (event, entry) => {
Expand Down Expand Up @@ -200,12 +205,21 @@ export const _internal = {
if (settings.contentEntryTypes.some((t) => t.getRenderModule)) {
plugins.push({
name: 'astro:content-render-imports',
async transform(contents, viteId) {
const contentRenderer = getContentRendererByViteId(viteId, settings);
if (!contentRenderer) return;

const fileId = viteId.split('?')[0];
return contentRenderer.bind(this)({ viteId, contents, fileUrl: pathToFileURL(fileId) });
transform: {
filter: {
id: {
include: settings.contentEntryTypes
.filter((t) => t.getRenderModule)
.map((t) => new RegExp(`\\.(${t.extensions.map((e) => e.slice(1)).join('|')})$`)),
},
},
async handler(contents, viteId) {
const contentRenderer = getContentRendererByViteId(viteId, settings);
if (!contentRenderer) return;

const fileId = viteId.split('?')[0];
return contentRenderer.bind(this)({ viteId, contents, fileUrl: pathToFileURL(fileId) });
},
},
});
}
Expand Down
10 changes: 7 additions & 3 deletions packages/astro/src/core/build/plugins/plugin-css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { getPageDataByViteID, getPageDatasByClientOnlyID } from '../internal.js'
import type { PageBuildData, StaticBuildOptions, StylesheetAsset } from '../types.js';
import { shouldInlineAsset } from './util.js';
import { ASTRO_VITE_ENVIRONMENT_NAMES } from '../../constants.js';
import { CSS_LANGS_RE } from '../../viteUtils.js';

/***** ASTRO PLUGIN *****/

Expand Down Expand Up @@ -53,8 +54,11 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
);
},

transform(_code, id) {
if (isCSSRequest(id)) {
transform: {
filter: {
id: CSS_LANGS_RE,
},
handler(_code, id) {
// In prerender, don't rebundle CSS that was already bundled in SSR.
// Return an empty string here to prevent it.
if (this.environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.prerender) {
Expand All @@ -65,7 +69,7 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
}
}
cssModulesInBundles.add(id);
}
},
},

async generateBundle(_outputOptions, bundle) {
Expand Down
Loading