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/yellow-numbers-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/compiler': minor
---

Adds support for `Astro.self` (as accepted in the [Recursive Components RFC](https://github.com/withastro/rfcs/blob/main/active-rfcs/0000-recursive-components.md)).
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ require (
golang.org/x/net v0.0.0-20210716203947-853a461950ff
)

require github.com/iancoleman/strcase v0.2.0 // indirect

replace github.com/norunners/vert => github.com/natemoo-re/vert v0.0.0-natemoo-re.7
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/natemoo-re/vert v0.0.0-natemoo-re.7 h1:nhfKslS16o2Uruqt8Bwv8ZFYUuf+PW9iC2M5HI/Bs6U=
Expand Down
12 changes: 4 additions & 8 deletions internal/printer/print-to-js.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ func render1(p *printer, n *Node, opts RenderOptions) {
}

p.printReturnClose()
// TODO: use proper component name
p.printFuncSuffix("$$Component")
p.printFuncSuffix(opts.opts)
return
}

Expand Down Expand Up @@ -149,8 +148,7 @@ func render1(p *printer, n *Node, opts RenderOptions) {
// 3. The metadata object
p.printComponentMetadata(n.Parent, opts.opts, []byte(c.Data))

// TODO: use the proper component name
p.printFuncPrelude("$$Component")
p.printFuncPrelude(opts.opts)
} else {
importStatements := c.Data[0:renderBodyStart]
content := c.Data[renderBodyStart:]
Expand All @@ -176,8 +174,7 @@ func render1(p *printer, n *Node, opts RenderOptions) {
}
}

// TODO: use the proper component name
p.printFuncPrelude("$$Component")
p.printFuncPrelude(opts.opts)
if len(c.Loc) > 0 {
p.addSourceMapping(loc.Loc{Start: c.Loc[0].Start + renderBodyStart})
}
Expand Down Expand Up @@ -223,8 +220,7 @@ func render1(p *printer, n *Node, opts RenderOptions) {
p.printTopLevelAstro(opts.opts)

// Render func prelude. Will only run for the first non-frontmatter node
// TODO: use the proper component name
p.printFuncPrelude("$$Component")
p.printFuncPrelude(opts.opts)
// This just ensures a newline
p.println("")

Expand Down
7 changes: 5 additions & 2 deletions internal/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,21 @@ func (p *printer) printDefineVars(n *astro.Node) {
}
}

func (p *printer) printFuncPrelude(componentName string) {
func (p *printer) printFuncPrelude(opts transform.TransformOptions) {
if p.hasFuncPrelude {
return
}
componentName := getComponentName(opts.Pathname)
p.addNilSourceMapping()
p.println("\n//@ts-ignore")
p.println(fmt.Sprintf("const %s = %s(async (%s, $$props, %s) => {", componentName, CREATE_COMPONENT, RESULT, SLOTS))
p.println(fmt.Sprintf("const Astro = %s.createAstro($$Astro, $$props, %s);", RESULT, SLOTS))
p.println(fmt.Sprintf("Astro.self = %s;", componentName))
p.hasFuncPrelude = true
}

func (p *printer) printFuncSuffix(componentName string) {
func (p *printer) printFuncSuffix(opts transform.TransformOptions) {
componentName := getComponentName(opts.Pathname)
p.addNilSourceMapping()
p.println("});")
p.println(fmt.Sprintf("export default %s;", componentName))
Expand Down
3 changes: 2 additions & 1 deletion internal/printer/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ var INTERNAL_IMPORTS = fmt.Sprintf("import {\n %s\n} from \"%s\";\n", strings.J
}, ",\n "), "http://localhost:3000/")
var PRELUDE = fmt.Sprintf(`//@ts-ignore
const $$Component = %s(async ($$result, $$props, %s) => {
const Astro = $$result.createAstro($$Astro, $$props, %s);%s`, CREATE_COMPONENT, SLOTS, SLOTS, "\n")
const Astro = $$result.createAstro($$Astro, $$props, %s);
Astro.self = $$Component;%s`, CREATE_COMPONENT, SLOTS, SLOTS, "\n")
var RETURN = fmt.Sprintf("return %s%s", TEMPLATE_TAG, BACKTICK)
var SUFFIX = fmt.Sprintf("%s;", BACKTICK) + `
});
Expand Down
18 changes: 18 additions & 0 deletions internal/printer/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package printer
import (
"regexp"
"strings"

"github.com/iancoleman/strcase"
)

func escapeText(src string) string {
Expand All @@ -13,6 +15,22 @@ func escapeText(src string) string {
)
}

func getComponentName(pathname string) string {
if len(pathname) == 0 {
return "$$Component"
}
parts := strings.Split(pathname, "/")
part := parts[len(parts)-1]
if len(part) == 0 {
return "$$Component"
}
basename := strcase.ToCamel(strings.Split(part, ".")[0])
if basename == "Astro" {
return "$$Component"
}
return strings.Join([]string{"$$", basename}, "")
}

func escapeExistingEscapes(src string) string {
return strings.Replace(src, "\\", "\\\\", -1)
}
Expand Down
Binary file modified lib/compiler/deno/astro.wasm
Binary file not shown.
16 changes: 16 additions & 0 deletions lib/compiler/test/component-name.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* eslint-disable no-console */

import { transform } from '@astrojs/compiler';

async function run() {
const result = await transform(`<div>Hello world!</div>`, {
sourcemap: true,
pathname: '/src/components/Cool.astro',
});

if (!result.code.includes('export default $$Cool')) {
throw new Error(`Expected component export to be named "Cool"!`);
}
}

await run();
1 change: 1 addition & 0 deletions lib/compiler/test/test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import './basic.test.mjs';
import './body-fragment.test.mjs';
import './body-expression.test.mjs';
import './component-only.test.mjs';
import './component-name.test.mjs';
import './empty-style.test.mjs';
import './output.test.mjs';
import './script-fragment.test.mjs';
Expand Down