From 8a00eb359ad4a51b202b8ea8c451587aa812ef09 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Mon, 24 Jan 2022 15:40:13 -0600 Subject: [PATCH 01/39] chore: enter pre --- .changeset/pre.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/pre.json diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 000000000..88f218d57 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,8 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "@astrojs/compiler": "0.9.2" + }, + "changesets": [] +} From 41b825a8cfd2969a2be3ea782d09536a06da319a Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Mon, 24 Jan 2022 15:43:07 -0600 Subject: [PATCH 02/39] Treat all documents as fragments which generate no implicit tags (#264) * feat: remove "as", treat all documents as fragments with no implicit tags * test: fix failing tests * lint: remove unused utils --- .changeset/wicked-forks-do.md | 5 + cmd/astro-wasm/astro-wasm.go | 61 +++--- internal/print-to-source.go | 73 ++++--- internal/printer/print-to-js.go | 21 +- internal/printer/printer_test.go | 186 +++++++++--------- internal/transform/transform.go | 61 ------ internal/transform/transform_test.go | 10 +- internal/transform/utils.go | 11 -- lib/compiler/shared/types.ts | 3 + lib/compiler/test/body-fragment.test.mjs | 1 - lib/compiler/test/extract.test.mjs | 1 - lib/compiler/test/script-fragment.test.mjs | 1 - .../test/top-level-expression.test.mjs | 1 - lib/compiler/test/visible.test.mjs | 1 - 14 files changed, 198 insertions(+), 238 deletions(-) create mode 100644 .changeset/wicked-forks-do.md diff --git a/.changeset/wicked-forks-do.md b/.changeset/wicked-forks-do.md new file mode 100644 index 000000000..470bf71ca --- /dev/null +++ b/.changeset/wicked-forks-do.md @@ -0,0 +1,5 @@ +--- +'@astrojs/compiler': minor +--- + +Remove "as" option, treats all documents as fragments that generate no implicit tags diff --git a/cmd/astro-wasm/astro-wasm.go b/cmd/astro-wasm/astro-wasm.go index 91aef5971..03e5d1365 100644 --- a/cmd/astro-wasm/astro-wasm.go +++ b/cmd/astro-wasm/astro-wasm.go @@ -54,11 +54,6 @@ func makeTransformOptions(options js.Value, hash string) transform.TransformOpti pathname = "" } - as := jsString(options.Get("as")) - if as == "" { - as = "document" - } - internalURL := jsString(options.Get("internalURL")) if internalURL == "" { internalURL = "astro/internal" @@ -87,7 +82,6 @@ func makeTransformOptions(options js.Value, hash string) transform.TransformOpti preprocessStyle := options.Get("preprocessStyle") return transform.TransformOptions{ - As: as, Scope: hash, Filename: filename, Pathname: pathname, @@ -150,31 +144,36 @@ func Transform() interface{} { handler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { resolve := args[0] - go func() { - var doc *astro.Node - - if transformOptions.As == "document" { - docNode, err := astro.Parse(strings.NewReader(source)) - doc = docNode - if err != nil { - fmt.Println(err) - } - } else if transformOptions.As == "fragment" { - nodes, err := astro.ParseFragment(strings.NewReader(source), &astro.Node{ - Type: astro.ElementNode, - Data: atom.Template.String(), - DataAtom: atom.Template, - }) - if err != nil { - fmt.Println(err) - } - doc = &astro.Node{ - Type: astro.DocumentNode, - HydrationDirectives: make(map[string]bool), - } - for i := 0; i < len(nodes); i++ { - n := nodes[i] - doc.AppendChild(n) + var doc *astro.Node + nodes, err := astro.ParseFragment(strings.NewReader(source), &astro.Node{ + Type: astro.ElementNode, + Data: atom.Template.String(), + DataAtom: atom.Template, + }) + if err != nil { + fmt.Println(err) + } + doc = &astro.Node{ + Type: astro.DocumentNode, + HydrationDirectives: make(map[string]bool), + } + for i := 0; i < len(nodes); i++ { + n := nodes[i] + doc.AppendChild(n) + } + + // Hoist styles and scripts to the top-level + transform.ExtractStyles(doc) + + // Pre-process styles + // Important! These goroutines need to be spawned from this file or they don't work + var wg sync.WaitGroup + if len(doc.Styles) > 0 { + if transformOptions.PreprocessStyle.(js.Value).IsUndefined() != true { + for i, style := range doc.Styles { + wg.Add(1) + i := i + go preprocessStyle(i, style, transformOptions, wg.Done) } } diff --git a/internal/print-to-source.go b/internal/print-to-source.go index 99eba68db..fbd71779e 100644 --- a/internal/print-to-source.go +++ b/internal/print-to-source.go @@ -14,42 +14,53 @@ func PrintToSource(buf *strings.Builder, node *Node) { case TextNode: buf.WriteString(node.Data) case ElementNode: - buf.WriteString(fmt.Sprintf(`<%s`, node.Data)) - for _, attr := range node.Attr { - if attr.Key == ImplicitNodeMarker { - continue + isImplicit := false + for _, a := range node.Attr { + if a.Key == ImplicitNodeMarker { + isImplicit = true + break } - if attr.Namespace != "" { - buf.WriteString(attr.Namespace) - buf.WriteString(":") - } - buf.WriteString(" ") - switch attr.Type { - case QuotedAttribute: - buf.WriteString(attr.Key) - buf.WriteString("=") - buf.WriteString(`"` + attr.Val + `"`) - case EmptyAttribute: - buf.WriteString(attr.Key) - case ExpressionAttribute: - buf.WriteString(attr.Key) - buf.WriteString("=") - buf.WriteString(`{` + strings.TrimSpace(attr.Val) + `}`) - case SpreadAttribute: - buf.WriteString(`{...` + strings.TrimSpace(attr.Val) + `}`) - case ShorthandAttribute: - buf.WriteString(attr.Key) - buf.WriteString("=") - buf.WriteString(`{` + strings.TrimSpace(attr.Key) + `}`) - case TemplateLiteralAttribute: - buf.WriteString(attr.Key) - buf.WriteString("=`" + strings.TrimSpace(attr.Val) + "`") + } + if !isImplicit { + buf.WriteString(fmt.Sprintf(`<%s`, node.Data)) + for _, attr := range node.Attr { + if attr.Key == ImplicitNodeMarker { + continue + } + if attr.Namespace != "" { + buf.WriteString(attr.Namespace) + buf.WriteString(":") + } + buf.WriteString(" ") + switch attr.Type { + case QuotedAttribute: + buf.WriteString(attr.Key) + buf.WriteString("=") + buf.WriteString(`"` + attr.Val + `"`) + case EmptyAttribute: + buf.WriteString(attr.Key) + case ExpressionAttribute: + buf.WriteString(attr.Key) + buf.WriteString("=") + buf.WriteString(`{` + strings.TrimSpace(attr.Val) + `}`) + case SpreadAttribute: + buf.WriteString(`{...` + strings.TrimSpace(attr.Val) + `}`) + case ShorthandAttribute: + buf.WriteString(attr.Key) + buf.WriteString("=") + buf.WriteString(`{` + strings.TrimSpace(attr.Key) + `}`) + case TemplateLiteralAttribute: + buf.WriteString(attr.Key) + buf.WriteString("=`" + strings.TrimSpace(attr.Val) + "`") + } } + buf.WriteString(`>`) } - buf.WriteString(`>`) for c := node.FirstChild; c != nil; c = c.NextSibling { PrintToSource(buf, c) } - buf.WriteString(fmt.Sprintf(``, node.Data)) + if !isImplicit { + buf.WriteString(fmt.Sprintf(``, node.Data)) + } } } diff --git a/internal/printer/print-to-js.go b/internal/printer/print-to-js.go index 23bf42bdf..d56a98a10 100644 --- a/internal/printer/print-to-js.go +++ b/internal/printer/print-to-js.go @@ -211,7 +211,9 @@ func render1(p *printer, n *Node, opts RenderOptions) { depth: depth + 1, opts: opts.opts, }) - p.addSourceMapping(loc.Loc{Start: n.Loc[1].Start - 3}) + if len(n.Loc) > 1 { + p.addSourceMapping(loc.Loc{Start: n.Loc[1].Start - 3}) + } } } return @@ -335,6 +337,13 @@ func render1(p *printer, n *Node, opts RenderOptions) { isComponent := isFragment || n.Component || n.CustomElement isClientOnly := isComponent && transform.HasAttr(n, "client:only") isSlot := n.DataAtom == atom.Slot + isImplicit := false + for _, a := range n.Attr { + if transform.IsImplictNodeMarker(a) { + isImplicit = true + break + } + } p.addSourceMapping(n.Loc[0]) switch true { @@ -344,6 +353,8 @@ func render1(p *printer, n *Node, opts RenderOptions) { p.print(fmt.Sprintf("${%s(%s,'%s',", RENDER_COMPONENT, RESULT, n.Data)) case isSlot: p.print(fmt.Sprintf("${%s(%s,%s[", RENDER_SLOT, RESULT, SLOTS)) + case isImplicit: + // do nothing default: p.print("<") @@ -357,12 +368,14 @@ func render1(p *printer, n *Node, opts RenderOptions) { p.print("null") case !isSlot && n.CustomElement: p.print(fmt.Sprintf("'%s'", n.Data)) - case !isSlot: + case !isSlot && !isImplicit: p.print(n.Data) } p.addSourceMapping(n.Loc[0]) - if isComponent { + if isImplicit { + // do nothing + } else if isComponent { p.print(",") p.printAttributesToObject(n) } else if isSlot { @@ -556,7 +569,7 @@ func render1(p *printer, n *Node, opts RenderOptions) { } if isComponent || isSlot { p.print(")}") - } else { + } else if !isImplicit { p.print(``) } } diff --git a/internal/printer/printer_test.go b/internal/printer/printer_test.go index 356ed23cb..b3cc87a6d 100644 --- a/internal/printer/printer_test.go +++ b/internal/printer/printer_test.go @@ -81,7 +81,7 @@ func TestPrinter(t *testing.T) { name: "basic (no frontmatter)", source: ``, want: want{ - code: ``, + code: ``, }, }, { @@ -92,7 +92,7 @@ const href = '/about'; About`, want: want{ frontmatter: []string{"", "const href = '/about';"}, - code: `About`, + code: `About`, }, }, { @@ -107,7 +107,7 @@ export const getStaticPaths = async () => { frontmatter: []string{`export const getStaticPaths = async () => { return { paths: [] } }`, ""}, - code: `
`, + code: `
`, }, }, { @@ -124,7 +124,7 @@ export const getStaticPaths = async () => { getStaticPaths: `export const getStaticPaths = async () => { return { paths: [] } }`, - code: `
`, + code: `
`, }, }, { @@ -143,7 +143,7 @@ const b = 0;`}, getStaticPaths: `export async function getStaticPaths() { return { paths: [] } }`, - code: `
`, + code: `
`, }, }, { @@ -151,14 +151,13 @@ const b = 0;`}, source: `--- import data from "test" assert { type: 'json' }; --- -`, +`, want: want{ frontmatter: []string{ `import data from "test" assert { type: 'json' };`, }, metadata: metadata{modules: []string{`{ module: $$module1, specifier: 'test', assert: {type:'json'} }`}}, styles: []string{}, - code: ``, }, }, { @@ -206,7 +205,8 @@ import VueComponent from '../components/Vue.vue'; ${` + RENDER_COMPONENT + `($$result,'VueComponent',VueComponent,{})} - `, + + `, }, }, { @@ -232,7 +232,8 @@ import * as ns from '../components'; ${` + RENDER_COMPONENT + `($$result,'ns.Component',ns.Component,{})} - `, + + `, }, }, { @@ -253,7 +254,8 @@ import * as ns from '../components'; - `, + + `, }, }, { @@ -351,7 +353,7 @@ import * as components from '../components'; name: "conditional render", source: `{false ?
#f
:
#t
}`, want: want{ - code: "${false ? $$render`
#f
` : $$render`
#t
`}", + code: "${false ? $$render`
#f
` : $$render`
#t
`}", }, }, { @@ -372,7 +374,7 @@ import * as components from '../components'; name: "simple ternary", source: `{link ? {link} :
no link
}`, want: want{ - code: fmt.Sprintf(`${link ? $$render%s${link}%s : $$render%s
no link
%s}`, BACKTICK, BACKTICK, BACKTICK, BACKTICK), + code: fmt.Sprintf(`${link ? $$render%s${link}%s : $$render%s
no link
%s}`, BACKTICK, BACKTICK, BACKTICK, BACKTICK), }, }, { @@ -387,25 +389,25 @@ const items = [0, 1, 2]; `, want: want{ frontmatter: []string{"", "const items = [0, 1, 2];"}, - code: fmt.Sprintf(`
    + code: fmt.Sprintf(`
      ${items.map(item => { return $$render%s
    • ${item}
    • %s; })} -
    `, BACKTICK, BACKTICK), +
`, BACKTICK, BACKTICK), }, }, { name: "map without component", source: `
`, want: want{ - code: fmt.Sprintf(`
`, BACKTICK, BACKTICK), + code: fmt.Sprintf(`
`, BACKTICK, BACKTICK), }, }, { name: "map with component", source: `
`, want: want{ - code: fmt.Sprintf(`
${$$renderComponent($$result,'Hello',Hello,{})}
`, BACKTICK, BACKTICK), + code: fmt.Sprintf(`
${$$renderComponent($$result,'Hello',Hello,{})}
`, BACKTICK, BACKTICK), }, }, { @@ -425,28 +427,28 @@ const groups = [[0, 1, 2], [3, 4, 5]]; want: want{ frontmatter: []string{"", "const groups = [[0, 1, 2], [3, 4, 5]];"}, styles: []string{}, - code: fmt.Sprintf(`
+ code: fmt.Sprintf(`
${groups.map(items => { return %s
    ${ items.map(item => { return %s
  • ${item}
  • %s; }) }
%s})} -
`, "$$render"+BACKTICK, "$$render"+BACKTICK, BACKTICK, BACKTICK), +
`, "$$render"+BACKTICK, "$$render"+BACKTICK, BACKTICK, BACKTICK), }, }, { name: "backtick in HTML comment", source: "", want: want{ - code: "", + code: "", }, }, { name: "nested expressions", source: ``, want: want{ - code: `
${(previous || next) && $$render` + BACKTICK + `` + BACKTICK + `}
`, + code: `
${(previous || next) && $$render` + BACKTICK + `` + BACKTICK + `}
`, }, }, { @@ -465,7 +467,7 @@ const items = ['red', 'yellow', 'blue']; `, want: want{ frontmatter: []string{"", "const items = ['red', 'yellow', 'blue'];"}, - code: `
+ code: `
${items.map((item) => ( // foo < > < } $$render` + "`" + `color
` + "`" + ` @@ -473,7 +475,7 @@ $$render` + "`" + `color
` + "`" + ` ${items.map((item) => ( /* foo < > < } */$$render` + "`" + `color` + "`" + ` ))} -`, +`, }, }, { @@ -491,7 +493,7 @@ $$render` + "`" + `color` + "`" + ` } `, want: want{ - code: `
+ code: `
${ () => { let generate = (input) => { @@ -501,7 +503,7 @@ ${ }; } } -
`, +
`, }, }, { @@ -566,7 +568,8 @@ const name = "world";
- `, + + `, }, }, { @@ -586,10 +589,8 @@ const name = "world";

I’m a page

`, want: want{ styles: []string{"{props:{\"data-astro-id\":\"DPOHFLYM\"},children:`.title.astro-DPOHFLYM{font-family:fantasy;font-size:28px;}.body.astro-DPOHFLYM{font-size:1em;}`}"}, - code: ` - -

Page Title

-

I’m a page

`, + code: "\n\n\t\t" + `

Page Title

+

I’m a page

`, }, }, { @@ -728,7 +729,8 @@ import Counter from '../components/Counter.jsx'`,
${$$renderComponent($$result,'Counter',Counter,{...(someProps),"client:visible":true,"client:component-hydration":"visible","client:component-path":($$metadata.getPath(Counter)),"client:component-export":($$metadata.getExport(Counter)),"class":"astro-HMNNHVCQ"},{"default": () => $$render` + "`" + `

Hello React!

` + "`" + `,})}
- `, + + `, }, }, { @@ -753,7 +755,7 @@ import Widget2 from '../components/Widget2.astro';`}, code: ` - `, + `, }, }, { @@ -766,7 +768,7 @@ import Widget2 from '../components/Widget2.astro';`}, styles: []string{}, scripts: []string{fmt.Sprintf(`{props:{"type":"module","hoist":true},children:%sconsole.log("Hello");%s}`, BACKTICK, BACKTICK)}, metadata: metadata{hoisted: []string{fmt.Sprintf(`{ type: 'inline', value: %sconsole.log("Hello");%s }`, BACKTICK, BACKTICK)}}, - code: ``, + code: ``, }, }, { @@ -779,7 +781,7 @@ import Widget2 from '../components/Widget2.astro';`}, styles: []string{}, scripts: []string{`{props:{"type":"module","hoist":true,"src":"url"}}`}, metadata: metadata{hoisted: []string{`{ type: 'remote', src: 'url' }`}}, - code: "", + code: "", }, }, { @@ -792,37 +794,37 @@ import Widget2 from '../components/Widget2.astro';`}, styles: []string{}, scripts: []string{"{props:{\"type\":\"module\",\"hoist\":true},children:`console.log(\"Hello\");`}"}, metadata: metadata{hoisted: []string{fmt.Sprintf(`{ type: 'inline', value: %sconsole.log("Hello");%s }`, BACKTICK, BACKTICK)}}, - code: `
+ code: `
-
`, +
`, }, }, { name: "script nohoist", source: `
`, want: want{ - code: `
`, + code: `
`, }, }, { name: "script define:vars", source: `
`, want: want{ - code: fmt.Sprintf(`
`, DEFINE_SCRIPT_VARS), + code: fmt.Sprintf(`
`, DEFINE_SCRIPT_VARS), }, }, { name: "text after title expression", source: `a {expr} b`, want: want{ - code: `a ${expr} b`, + code: `a ${expr} b`, }, }, { name: "text after title expressions", source: `a {expr} b {expr} c`, want: want{ - code: `a ${expr} b ${expr} c`, + code: `a ${expr} b ${expr} c`, }, }, { @@ -845,14 +847,14 @@ import Widget2 from '../components/Widget2.astro';`}, name: "condition expressions at the top-level", source: `{cond && }{cond && }`, want: want{ - code: "${cond && $$render``}${cond && $$render``}", + code: "${cond && $$render``}${cond && $$render``}", }, }, { name: "condition expressions at the top-level with head content", source: `{cond && }{cond && My title}`, want: want{ - code: "${cond && $$render``}${cond && $$render`My title`}", + code: "${cond && $$render``}${cond && $$render`My title`}", }, }, { @@ -865,7 +867,7 @@ import 'test'; frontmatter: []string{`import 'test';`}, styles: []string{}, metadata: metadata{modules: []string{`{ module: $$module1, specifier: 'test', assert: {} }`}}, - code: `${$$renderComponent($$result,'my-element','my-element',{})}`, + code: `${$$renderComponent($$result,'my-element','my-element',{})}`, }, }, { @@ -917,7 +919,7 @@ ${$$renderComponent($$result,'my-element','my-element',{"client:load":true,"clie name: "Self-closing script in head works", source: ``, + code: ``, }, }, { @@ -938,7 +940,7 @@ ${$$renderComponent($$result,'my-element','my-element',{"client:load":true,"clie name: "Self-closing components in head can have siblings", source: ``, want: want{ - code: `${$$renderComponent($$result,'BaseHead',BaseHead,{})}`, + code: `${$$renderComponent($$result,'BaseHead',BaseHead,{})}`, }, }, { @@ -974,7 +976,7 @@ const canonicalURL = new URL('http://example.com'); frontmatter: []string{"", `const image = './penguin.png'; const canonicalURL = new URL('http://example.com');`}, styles: []string{}, - code: "${image && ($$render``)}", + code: "${image && ($$render``)}", }, }, { @@ -996,7 +998,7 @@ let allPosts = Astro.fetchContent('./post/*.md'); } let allPosts = Astro.fetchContent('./post/*.md');`}, styles: []string{}, - code: "
testing
", + code: "
testing
", }, }, { @@ -1020,10 +1022,10 @@ import ZComponent from '../components/ZComponent.jsx';`}, `{ module: $$module2, specifier: '../components/ZComponent.jsx', assert: {} }`, }, }, - code: ` + code: ` ${` + RENDER_COMPONENT + `($$result,'AComponent',AComponent,{})} ${` + RENDER_COMPONENT + `($$result,'ZComponent',ZComponent,{})} -`, +`, }, }, { @@ -1035,16 +1037,16 @@ import ZComponent from '../components/ZComponent.jsx';`}, src="https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75" srcSet="https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75 800w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75 1200w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1600&q=75 1600w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=2400&q=75 2400w" sizes="(max-width: 800px) 800px, (max-width: 1200px) 1200px, (max-width: 1600px) 1600px, (max-width: 2400px) 2400px, 1200px" ->`, +>`, want: want{ - code: `` + longRandomString + ``, + code: `` + longRandomString + ``, }, }, { name: "SVG styles", source: ``, want: want{ - code: ``, + code: ``, }, }, { @@ -1055,7 +1057,7 @@ const title = 'icon'; {title ?? null}`, want: want{ frontmatter: []string{"", "const title = 'icon';"}, - code: `${title ?? null}`, + code: `${title ?? null}`, }, }, { @@ -1066,7 +1068,7 @@ const title = 'icon'; {title ? {title} : null}`, want: want{ frontmatter: []string{"", "const title = 'icon';"}, - code: `${title ? $$render` + BACKTICK + `${title}` + BACKTICK + ` : null}`, + code: `${title ? $$render` + BACKTICK + `${title}` + BACKTICK + ` : null}`, }, }, { @@ -1074,7 +1076,7 @@ const title = 'icon'; source: ``, want: want{ scripts: []string{`{props:{"hoist":true}}`}, - code: ``, + code: ``, }, }, { @@ -1082,7 +1084,7 @@ const title = 'icon'; source: ``, want: want{ styles: []string{`{props:{"define:vars":({ color: "Gainsboro" }),"data-astro-id":"7HAAVZPE"}}`}, - code: ``, + code: ``, }, }, { @@ -1129,7 +1131,7 @@ const title = 'icon'; gtag('config', 'G-TEL60V1WM9'); -->`, want: want{ - code: ` + code: ` @@ -1168,7 +1170,7 @@ const title = 'icon'; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-TEL60V1WM9'); - -->`, + -->`, }, }, { @@ -1205,49 +1207,49 @@ import { Container, Col, Row } from 'react-bootstrap'; "{props:{\"data-astro-id\":\"EX5CHM4O\"},children:`div.astro-EX5CHM4O{color:green;}`}", "{props:{\"global\":true},children:`div { color: red }`}", }, - code: "\n\n\n\n\n\n\n\n
", + code: "\n\n\n\n\n\n\n\n
", }, }, { name: "Fragment", source: `
Default
Named
`, want: want{ - code: `${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render` + BACKTICK + `
Default
Named
` + BACKTICK + `,})}`, + code: `${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render` + BACKTICK + `
Default
Named
` + BACKTICK + `,})}`, }, }, { name: "Fragment shorthand", source: `<>
Default
Named
`, want: want{ - code: `${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render` + BACKTICK + `
Default
Named
` + BACKTICK + `,})}`, + code: `${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render` + BACKTICK + `
Default
Named
` + BACKTICK + `,})}`, }, }, { name: "Fragment slotted", source: `<>
Default
Named
`, want: want{ - code: `${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render` + BACKTICK + `${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render` + BACKTICK + `
Default
Named
` + BACKTICK + `,})}` + BACKTICK + `,})}`, + code: `${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render` + BACKTICK + `${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render` + BACKTICK + `
Default
Named
` + BACKTICK + `,})}` + BACKTICK + `,})}`, }, }, { name: "Fragment slotted with name", source: `
Default
Named
`, want: want{ - code: `${$$renderComponent($$result,'Component',Component,{},{"named": () => $$render` + BACKTICK + `${$$renderComponent($$result,'Fragment',Fragment,{"slot":"named"},{"default": () => $$render` + BACKTICK + `
Default
Named
` + BACKTICK + `,})}` + BACKTICK + `,})}`, + code: `${$$renderComponent($$result,'Component',Component,{},{"named": () => $$render` + BACKTICK + `${$$renderComponent($$result,'Fragment',Fragment,{"slot":"named"},{"default": () => $$render` + BACKTICK + `
Default
Named
` + BACKTICK + `,})}` + BACKTICK + `,})}`, }, }, { name: "Preserve slots inside custom-element", source: `
Name
Default
`, want: want{ - code: `${$$renderComponent($$result,'my-element','my-element',{},{"default": () => $$render` + BACKTICK + `
Name
Default
` + BACKTICK + `,})}`, + code: `${$$renderComponent($$result,'my-element','my-element',{},{"default": () => $$render` + BACKTICK + `
Name
Default
` + BACKTICK + `,})}`, }, }, { name: "Preserve namespaces", source: ``, want: want{ - code: ``, + code: ``, }, }, { @@ -1313,7 +1315,8 @@ const { product } = Astro.props; ${$$renderComponent($$result,'Footer',Footer,{})} -`, + +`, frontmatter: []string{ `import Header from '../../components/Header.jsx' import Footer from '../../components/Footer.astro' @@ -1345,6 +1348,13 @@ import ProductPageContent from '../../components/ProductPageContent.jsx';`, }, }, }, + { + name: "doctype", + source: `
`, + want: want{ + code: `
`, + }, + }, { name: "select option expression", source: `--- @@ -1353,7 +1363,7 @@ const value = 'test'; `, want: want{ frontmatter: []string{"", "const value = 'test';"}, - code: ``, + code: ``, }, }, { @@ -1364,7 +1374,7 @@ const value = 'test'; `, want: want{ frontmatter: []string{"", "const value = 'test';"}, - code: ``, + code: ``, }, }, { @@ -1375,14 +1385,14 @@ const value = 'test'; `, want: want{ frontmatter: []string{"", "const value = 'test';"}, - code: ``, + code: ``, }, }, { name: "textarea inside expression", source: `{bool && } {!bool && }`, want: want{ - code: `${bool && $$render` + BACKTICK + `` + BACKTICK + `} ${!bool && $$render` + BACKTICK + `` + BACKTICK + `}`, + code: `${bool && $$render` + BACKTICK + `` + BACKTICK + `} ${!bool && $$render` + BACKTICK + `` + BACKTICK + `}`, }, }, { @@ -1393,7 +1403,7 @@ const items = ["Dog", "Cat", "Platipus"]; {items.map(item => ())}
{item}
`, want: want{ frontmatter: []string{"", `const items = ["Dog", "Cat", "Platipus"];`}, - code: `${items.map(item => ($$render` + BACKTICK + `` + BACKTICK + `))}
${item}
`, + code: `${items.map(item => ($$render` + BACKTICK + `` + BACKTICK + `))}
${item}
`, }, }, { @@ -1404,7 +1414,7 @@ const items = ["Dog", "Cat", "Platipus"]; {items.map(item => ())}
Name
{item}
`, want: want{ frontmatter: []string{"", `const items = ["Dog", "Cat", "Platipus"];`}, - code: `${items.map(item => ($$render` + BACKTICK + `` + BACKTICK + `))}
Name
${item}
`, + code: `${items.map(item => ($$render` + BACKTICK + `` + BACKTICK + `))}
Name
${item}
`, }, }, { @@ -1415,49 +1425,49 @@ const items = ["Dog", "Cat", "Platipus"]; {items.map(item => ())}
Name
{item}{item + 's'}
`, want: want{ frontmatter: []string{"", `const items = ["Dog", "Cat", "Platipus"];`}, - code: `${items.map(item => ($$render` + BACKTICK + `` + BACKTICK + `))}
Name
${item}${item + 's'}
`, + code: `${items.map(item => ($$render` + BACKTICK + `` + BACKTICK + `))}
Name
${item}${item + 's'}
`, }, }, { name: "td expressions", source: `

Row 1

{title}
`, want: want{ - code: `

Row 1

${title}
`, + code: `

Row 1

${title}
`, }, }, { name: "th expressions", source: `
{title}
`, want: want{ - code: `
${title}
`, + code: `
${title}
`, }, }, { name: "anchor expressions", source: `{expr}`, want: want{ - code: `${expr}`, + code: `${expr}`, }, }, { name: "anchor inside expression", source: `{true && expr}`, want: want{ - code: `${true && $$render` + BACKTICK + `expr` + BACKTICK + `}`, + code: `${true && $$render` + BACKTICK + `expr` + BACKTICK + `}`, }, }, { name: "anchor content", source: `

  • {expr}
`, want: want{ - code: `

  • ${expr}
`, + code: `

  • ${expr}
`, }, }, { name: "small expression", source: `
{a}{data.map(a => )}
`, want: want{ - code: `
${a}${data.map(a => $$render` + BACKTICK + `${$$renderComponent($$result,'Component',Component,{"value":(a)})}` + BACKTICK + `)}
`, + code: `
${a}${data.map(a => $$render` + BACKTICK + `${$$renderComponent($$result,'Component',Component,{"value":(a)})}` + BACKTICK + `)}
`, }, }, { @@ -1471,7 +1481,7 @@ const items = ["Dog", "Cat", "Platipus"]; name: "escaped entity", source: `A person saying "hello"`, want: want{ - code: `A person saying "hello"`, + code: `A person saying "hello"`, }, }, { @@ -1492,7 +1502,7 @@ const items = ["Dog", "Cat", "Platipus"]; name: "user-defined `implicit` is printed", source: ``, want: want{ - code: ``, + code: ``, }, }, { @@ -1500,15 +1510,11 @@ const items = ["Dog", "Cat", "Platipus"]; source: ` - -
My Text
`, +
My Text
`, want: want{ - styles: []string{fmt.Sprintf(`{props:{"data-astro-id":"RN5ULUD7"},children:%s/* comment */.container.astro-RN5ULUD7{padding:2rem;}%s}`, BACKTICK, BACKTICK)}, - code: ` - -
My Text
`, + styles: []string{fmt.Sprintf(`{props:{"data-astro-id":"SJ3WYE6H"},children:%s/* comment */.container.astro-SJ3WYE6H{padding:2rem;}%s}`, BACKTICK, BACKTICK)}, + code: `
My Text
`, }, }, { @@ -1521,7 +1527,7 @@ const items = ["Dog", "Cat", "Platipus"]; `, want: want{ - code: fmt.Sprintf(` + code: fmt.Sprintf(` ${true ? ($$render%s%s) : null} ${true ? ($$render%s%s) : null} @@ -1541,14 +1547,14 @@ const items = ["Dog", "Cat", "Platipus"]; name: "Empty expression", source: "({})", want: want{ - code: `(${(void 0)})`, + code: `(${(void 0)})`, }, }, { name: "Empty attribute expression", source: "", want: want{ - code: ``, + code: ``, }, }, { diff --git a/internal/transform/transform.go b/internal/transform/transform.go index 4ad42969d..45ec3e122 100644 --- a/internal/transform/transform.go +++ b/internal/transform/transform.go @@ -11,7 +11,6 @@ import ( ) type TransformOptions struct { - As string Scope string Filename string Pathname string @@ -39,42 +38,6 @@ func Transform(doc *astro.Node, opts TransformOptions) *astro.Node { script.Parent.RemoveChild(script) } - // Sometimes files have leading `, { sourcemap: true, - as: 'fragment', site: undefined, sourcefile: 'MoreMenu.astro', sourcemap: 'both', diff --git a/lib/compiler/test/top-level-expression.test.mjs b/lib/compiler/test/top-level-expression.test.mjs index e74f784cb..95b5e2061 100644 --- a/lib/compiler/test/top-level-expression.test.mjs +++ b/lib/compiler/test/top-level-expression.test.mjs @@ -30,7 +30,6 @@ const internal = []; async function run() { const result = await transform(contents, { sourcemap: true, - as: 'fragment', site: undefined, sourcefile: 'MoreMenu.astro', sourcemap: 'both', diff --git a/lib/compiler/test/visible.test.mjs b/lib/compiler/test/visible.test.mjs index 80ad3a312..9d0f760d7 100644 --- a/lib/compiler/test/visible.test.mjs +++ b/lib/compiler/test/visible.test.mjs @@ -19,7 +19,6 @@ async function run() { `, { sourcemap: true, - as: 'fragment', site: undefined, sourcefile: 'MoreMenu.astro', sourcemap: 'both', From 8ce39c7c196121736277eecffe4ac5ed38f42c08 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Mon, 24 Jan 2022 16:03:56 -0600 Subject: [PATCH 03/39] [DO NOT MERGE] add `renderHead` util to output (#265) * feat: add renderHead util to output * chore: update ci to run on `next` * test: update tests * chore: add changeset --- .changeset/tasty-garlics-call.md | 5 +++++ .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 1 + internal/printer/print-to-js.go | 3 +++ internal/printer/printer.go | 7 +++++++ internal/printer/printer_test.go | 32 +++++++++++++++++--------------- 6 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 .changeset/tasty-garlics-call.md diff --git a/.changeset/tasty-garlics-call.md b/.changeset/tasty-garlics-call.md new file mode 100644 index 000000000..bee3440cd --- /dev/null +++ b/.changeset/tasty-garlics-call.md @@ -0,0 +1,5 @@ +--- +'@astrojs/compiler': minor +--- + +Do not render implicit tags created during the parsing process diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 293416fff..f66561f16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: Test on: push: - branches: ['main'] + branches: ['main', 'next'] pull_request: - branches: ['main'] + branches: ['main', 'next'] # Automatically cancel in-progress actions on the same branch concurrency: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 124d276ab..e2ca2a1a4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,7 @@ on: push: branches: - main + - next jobs: release: diff --git a/internal/printer/print-to-js.go b/internal/printer/print-to-js.go index d56a98a10..2c60e20d2 100644 --- a/internal/printer/print-to-js.go +++ b/internal/printer/print-to-js.go @@ -570,6 +570,9 @@ func render1(p *printer, n *Node, opts RenderOptions) { if isComponent || isSlot { p.print(")}") } else if !isImplicit { + if n.DataAtom == atom.Head { + p.printRenderHead() + } p.print(``) } } diff --git a/internal/printer/printer.go b/internal/printer/printer.go index 18b7a7a0d..63b5a7930 100644 --- a/internal/printer/printer.go +++ b/internal/printer/printer.go @@ -37,6 +37,7 @@ var ADD_ATTRIBUTE = "$$addAttribute" var SPREAD_ATTRIBUTES = "$$spreadAttributes" var DEFINE_STYLE_VARS = "$$defineStyleVars" var DEFINE_SCRIPT_VARS = "$$defineScriptVars" +var RENDER_HEAD = "$$renderHead" var CREATE_METADATA = "$$createMetadata" var METADATA = "$$metadata" var RESULT = "$$result" @@ -59,6 +60,7 @@ func (p *printer) printInternalImports(importSpecifier string) { p.print("import {\n ") p.print(FRAGMENT + ",\n ") p.print("render as " + TEMPLATE_TAG + ",\n ") + p.print("renderHead as " + RENDER_HEAD + ",\n ") p.print("createAstro as " + CREATE_ASTRO + ",\n ") p.print("createComponent as " + CREATE_COMPONENT + ",\n ") p.print("renderComponent as " + RENDER_COMPONENT + ",\n ") @@ -90,6 +92,11 @@ func (p *printer) printCSSImports(cssLen int) { p.hasCSSImports = true } +func (p *printer) printRenderHead() { + p.addNilSourceMapping() + p.print(fmt.Sprintf("${%s(%s)}", RENDER_HEAD, RESULT)) +} + func (p *printer) printReturnOpen() { p.addNilSourceMapping() p.print("return ") diff --git a/internal/printer/printer_test.go b/internal/printer/printer_test.go index b3cc87a6d..eb71589bc 100644 --- a/internal/printer/printer_test.go +++ b/internal/printer/printer_test.go @@ -16,6 +16,7 @@ import ( var INTERNAL_IMPORTS = fmt.Sprintf("import {\n %s\n} from \"%s\";\n", strings.Join([]string{ FRAGMENT, "render as " + TEMPLATE_TAG, + "renderHead as " + RENDER_HEAD, "createAstro as " + CREATE_ASTRO, "createComponent as " + CREATE_COMPONENT, "renderComponent as " + RENDER_COMPONENT, @@ -41,6 +42,7 @@ var STYLE_SUFFIX = "];\nfor (const STYLE of STYLES) $$result.styles.add(STYLE);\ var SCRIPT_PRELUDE = "const SCRIPTS = [\n" var SCRIPT_SUFFIX = "];\nfor (const SCRIPT of SCRIPTS) $$result.scripts.add(SCRIPT);\n" var CREATE_ASTRO_CALL = "const $$Astro = $$createAstro(import.meta.url, 'https://astro.build', '.');\nconst Astro = $$Astro;" +var RENDER_HEAD_RESULT = fmt.Sprintf("${%s(%s)}", RENDER_HEAD, RESULT) // SPECIAL TEST FIXTURES var NON_WHITESPACE_CHARS = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?") @@ -202,7 +204,7 @@ import VueComponent from '../components/Vue.vue'; code: ` Hello world - + ` + RENDER_HEAD_RESULT + ` ${` + RENDER_COMPONENT + `($$result,'VueComponent',VueComponent,{})} @@ -229,7 +231,7 @@ import * as ns from '../components'; code: ` Hello world - + ` + RENDER_HEAD_RESULT + ` ${` + RENDER_COMPONENT + `($$result,'ns.Component',ns.Component,{})} @@ -249,7 +251,7 @@ import * as ns from '../components'; `, want: want{ code: ` - + ` + RENDER_HEAD_RESULT + `
Row 1
Row 2