diff --git a/.changeset/orange-boats-refuse.md b/.changeset/orange-boats-refuse.md new file mode 100644 index 000000000000..6feb31b812a2 --- /dev/null +++ b/.changeset/orange-boats-refuse.md @@ -0,0 +1,5 @@ +--- +'@astrojs/cloudflare': patch +--- + +Fixes an issue where `esbuild` would throw a "Top-level return cannot be used inside an ECMAScript module" error during dependency scanning in certain environments. diff --git a/packages/integrations/cloudflare/src/esbuild-plugin-astro-frontmatter.ts b/packages/integrations/cloudflare/src/esbuild-plugin-astro-frontmatter.ts index 1256737c770d..44fbc3739d20 100644 --- a/packages/integrations/cloudflare/src/esbuild-plugin-astro-frontmatter.ts +++ b/packages/integrations/cloudflare/src/esbuild-plugin-astro-frontmatter.ts @@ -24,9 +24,16 @@ export function astroFrontmatterScanPlugin(): ESBuildPlugin { // Extract frontmatter content between --- markers const frontmatterMatch = FRONTMATTER_RE.exec(code); if (frontmatterMatch) { - // Return the frontmatter as TypeScript for import scanning + // 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 + // + // Known Limitation: Using regex /\breturn\b/ will incorrectly match + // identifiers like `$return` or aliases like `import { return as ret }`. + const contents = frontmatterMatch[1].replace(/\breturn\b/g, 'throw '); + return { - contents: frontmatterMatch[1], + contents, loader: 'ts', }; } diff --git a/packages/integrations/cloudflare/test/fixtures/top-level-return/astro.config.mjs b/packages/integrations/cloudflare/test/fixtures/top-level-return/astro.config.mjs new file mode 100644 index 000000000000..339f0e2a49c0 --- /dev/null +++ b/packages/integrations/cloudflare/test/fixtures/top-level-return/astro.config.mjs @@ -0,0 +1,7 @@ +import cloudflare from '@astrojs/cloudflare'; +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + adapter: cloudflare(), + output: 'server', +}); diff --git a/packages/integrations/cloudflare/test/fixtures/top-level-return/package.json b/packages/integrations/cloudflare/test/fixtures/top-level-return/package.json new file mode 100644 index 000000000000..a3bbe0091594 --- /dev/null +++ b/packages/integrations/cloudflare/test/fixtures/top-level-return/package.json @@ -0,0 +1,12 @@ +{ + "name": "@test/astro-cloudflare-top-level-return", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "astro build" + }, + "dependencies": { + "@astrojs/cloudflare": "workspace:*", + "astro": "workspace:*" + } +} diff --git a/packages/integrations/cloudflare/test/fixtures/top-level-return/src/lib/index.ts b/packages/integrations/cloudflare/test/fixtures/top-level-return/src/lib/index.ts new file mode 100644 index 000000000000..bbb7aa5e95a7 --- /dev/null +++ b/packages/integrations/cloudflare/test/fixtures/top-level-return/src/lib/index.ts @@ -0,0 +1,7 @@ +export function guard() { + return false; +} + +const ret = 0; + +export { ret as return } \ No newline at end of file diff --git a/packages/integrations/cloudflare/test/fixtures/top-level-return/src/pages/index.astro b/packages/integrations/cloudflare/test/fixtures/top-level-return/src/pages/index.astro new file mode 100644 index 000000000000..171a79ab888c --- /dev/null +++ b/packages/integrations/cloudflare/test/fixtures/top-level-return/src/pages/index.astro @@ -0,0 +1,25 @@ +--- +// This import statement is necessary to indicate that this code is an ECMAScript module. +import { guard } from "../lib/index.js" +// Un-commenting the following lines will trigger the following error: +// `X [ERROR] No matching export in "../lib/index.ts" for import "throw"` +// This is because 'return' is replaced with 'throw', and it's highly unlikely +// that the source library provides an export named 'throw', leading to a name mismatch. +// +// import { return as ret } from "../lib/index.js" +// console.log(ret) + +if (guard()) { + return Astro.redirect("/404") +} + +--- + + +
+