Skip to content

Commit c758d7e

Browse files
authored
fix: await issue with fragment (#1067)
* fix: missing async for fragment Signed-off-by: mertmit <mertmit99@gmail.com> * test: fragment with await Signed-off-by: mertmit <mertmit99@gmail.com> * fix: add changeset Signed-off-by: mertmit <mertmit99@gmail.com> * test: fragment shorthand and awaited prop Signed-off-by: mertmit <mertmit99@gmail.com> * test: component with await Signed-off-by: mertmit <mertmit99@gmail.com> --------- Signed-off-by: mertmit <mertmit99@gmail.com>
1 parent 0399d55 commit c758d7e

File tree

8 files changed

+197
-9
lines changed

8 files changed

+197
-9
lines changed

.changeset/small-lions-reflect.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@astrojs/compiler": patch
3+
---
4+
5+
Add async properly when await used inside fragment
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
[TestPrinter/Component_with_await - 1]
3+
## Input
4+
5+
```
6+
<body><Component> { await Promise.resolve("Awaited") } </Component></body>
7+
```
8+
9+
## Output
10+
11+
```js
12+
import {
13+
Fragment,
14+
render as $$render,
15+
createAstro as $$createAstro,
16+
createComponent as $$createComponent,
17+
renderComponent as $$renderComponent,
18+
renderHead as $$renderHead,
19+
maybeRenderHead as $$maybeRenderHead,
20+
unescapeHTML as $$unescapeHTML,
21+
renderSlot as $$renderSlot,
22+
mergeSlots as $$mergeSlots,
23+
addAttribute as $$addAttribute,
24+
spreadAttributes as $$spreadAttributes,
25+
defineStyleVars as $$defineStyleVars,
26+
defineScriptVars as $$defineScriptVars,
27+
renderTransition as $$renderTransition,
28+
createTransitionScope as $$createTransitionScope,
29+
renderScript as $$renderScript,
30+
createMetadata as $$createMetadata
31+
} from "http://localhost:3000/";
32+
33+
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
34+
35+
const $$Component = $$createComponent(async ($$result, $$props, $$slots) => {
36+
37+
return $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'Component',Component,{},{"default": async () => $$render`${ await Promise.resolve("Awaited") }`,})}</body>`;
38+
}, undefined, undefined);
39+
export default $$Component;
40+
```
41+
---
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
[TestPrinter/Fragment_shorthand_with_await - 1]
3+
## Input
4+
5+
```
6+
<body><> { await Promise.resolve("Awaited") } </></body>
7+
```
8+
9+
## Output
10+
11+
```js
12+
import {
13+
Fragment,
14+
render as $$render,
15+
createAstro as $$createAstro,
16+
createComponent as $$createComponent,
17+
renderComponent as $$renderComponent,
18+
renderHead as $$renderHead,
19+
maybeRenderHead as $$maybeRenderHead,
20+
unescapeHTML as $$unescapeHTML,
21+
renderSlot as $$renderSlot,
22+
mergeSlots as $$mergeSlots,
23+
addAttribute as $$addAttribute,
24+
spreadAttributes as $$spreadAttributes,
25+
defineStyleVars as $$defineStyleVars,
26+
defineScriptVars as $$defineScriptVars,
27+
renderTransition as $$renderTransition,
28+
createTransitionScope as $$createTransitionScope,
29+
renderScript as $$renderScript,
30+
createMetadata as $$createMetadata
31+
} from "http://localhost:3000/";
32+
33+
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
34+
35+
const $$Component = $$createComponent(async ($$result, $$props, $$slots) => {
36+
37+
return $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'Fragment',Fragment,{},{"default": async () => $$render`${ await Promise.resolve("Awaited") }`,})}</body>`;
38+
}, undefined, undefined);
39+
export default $$Component;
40+
```
41+
---
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
[TestPrinter/Fragment_with_await - 1]
3+
## Input
4+
5+
```
6+
<body><Fragment> { await Promise.resolve("Awaited") } </Fragment></body>
7+
```
8+
9+
## Output
10+
11+
```js
12+
import {
13+
Fragment,
14+
render as $$render,
15+
createAstro as $$createAstro,
16+
createComponent as $$createComponent,
17+
renderComponent as $$renderComponent,
18+
renderHead as $$renderHead,
19+
maybeRenderHead as $$maybeRenderHead,
20+
unescapeHTML as $$unescapeHTML,
21+
renderSlot as $$renderSlot,
22+
mergeSlots as $$mergeSlots,
23+
addAttribute as $$addAttribute,
24+
spreadAttributes as $$spreadAttributes,
25+
defineStyleVars as $$defineStyleVars,
26+
defineScriptVars as $$defineScriptVars,
27+
renderTransition as $$renderTransition,
28+
createTransitionScope as $$createTransitionScope,
29+
renderScript as $$renderScript,
30+
createMetadata as $$createMetadata
31+
} from "http://localhost:3000/";
32+
33+
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
34+
35+
const $$Component = $$createComponent(async ($$result, $$props, $$slots) => {
36+
37+
return $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'Fragment',Fragment,{},{"default": async () => $$render`${ await Promise.resolve("Awaited") }`,})}</body>`;
38+
}, undefined, undefined);
39+
export default $$Component;
40+
```
41+
---
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
[TestPrinter/Fragment_wrapping_link_with_awaited_href - 1]
3+
## Input
4+
5+
```
6+
<head><Fragment><link rel="preload" href={(await import('../fonts/some-font.woff2')).default} as="font" crossorigin /></Fragment></head>
7+
```
8+
9+
## Output
10+
11+
```js
12+
import {
13+
Fragment,
14+
render as $$render,
15+
createAstro as $$createAstro,
16+
createComponent as $$createComponent,
17+
renderComponent as $$renderComponent,
18+
renderHead as $$renderHead,
19+
maybeRenderHead as $$maybeRenderHead,
20+
unescapeHTML as $$unescapeHTML,
21+
renderSlot as $$renderSlot,
22+
mergeSlots as $$mergeSlots,
23+
addAttribute as $$addAttribute,
24+
spreadAttributes as $$spreadAttributes,
25+
defineStyleVars as $$defineStyleVars,
26+
defineScriptVars as $$defineScriptVars,
27+
renderTransition as $$renderTransition,
28+
createTransitionScope as $$createTransitionScope,
29+
renderScript as $$renderScript,
30+
createMetadata as $$createMetadata
31+
} from "http://localhost:3000/";
32+
33+
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
34+
35+
const $$Component = $$createComponent(async ($$result, $$props, $$slots) => {
36+
37+
return $$render`<head>${$$renderComponent($$result,'Fragment',Fragment,{},{"default": async () => $$render`<link rel="preload"${$$addAttribute((await import('../fonts/some-font.woff2')).default, "href")} as="font" crossorigin>`,})}${$$renderHead($$result)}</head>`;
38+
}, undefined, undefined);
39+
export default $$Component;
40+
```
41+
---

internal/printer/print-to-js.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -706,9 +706,9 @@ func render1(p *printer, n *Node, opts RenderOptions) {
706706

707707
// If selected, pass through result object on the Astro side
708708
if opts.opts.ResultScopedSlot {
709-
p.print(fmt.Sprintf(`%s: ($$result) => `, slotProp))
709+
p.print(fmt.Sprintf(`%s: %s($$result) => `, slotProp, p.getAsyncFuncPrefix()))
710710
} else {
711-
p.print(fmt.Sprintf(`%s: () => `, slotProp))
711+
p.print(fmt.Sprintf(`%s: %s() => `, slotProp, p.getAsyncFuncPrefix()))
712712
}
713713

714714
p.printTemplateLiteralOpen()

internal/printer/printer.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,15 @@ func (p *printer) addTSXStyle(start int, end int, content string, styleType stri
105105
})
106106
}
107107

108+
func (p *printer) getAsyncFuncPrefix() string {
109+
// Decide whether to print `async` if top-level await is used. Use a loose check for now.
110+
funcPrefix := ""
111+
if strings.Contains(p.sourcetext, "await") {
112+
funcPrefix = "async "
113+
}
114+
return funcPrefix
115+
}
116+
108117
func (p *printer) printTextWithSourcemap(text string, l loc.Loc) {
109118
start := l.Start
110119
skipNext := false
@@ -336,14 +345,8 @@ func (p *printer) printFuncPrelude(opts transform.TransformOptions, printAstroGl
336345
}
337346
componentName := getComponentName(opts.Filename)
338347

339-
// Decide whether to print `async` if top-level await is used. Use a loose check for now.
340-
funcPrefix := ""
341-
if strings.Contains(p.sourcetext, "await") {
342-
funcPrefix = "async "
343-
}
344-
345348
p.addNilSourceMapping()
346-
p.println(fmt.Sprintf("const %s = %s(%s(%s, $$props, %s) => {", componentName, CREATE_COMPONENT, funcPrefix, RESULT, SLOTS))
349+
p.println(fmt.Sprintf("const %s = %s(%s(%s, $$props, %s) => {", componentName, CREATE_COMPONENT, p.getAsyncFuncPrefix(), RESULT, SLOTS))
347350
if printAstroGlobal {
348351
p.addNilSourceMapping()
349352
p.println(fmt.Sprintf("const Astro = %s.createAstro($$Astro, $$props, %s);", RESULT, SLOTS))

internal/printer/printer_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,22 @@ import { Container, Col, Row } from 'react-bootstrap';
12331233
name: "Fragment slotted with name",
12341234
source: `<body><Component><Fragment slot=named><div>Default</div><div>Named</div></Fragment></Component></body>`,
12351235
},
1236+
{
1237+
name: "Fragment with await",
1238+
source: `<body><Fragment> { await Promise.resolve("Awaited") } </Fragment></body>`,
1239+
},
1240+
{
1241+
name: "Fragment shorthand with await",
1242+
source: `<body><> { await Promise.resolve("Awaited") } </></body>`,
1243+
},
1244+
{
1245+
name: "Fragment wrapping link with awaited href",
1246+
source: `<head><Fragment><link rel="preload" href={(await import('../fonts/some-font.woff2')).default} as="font" crossorigin /></Fragment></head>`,
1247+
},
1248+
{
1249+
name: "Component with await",
1250+
source: `<body><Component> { await Promise.resolve("Awaited") } </Component></body>`,
1251+
},
12361252
{
12371253
name: "Preserve slots inside custom-element",
12381254
source: `<body><my-element><div slot=name>Name</div><div>Default</div></my-element></body>`,

0 commit comments

Comments
 (0)