Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 5 additions & 0 deletions .changeset/dirty-friends-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/cloudflare': patch
---

Reverts a change to the esbuild dep-scan plugin that caused `astro check` and `astro build` to fail by making esbuild incorrectly bundle `virtual:` modules (e.g. from expressive-code)
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { readFile } from 'node:fs/promises';
import { dirname, isAbsolute, resolve } from 'node:path';
import type { DepOptimizationConfig } from 'vite';

const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---/;
Expand All @@ -17,8 +16,6 @@ function replaceTopLevelReturns(code: string): string {
});
}

const ASTRO_FRONTMATTER_NAMESPACE = 'astro-frontmatter';

// Not exposed as a type from Vite, so need to grab this way.
type ESBuildPlugin = NonNullable<
NonNullable<DepOptimizationConfig['esbuildOptions']>['plugins']
Expand All @@ -28,56 +25,45 @@ type ESBuildPlugin = NonNullable<
* An esbuild plugin that extracts frontmatter from .astro files during
* dependency optimization scanning. This allows Vite to discover imports
* in the server-side frontmatter code.
*
* This plugin uses an `onResolve` handler to intercept `.astro` files before
* Vite's built-in `vite:dep-scan` plugin routes them to the `html` namespace.
* Without this, Vite's scanner only extracts `<script>` tags from `.astro`
* files, completely missing frontmatter imports (which is where SSR-side
* dependencies like `zod`, `nanostores`, `astro:transitions`, etc. live).
*/
export function astroFrontmatterScanPlugin(): ESBuildPlugin {
return {
name: 'astro-frontmatter-scan',
setup(build) {
// Intercept .astro file resolution to route them through our namespace
// before Vite's `vite:dep-scan` plugin puts them in the `html` namespace.
// In esbuild, plugins are processed in order and the first `onResolve`
// match wins. Since user plugins (including this one) are registered before
// Vite's scanner plugin, this handler takes priority.
build.onResolve({ filter: /\.astro$/ }, (args) => {
// Only intercept files in the default namespace. Files already in a
// custom namespace are either already claimed or are re-entry points
// that should not be processed again.
if (args.namespace !== 'file' && args.namespace !== '' && args.namespace !== undefined) {
return undefined;
}
const resolvedPath = isAbsolute(args.path)
? args.path
: resolve(args.resolveDir, args.path);
return { path: resolvedPath, namespace: ASTRO_FRONTMATTER_NAMESPACE };
});

build.onLoad({ filter: /\.astro$/, namespace: ASTRO_FRONTMATTER_NAMESPACE }, async (args) => {
// Scope to the "file" namespace so that .astro files resolved into the
// "html" namespace (e.g. when a .ts file default-imports a component)
// fall through to Vite's built-in html-type handler, which appends
// `export default {}` and avoids "No matching export" errors.
build.onLoad({ filter: /\.astro$/, namespace: 'file' }, async (args) => {
try {
const code = await readFile(args.path, 'utf-8');

// Extract frontmatter content between --- markers
const frontmatterMatch = FRONTMATTER_RE.exec(code);
if (frontmatterMatch) {
// Replace `return` with `throw` to avoid esbuild's "Top-level return" error during scanning.
// This aligns with Astro's core compiler logic for frontmatter error handling.
// See: packages/astro/src/vite-plugin-astro/compile.ts
const contents = replaceTopLevelReturns(frontmatterMatch[1]);

// Append `export default {}` so that default imports of .astro files
// (e.g. `import MyComponent from './MyComponent.astro'`) resolve correctly
// during the dep scan. Without this, .astro files loaded in the `html`
// namespace (when imported from .ts files) would have no default export,
// causing esbuild to fail with "No matching export for import 'default'".
return {
contents: contents + '\nexport default {}',
loader: 'ts',
resolveDir: dirname(args.path),
};
}
} catch {
// Ignore read errors
}

// No frontmatter or read error, return empty with a default export
return {
contents: 'export default {}',
loader: 'ts',
resolveDir: dirname(args.path),
};
});
},
Expand Down
6 changes: 0 additions & 6 deletions packages/integrations/cloudflare/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,6 @@ export default function createIntegration({
'astro/jsx-runtime',
'astro/app/entrypoint/dev',
'astro/virtual-modules/middleware.js',
'astro/virtual-modules/transitions.js',
'astro/virtual-modules/transitions-router.js',
'astro/virtual-modules/transitions-types.js',
'astro/virtual-modules/transitions-events.js',
'astro/virtual-modules/transitions-swap-functions.js',
...(isAstroPrismPackageInstalled ? prismFiles : []),
],
exclude: [
Expand All @@ -301,7 +296,6 @@ export default function createIntegration({
'virtual:@astrojs/*',
'@astrojs/starlight',
],
ignoreOutdatedRequests: true,
esbuildOptions: {
// Suppress Vite's `createRequire(import.meta.url)` banner to work around
// https://github.com/vitejs/vite/issues/22004 — Vite's SSR transform
Expand Down
149 changes: 0 additions & 149 deletions packages/integrations/cloudflare/test/dev-ssr-optimization.test.ts

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

13 changes: 0 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading