withastro / compiler

The Astro compiler. Written in Go. Distributed as WASM.
Other
502 stars 59 forks source link

🐛 BUG: Hoisted exports break `as const` & `satisfies <type>` #863

Open bb010g opened 1 year ago

bb010g commented 1 year ago

What version of @astrojs/compiler are you using?

2.1.0

What package manager are you using?

pnpm

What operating system are you using?

Windows

Describe the Bug

HoistExports in //internal/js_scanner/js_scanner.go fails to account for some TypeScript syntax when lexing.

Both of the following exported expressions will be split incorrectly, each resulting in a syntax error:

export const foo = {
} as const;

export const bar = {
} satisfies object;

Here's the compiled output for the following .astro source:

---
// Unhoisted comment.
export const bar = {
} as const satisfies object;
---
<div>Astro</div>
import {
  Fragment,
  render as $$render,
  createAstro as $$createAstro,
  createComponent as $$createComponent,
  renderComponent as $$renderComponent,
  renderHead as $$renderHead,
  maybeRenderHead as $$maybeRenderHead,
  unescapeHTML as $$unescapeHTML,
  renderSlot as $$renderSlot,
  mergeSlots as $$mergeSlots,
  addAttribute as $$addAttribute,
  spreadAttributes as $$spreadAttributes,
  defineStyleVars as $$defineStyleVars,
  defineScriptVars as $$defineScriptVars,
  renderTransition as $$renderTransition,
  createTransitionScope as $$createTransitionScope,
  createMetadata as $$createMetadata
} from "astro/runtime/server/index.js";

export const $$metadata = $$createMetadata("/Users/astro/Code/project/src/pages/foo.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });

const $$Astro = $$createAstro();
const Astro = $$Astro;
export const bar = {
}
const $$Foo = $$createComponent(async ($$result, $$props, $$slots) => {
const Astro = $$result.createAstro($$Astro, $$props, $$slots);
Astro.self = $$Foo;

// Unhoisted comment.
 as const satisfies object;

return $$render`${$$maybeRenderHead($$result)}<div>Astro</div>`;
}, '/Users/astro/Code/project/src/pages/foo.astro', undefined);
export default $$Foo;

You can see that as const satisfies object; isn't hoisted along with the rest of the exported expression.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-vlvcmq

MoustaphaDev commented 11 months ago

Related https://github.com/withastro/compiler/issues/878