Repository: withastro/astro
File: packages/astro/src/vite-plugin-astro/index.ts (TypeScript)

Code before:
			if (hasSpecialQueries(id)) return;

			const parsedId = parseAstroRequest(id);
			// ignore astro file sub-requests, e.g. Foo.astro?astro&type=script&index=0&lang.ts
			if (!parsedId.filename.endsWith('.astro') || parsedId.query.astro) {
				// Special edge case handling for Vite 6 beta, the style dependencies need to be registered here take affect
				// TODO: Remove this when Vite fixes it (https://github.com/vitejs/vite/pull/18103)
				if (this.environment.name === 'client') {
					const astroFilename = normalizePath(normalizeFilename(parsedId.filename, config.root));
					const compileMetadata = astroFileToCompileMetadata.get(astroFilename);
					if (compileMetadata && parsedId.query.type === 'style' && parsedId.query.index != null) {
						const result = compileMetadata.css[parsedId.query.index];

						// Register dependencies from preprocessing this style
						result.dependencies?.forEach((dep) => this.addWatchFile(dep));
					}
				}

				return;
			}

			// If an Astro component is imported in code used on the client, we return an empty
			// module so that Vite doesn’t bundle the server-side Astro code for the client.
			if (!options?.ssr) {
				return {
					code: 'export default {}',
					meta: { vite: { lang: 'ts' } },
				};
			}

			const filename = normalizePath(parsedId.filename);
			const transformResult = await compile(source, filename);

			const astroMetadata: AstroPluginMetadata['astro'] = {
				// Remove Astro components that have been mistakenly given client directives
				// We'll warn the user about this later, but for now we'll prevent them from breaking the build
				clientOnlyComponents: transformResult.clientOnlyComponents.filter(notAstroComponent),
				hydratedComponents: transformResult.hydratedComponents.filter(notAstroComponent),
				serverComponents: transformResult.serverComponents,
				scripts: transformResult.scripts,
				containsHead: transformResult.containsHead,
				propagation: transformResult.propagation ? 'self' : 'none',
				pageOptions: {},
			};

			return {
				code: transformResult.code,
				map: transformResult.map,
				meta: {
					astro: astroMetadata,
					vite: {

Review comment (bug):
@ematipico asked on Discord why we shouldn’t return a function that throws an error here, which is a good question and was the first thing I tried.

I’m not 100% sure why, but when doing something like `export default () => { throw new Error('...') }`, this error was _always_ thrown on the client. I guess Astro tries to call these for some reason if the export is a function?

Code after:
			if (hasSpecialQueries(id)) return;

			const parsedId = parseAstroRequest(id);
			// ignore astro file sub-requests, e.g. Foo.astro?astro&type=script&index=0&lang.ts
			if (!parsedId.filename.endsWith('.astro') || parsedId.query.astro) {
				// Special edge case handling for Vite 6 beta, the style dependencies need to be registered here take affect
				// TODO: Remove this when Vite fixes it (https://github.com/vitejs/vite/pull/18103)
				if (this.environment.name === 'client') {
					const astroFilename = normalizePath(normalizeFilename(parsedId.filename, config.root));
					const compileMetadata = astroFileToCompileMetadata.get(astroFilename);
					if (compileMetadata && parsedId.query.type === 'style' && parsedId.query.index != null) {
						const result = compileMetadata.css[parsedId.query.index];

						// Register dependencies from preprocessing this style
						result.dependencies?.forEach((dep) => this.addWatchFile(dep));
					}
				}

				return;
			}

			const filename = normalizePath(parsedId.filename);

			// If an Astro component is imported in code used on the client, we return an empty
			// module so that Vite doesn’t bundle the server-side Astro code for the client.
			if (!options?.ssr) {
				return {
					code: `export default import.meta.env.DEV
									? () => {
											throw new Error(
												'Astro components cannot be used in the browser.\\nTried to render "${filename}".'
											);
										}
									: {};`,
					meta: { vite: { lang: 'ts' } },
				};
			}

			const transformResult = await compile(source, filename);

			const astroMetadata: AstroPluginMetadata['astro'] = {
				// Remove Astro components that have been mistakenly given client directives
				// We'll warn the user about this later, but for now we'll prevent them from breaking the build
				clientOnlyComponents: transformResult.clientOnlyComponents.filter(notAstroComponent),
				hydratedComponents: transformResult.hydratedComponents.filter(notAstroComponent),
				serverComponents: transformResult.serverComponents,
				scripts: transformResult.scripts,
				containsHead: transformResult.containsHead,
				propagation: transformResult.propagation ? 'self' : 'none',
				pageOptions: {},
			};