diff options
28 files changed, 769 insertions, 732 deletions
diff --git a/examples/snowpack/astro/components/BaseHead.astro b/examples/snowpack/astro/components/BaseHead.astro new file mode 100644 index 000000000..b24861ca6 --- /dev/null +++ b/examples/snowpack/astro/components/BaseHead.astro @@ -0,0 +1,38 @@ +--- +import Banner from './Banner.astro'; +import Nav from './Nav.astro'; + +export let title: string; +export let description: string; +export let permalink: string; +--- + +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> +<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" /> +<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" /> +<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" /> +<link rel="manifest" href="/favicon/site.webmanifest" /> + +<!-- Primary Meta Tags --> +<title>{title}</title> +<meta name="title" content={title} /> +<meta name="description" content="{description}" /> + +<!-- Open Graph / Facebook --> +<meta property="og:type" content="website" /> +<meta property="og:url" content={permalink} /> +<meta property="og:title" content={title} /> +<meta property="og:description" content={description} /> +<meta property="og:image" content="https://www.snowpack.dev/img/social-2.jpg" /> + +<!-- Twitter --> +<meta property="twitter:card" content="summary_large_image" /> +<meta property="twitter:url" content={permalink} /> +<meta property="twitter:title" content={title} /> +<meta property="twitter:description" content={description} /> +<meta property="twitter:image" content="https://www.snowpack.dev/img/social-2.jpg" /> + +<!-- Global Stylesheets --> +<link rel="stylesheet" href="/css/app.css" /> +<link href="https://fonts.googleapis.com/css2?family=Overpass:wght@400;700;900&display=swap" rel="stylesheet" />
\ No newline at end of file diff --git a/examples/snowpack/astro/components/BaseLayout.astro b/examples/snowpack/astro/components/BaseLayout.astro new file mode 100644 index 000000000..2e141a83f --- /dev/null +++ b/examples/snowpack/astro/components/BaseLayout.astro @@ -0,0 +1,20 @@ +--- +import Banner from './Banner.astro'; +import Nav from './Nav.astro'; +--- + +<Banner></Banner> +<Nav /> + +<slot></slot> + +<!-- Global site tag (gtag.js) - Google Analytics --> +<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-130280175-9"></script> +<script> + window.dataLayer = window.dataLayer || []; + function gtag() { + dataLayer.push(arguments); + } + gtag('js', new Date()); + gtag('config', 'UA-130280175-9', { page_path: location.pathname === '/' ? (location.pathname + location.hash) : (location.pathname) }); +</script>
\ No newline at end of file diff --git a/examples/snowpack/astro/components/MainLayout.astro b/examples/snowpack/astro/components/MainLayout.astro new file mode 100644 index 000000000..dbc714510 --- /dev/null +++ b/examples/snowpack/astro/components/MainLayout.astro @@ -0,0 +1,23 @@ +--- +import BaseLayout from './BaseLayout.astro'; +import Menu from './Menu.astro'; +export function setup({ context }) { +return {}; +} +--- + +<BaseLayout> + <div class="container"> + <section class="snow-view__docs is-full"> + + <aside id="nav-primary" class="snow-view-nav"> + <Menu /> + </aside> + + <article class="snow-view-main"> + <slot></slot> + </article> + + </section> + </div> +</BaseLayout>
\ No newline at end of file diff --git a/examples/snowpack/astro/components/Nav.astro b/examples/snowpack/astro/components/Nav.astro index d679553c6..8ca95cb2a 100644 --- a/examples/snowpack/astro/components/Nav.astro +++ b/examples/snowpack/astro/components/Nav.astro @@ -1,5 +1,5 @@ --- - export let props: { version: string }; +export let version: string = '3.1.2'; --- <style lang="scss"> @@ -257,7 +257,7 @@ </div> <div style="flex-grow: 1"></div> <a href="https://github.com/snowpackjs/snowpack/releases" target="_blank" class="link version"> - {`v${props.version}`} + {`v${version}`} </a> <a href="https://github.com/snowpackjs/snowpack" target="_blank" class="link link__desktop"> <svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="github" class="snow-icon" role="img" diff --git a/examples/snowpack/astro/components/Subnav.astro b/examples/snowpack/astro/components/Subnav.astro index 2c054a5fc..69560cae1 100644 --- a/examples/snowpack/astro/components/Subnav.astro +++ b/examples/snowpack/astro/components/Subnav.astro @@ -1,9 +1,7 @@ --- - export let props: { - title: string, - inputPath: string, - headers: { text: string, slug: string }[] - }; +export let title: string; +export let inputPath: string; +export let headers: string; --- <style lang="scss"> @@ -59,12 +57,12 @@ <script type="module" defer src="/js/index.js"></script> <aside class="subnav"> - {props.headers.length > 0 && ( + {headers.length > 0 && ( <div> <h4 class="header">On this page</h4> <nav class="toc"> <ol> - {props.headers.map((heading) => { + {headers.map((heading) => { return <li><a href={"#" + heading.slug}>{heading.text}</a></li> })} </ol> @@ -74,5 +72,5 @@ )} <h4 class="header">Suggest a change</h4> - <a href="https://github.com/snowpackjs/snowpack/blob/main/www/{props.inputPath}">Edit this page on GitHub</a> + <a href="https://github.com/snowpackjs/snowpack/blob/main/www/{inputPath}">Edit this page on GitHub</a> </aside> diff --git a/examples/snowpack/astro/layouts/base.astro b/examples/snowpack/astro/layouts/base.astro deleted file mode 100644 index 4b460c8c2..000000000 --- a/examples/snowpack/astro/layouts/base.astro +++ /dev/null @@ -1,62 +0,0 @@ ---- - import Banner from '../components/Banner.astro'; - import Nav from '../components/Nav.astro'; - export function setup({ context }) { - return { - context: { - title: 'Snowpack', - description: 'Snowpack is a lightning-fast frontend build tool, designed for the modern web.', - currentSnowpackVersion: '3.0.13', - } - }; - } ---- - -<astro:head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> - <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" /> - <link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" /> - <link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" /> - <link rel="manifest" href="/favicon/site.webmanifest" /> - - <!-- Primary Meta Tags --> - <title>{context.title}</title> - <meta name="title" content={context.title} /> - <meta name="description" content="{context.description}" /> - - <!-- Open Graph / Facebook --> - <meta property="og:type" content="website" /> - <meta property="og:url" content={context.permalink} /> - <meta property="og:title" content={context.title} /> - <meta property="og:description" content={context.description} /> - <meta property="og:image" content="https://www.snowpack.dev/img/social-2.jpg" /> - - <!-- Twitter --> - <meta property="twitter:card" content="summary_large_image" /> - <meta property="twitter:url" content={context.permalink} /> - <meta property="twitter:title" content={context.title} /> - <meta property="twitter:description" content={context.description} /> - <meta property="twitter:image" content="https://www.snowpack.dev/img/social-2.jpg" /> - - <!-- Global Stylesheets --> - <link rel="stylesheet" href="/css/app.css" /> - <link href="https://fonts.googleapis.com/css2?family=Overpass:wght@400;700;900&display=swap" rel="stylesheet" /> -</astro:head> - -<Banner></Banner> -<Nav version={context.currentSnowpackVersion} /> - -<!-- if no slot given, assume add to bottom --> -<slot></slot> - -<!-- Global site tag (gtag.js) - Google Analytics --> -<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-130280175-9"></script> -<script> - window.dataLayer = window.dataLayer || []; - function gtag() { - dataLayer.push(arguments); - } - gtag('js', new Date()); - gtag('config', 'UA-130280175-9', { page_path: location.pathname === '/' ? (location.pathname + location.hash) : (location.pathname) }); -</script>
\ No newline at end of file diff --git a/examples/snowpack/astro/layouts/content-with-cover.astro b/examples/snowpack/astro/layouts/content-with-cover.astro index 066cdea3f..dd9909578 100644 --- a/examples/snowpack/astro/layouts/content-with-cover.astro +++ b/examples/snowpack/astro/layouts/content-with-cover.astro @@ -1,78 +1,88 @@ --- - import Menu from '../components/Menu.astro'; - import Subnav from '../components/Subnav.astro'; +import Subnav from '../components/Subnav.astro'; +import Menu from '../components/Menu.astro'; +import BaseHead from '../components/BaseHead.astro'; +import BaseLayout from '../components/BaseLayout.astro'; - export const layout = 'layouts/base.astro'; - export function setup({ context }) { - return {}; - } +export let content: any; --- +<html> -<style> - .cover-wrapper { - width: 100%; - height: 44vh; - min-height: 20rem; - max-height: 30rem; - position: relative; - background: #2a85ca40; - overflow: hidden; - } - .cover, - .cover-blur { - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - height: 100%; - width: 100%; - } - .cover-blur { - object-fit: cover; - filter: blur(3px) brightness(1.5); - transform: scale(1.1); - } - .cover { - object-fit: contain; - filter: brightness(1.5); - } - @media (max-width: 1200px) { +<head> + <style> + .cover-wrapper { + width: 100%; + height: 44vh; + min-height: 20rem; + max-height: 30rem; + position: relative; + background: #2a85ca40; + overflow: hidden; + } + .cover, + .cover-blur { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + height: 100%; + width: 100%; + } .cover-blur { object-fit: cover; + filter: blur(3px) brightness(1.5); + transform: scale(1.1); } .cover { - object-fit: cover; + object-fit: contain; + filter: brightness(1.5); } - } -</style> + @media (max-width: 1200px) { + .cover-blur { + object-fit: cover; + } + .cover { + object-fit: cover; + } + } + </style> + <BaseHead title={content.title} description={content.description} permalink="TODO" /> +</head> + +<body> + <BaseLayout> -<div class="cover-wrapper"> - <img class="cover-blur" src={context.cover} alt=""/> - <img class="cover" src={context.cover} alt=""/> -</div> + <div class="cover-wrapper"> + <img class="cover-blur" src={content.cover} alt=""/> + <img class="cover" src={content.cover} alt=""/> + </div> -<div class="container"> - <section class="snow-view__docs has-subnav"> + <div class="container"> + <section class="snow-view__docs has-subnav"> - <aside id="nav-primary" class="snow-view-nav"> - <Menu /> - </aside> + <aside id="nav-primary" class="snow-view-nav"> + <Menu /> + </aside> - <article class="snow-view-main"> - <div class="content"> - <h2 class="content-title"> - {context.title} - </h2> - <div class="content-layout"> - <div class="content-body"> - <slot></slot> + <article class="snow-view-main"> + <div class="content"> + <h2 class="content-title"> + {content.title} + </h2> + <div class="content-layout"> + <div class="content-body"> + {content.body} + </div> + </div> </div> - </div> - </div> - </article> + </article> + + <Subnav title={content.title} headers={content.headers} /> + </section> + </div> + </BaseLayout> +</body> - <Subnav title={context.title} headers={context.content.headers} /> - </section> -</div>
\ No newline at end of file +</html>
\ No newline at end of file diff --git a/examples/snowpack/astro/layouts/content.astro b/examples/snowpack/astro/layouts/content.astro index 1d72bed9f..8a7504264 100644 --- a/examples/snowpack/astro/layouts/content.astro +++ b/examples/snowpack/astro/layouts/content.astro @@ -1,37 +1,45 @@ --- - import Subnav from '../components/Subnav.astro'; - import Menu from '../components/Menu.astro'; - - export const layout = 'layouts/base.astro'; - export function setup({ context }) { - return { - context: { - } - }; - } +import Subnav from '../components/Subnav.astro'; +import Menu from '../components/Menu.astro'; +import BaseHead from '../components/BaseHead.astro'; +import BaseLayout from '../components/BaseLayout.astro'; + +export let content: any; --- -<div class="container"> - <section class="snow-view__docs has-subnav"> +<html> + +<head> + <BaseHead title={content.title} description={content.description} permalink="TODO" /> +</head> - <aside id="nav-primary" class="snow-view-nav"> - <Menu /> - </aside> +<body> + <BaseLayout> + <div class="container"> + <section class="snow-view__docs has-subnav"> - <Subnav title={context.title} headers={context.content.headers} /> + <aside id="nav-primary" class="snow-view-nav"> + <Menu /> + </aside> - <article class="snow-view-main"> - <div class="content"> - <h2 class="content-title"> - {context.title} - </h2> - <div class="content-layout"> - <div class="content-body"> - <slot></slot> + <Subnav title={content.title} headers={content.headers} /> + + <article class="snow-view-main"> + <div class="content"> + <h2 class="content-title"> + {content.title} + </h2> + <div class="content-layout"> + <div class="content-body"> + <slot></slot> + </div> + </div> </div> - </div> - </div> - </article> + </article> + + </section> + </div> + </BaseLayout> +</body> - </section> -</div>
\ No newline at end of file +</html>
\ No newline at end of file diff --git a/examples/snowpack/astro/layouts/main.astro b/examples/snowpack/astro/layouts/main.astro deleted file mode 100644 index cb1787a50..000000000 --- a/examples/snowpack/astro/layouts/main.astro +++ /dev/null @@ -1,21 +0,0 @@ ---- - import Menu from '../components/Menu.astro'; - export const layout = 'layouts/base.astro'; - export function setup({ context }) { - return {}; - } ---- - -<div class="container"> - <section class="snow-view__docs is-full"> - - <aside id="nav-primary" class="snow-view-nav"> - <Menu /> - </aside> - - <article class="snow-view-main"> - <slot></slot> - </article> - - </section> -</div>
\ No newline at end of file diff --git a/examples/snowpack/astro/layouts/post.astro b/examples/snowpack/astro/layouts/post.astro index 3528f0cd8..8f0a3c52b 100644 --- a/examples/snowpack/astro/layouts/post.astro +++ b/examples/snowpack/astro/layouts/post.astro @@ -1,127 +1,136 @@ --- - import { format as formatDate, parseISO } from 'date-fns'; - export const layout = 'layouts/base.astro'; - export function setup({ context }) { - return {}; - } ---- - -<astro:head> - <link rel="stylesheet" href="/css/legacy-post.css" /> -</astro:head> +import BaseHead from '../components/BaseHead.astro'; +import BaseLayout from '../components/BaseLayout.astro'; +import { format as formatDate, parseISO } from 'date-fns'; -<style> - .markdown-body img, - .markdown-body video, - .markdown-body iframe { - box-shadow: 0px 5px 12px 0 #CCC; - border-radius: 3px; - min-width: 130%; - width: 130%; - margin-left: -15%; - margin-right: -15%; - margin-top: 4rem; - margin-bottom: -1rem; - } +export let content: any; +--- - @media (max-width: 860px) { +<html> +<head> + <style> .markdown-body img, .markdown-body video, .markdown-body iframe { - min-width: 100%; - margin-left: 0; - margin-right: 0; - margin-bottom: -2rem; + box-shadow: 0px 5px 12px 0 #CCC; + border-radius: 3px; + min-width: 130%; + width: 130%; + margin-left: -15%; + margin-right: -15%; + margin-top: 4rem; + margin-bottom: -1rem; } - } - - .markdown-body table td:nth-child(1) { - white-space: nowrap; - } - - .markdown-body, - .fbody-header { - max-width: 840px; - } - - .markdown-body { - font-size: 18px; - margin-bottom: 20vh; - } - - .markdown-body h2 { - font-size: 1.8em; - } - - @media (max-width: 860px) { + + @media (max-width: 860px) { + + .markdown-body img, + .markdown-body video, + .markdown-body iframe { + min-width: 100%; + margin-left: 0; + margin-right: 0; + margin-bottom: -2rem; + } + } + + .markdown-body table td:nth-child(1) { + white-space: nowrap; + } + .markdown-body, - .toc { - padding: 1em; + .fbody-header { + max-width: 840px; } - } - - @media (max-width: 740px) { - .markdown-body img, - .markdown-body iframe { - max-width: 108%; - margin-left: -4%; - margin-right: -4%; + + .markdown-body { + font-size: 18px; + margin-bottom: 20vh; } - - .grid-body { - padding: 20px 0 0 0; + + .markdown-body h2 { + font-size: 1.8em; } - } - - .header-snowpack { - font-size: 3.5rem; - text-align: center; - } - - .markdown-body h1 { - font-size: 3.5em; - } - - .markdown-body h3 .header-link { - opacity: 1; - } -</style> - -<div class="grid-extra-space"> - <div class="grid-body-header"> - <svg height="80px" style="padding-left: 8px;" viewBox="0 0 640 512" version="1.1" xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink"> - <g id="Page-1" stroke="none" stroke-width="1" fill="currentColor" fill-rule="evenodd"> - <g id="mountain-solid" transform="translate(-1.000000, 0.000000)" fill-rule="nonzero"> - <path - d="M635.92,462.7 L347.92,14.7 C342.03,5.54 331.89,0 321,0 C310.11,0 299.97,5.54 294.08,14.7 L6.08,462.7 C-0.250773249,472.547007 -0.699487627,485.064987 4.91,495.34 C10.522069,505.612419 21.2945349,512 33,512 L609,512 C620.71,512 631.48,505.61 637.09,495.33 C642.699457,485.058495 642.250708,472.543372 635.92,462.7 Z M321,91.18 L406.39,224 L321,224 L257,288 L218.94,249.94 L321,91.18 Z" - id="Shape"></path> - </g> - </g> - </svg> - <h1 class="header-snowpack">{context.title}</h1> - - - <div> - {context.tagline && <div style="margin-bottom: 1rem;">{context.tagline}</div>} - <div> - Published <a href='#published-at'>{formatDate(parseISO(context.date), 'MMMM d, yyyy')}</a> - by <a href="https://twitter.com/FredKSchott">Fred K. Schott</a> + + @media (max-width: 860px) { + .markdown-body, + .toc { + padding: 1em; + } + } + + @media (max-width: 740px) { + .markdown-body img, + .markdown-body iframe { + max-width: 108%; + margin-left: -4%; + margin-right: -4%; + } + + .grid-body { + padding: 20px 0 0 0; + } + } + + .header-snowpack { + font-size: 3.5rem; + text-align: center; + } + + .markdown-body h1 { + font-size: 3.5em; + } + + .markdown-body h3 .header-link { + opacity: 1; + } + </style> + <BaseHead title={content.title} description={content.description} permalink="TODO" /> + <link rel="stylesheet" href="/css/legacy-post.css" /> +</head> + +<body> + <BaseLayout> + + <div class="grid-extra-space"> + <div class="grid-body-header"> + <svg height="80px" style="padding-left: 8px;" viewBox="0 0 640 512" version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <g id="Page-1" stroke="none" stroke-width="1" fill="currentColor" fill-rule="evenodd"> + <g id="mountain-solid" transform="translate(-1.000000, 0.000000)" fill-rule="nonzero"> + <path + d="M635.92,462.7 L347.92,14.7 C342.03,5.54 331.89,0 321,0 C310.11,0 299.97,5.54 294.08,14.7 L6.08,462.7 C-0.250773249,472.547007 -0.699487627,485.064987 4.91,495.34 C10.522069,505.612419 21.2945349,512 33,512 L609,512 C620.71,512 631.48,505.61 637.09,495.33 C642.699457,485.058495 642.250708,472.543372 635.92,462.7 Z M321,91.18 L406.39,224 L321,224 L257,288 L218.94,249.94 L321,91.18 Z" + id="Shape"></path> + </g> + </g> + </svg> + <h1 class="header-snowpack">{content.title}</h1> + + + <div> + {content.tagline && <div style="margin-bottom: 1rem;">{content.tagline}</div>} + <div> + Published <a href='#published-at'>{formatDate(parseISO(content.date), 'MMMM d, yyyy')}</a> + by <a href="https://twitter.com/FredKSchott">Fred K. Schott</a> + </div> + </div> + + <!-- Place this tag where you want the button to render. --> + <div class="hidden-mobile" style="text-align: center; margin-top: 0.5rem; filter: scale(2);"> + <a class="github-button" href="https://github.com/snowpackjs/snowpack" data-icon="octicon-star" data-size="large" + data-show-count="true" aria-label="Star snowpackjs/snowpack on GitHub">Star</a> + </div> + <!-- Place this tag in your head or just before your close body tag. --> + <script defer src="https://buttons.github.io/buttons.js"></script> </div> </div> - - <!-- Place this tag where you want the button to render. --> - <div class="hidden-mobile" style="text-align: center; margin-top: 0.5rem; filter: scale(2);"> - <a class="github-button" href="https://github.com/snowpackjs/snowpack" data-icon="octicon-star" data-size="large" - data-show-count="true" aria-label="Star snowpackjs/snowpack on GitHub">Star</a> + <div class="grid-body"> + <article class="markdown-body"> + <slot></slot> + </article> </div> - <!-- Place this tag in your head or just before your close body tag. --> - <script defer src="https://buttons.github.io/buttons.js"></script> - </div> -</div> -<div class="grid-body"> - <article class="markdown-body"> - <slot></slot> - </article> -</div> + </BaseLayout> +</body> + +</html>
\ No newline at end of file diff --git a/examples/snowpack/astro/pages/404.astro b/examples/snowpack/astro/pages/404.astro index 9687c2d9b..4677ed50d 100644 --- a/examples/snowpack/astro/pages/404.astro +++ b/examples/snowpack/astro/pages/404.astro @@ -1,19 +1,26 @@ --- - export const layout = 'layouts/main.astro'; +import BaseHead from '../components/BaseHead.astro'; +import MainLayout from '../components/MainLayout.astro'; - export function setup({ context }) { - return { - context: { - title: '404 - Not Found', - } - }; - } +let title = 'Not Found'; +let description = 'Snowpack is a lightning-fast frontend build tool, designed for the modern web.'; --- -<h2 class="content-title"> - {context.title} -</h2> +<html> -<div class="content"> - <a href="/">Go Home</a> -</div>
\ No newline at end of file +<head> + <BaseHead title={title} description={description} permalink="TODO" /> +</head> + +<body> + <MainLayout> + <h2 class="content-title"> + {title} + </h2> + <div class="content"> + <a href="/">Go Home</a> + </div> + </MainLayout> +</body> + +</html>
\ No newline at end of file diff --git a/examples/snowpack/astro/pages/guides.astro b/examples/snowpack/astro/pages/guides.astro index 093284869..43c1f8c5c 100644 --- a/examples/snowpack/astro/pages/guides.astro +++ b/examples/snowpack/astro/pages/guides.astro @@ -1,73 +1,86 @@ --- - import Card from '../components/Card.jsx'; +import Card from '../components/Card.jsx'; +import BaseHead from '../components/BaseHead.astro'; +import MainLayout from '../components/MainLayout.astro'; - export const layout = 'layouts/main.astro'; - - // mocked for now, to be added later - // 1. import {paginate} from 'magicthing'; - // 2. export default function ({paginate}) { - function paginate(options) { - if (options.tag === 'guide') { - return [ - { title: 'Test guide 1', href: "#" }, - { title: 'Test guide 2', href: "#" }, - ]; - } - if (options.tag === 'communityGuides') { - return [{ title: 'Test communityGuides', href: "#" }]; - } - return []; +// mocked for now, to be added later +// 1. import {paginate} from 'magicthing'; +// 2. export default function ({paginate}) { +function paginate(options) { + if (options.tag === 'guide') { + return [ + { title: 'Test guide 1', href: "#" }, + { title: 'Test guide 2', href: "#" }, + ]; } - - export function setup({ context, /* paginate */ }) { - return { - context: { - title: 'Guides', - description: "Snowpack's usage and integration guides.", - guides: paginate({ - files: '/posts/guides/*.md', - // sort: ((a, b) => new Date(b) - new Date(a)), - tag: 'guide', - limit: 10, - // page: query.page, - }), - communityGuides: paginate({ - files: '/posts/guides/*.md', - // sort: ((a, b) => new Date(b) - new Date(a)), - tag: 'communityGuides', - limit: 10, - }), - } - }; + if (options.tag === 'communityGuides') { + return [{ title: 'Test communityGuides', href: "#" }]; } + return []; +} + +let title = 'Guides'; +let description = 'Snowpack\'s usage and integration guides.'; +let guides; +let communityGuides; + + +export function setup({ /* paginate */ }) { + guides = paginate({ + files: '/posts/guides/*.md', + // sort: ((a, b) => new Date(b) - new Date(a)), + tag: 'guide', + limit: 10, + // page: query.page, + }); + communityGuides = paginate({ + files: '/posts/guides/*.md', + // sort: ((a, b) => new Date(b) - new Date(a)), + tag: 'communityGuides', + limit: 10, + }); + return {}; +} --- -<h2 class="content-title"> - {context.title} -</h2> +<html> + +<head> + <BaseHead title={title} description={description} permalink="TODO" /> +</head> + +<body> + <MainLayout> + <h2 class="content-title"> + {title} + </h2> + + <h3 class="content-title"> + Using Snowpack + </h3> -<h3 class="content-title"> - Using Snowpack -</h3> + <div class="content"> + <ul> + {guides.map((post) => { + return <li><a href={post.href}>{post.title}</a></li>; + })} + </ul> + </div> -<div class="content"> - <ul> - {context.guides.map((post) => { - return <li><a href={post.href}>{post.title}</a></li>; - })} - </ul> -</div> + <br /> + <br /> -<br /> -<br /> + <h3 class="content-title"> + Popular Integration Guides + </h3> -<h3 class="content-title"> - Popular Integration Guides -</h3> + <div class="card-grid card-grid-4"> + {communityGuides.map((post) => { + return + <Card item={post} />; + })} + </div> + </MainLayout> +</body> -<div class="card-grid card-grid-4"> - {context.communityGuides.map((post) => { - return - <Card item={post} />; - })} -</div>
\ No newline at end of file +</html>
\ No newline at end of file diff --git a/examples/snowpack/astro/pages/index.astro b/examples/snowpack/astro/pages/index.astro index 3911bcc84..3e2adccda 100644 --- a/examples/snowpack/astro/pages/index.astro +++ b/examples/snowpack/astro/pages/index.astro @@ -1,18 +1,19 @@ --- - import Menu from '../components/Menu.astro'; - import Hero from '../components/Hero.astro'; +import Menu from '../components/Menu.astro'; +import Hero from '../components/Hero.astro'; +import BaseHead from '../components/BaseHead.astro'; +import BaseLayout from '../components/BaseLayout.astro'; - export const layout = 'layouts/base.astro'; - export function setup({ context }) { - return {}; - } +let title = 'Snowpack'; +let description = 'Snowpack is a lightning-fast frontend build tool, designed for the modern web.'; --- -<astro:head> - <meta charset="AAA" /> +<html> + +<head> <style lang="scss"> @use '../../public/css/var' as *; - + .top { text-align: left; } @@ -56,113 +57,96 @@ margin: 0.5em; } </style> -</astro:head> -<Hero bar="{context.title}"></Hero> + <BaseHead title={title} description={description} permalink="TODO" /> +</head> -<div foo="{context.title}" class="container" style="margin: 0 auto"> - <section class="snow-view__docs is-full is-home"> - <aside id="nav-primary" class="snow-view-nav"> - <Menu></Menu> - </aside> +<body> + <BaseLayout> + <Hero bar="{title}" /> + <div foo="{title}" class="container" style="margin: 0 auto"> + <section class="snow-view__docs is-full is-home"> + <aside id="nav-primary" class="snow-view-nav"> + <Menu></Menu> + </aside> - <article class="snow-view-main"> - <div class="content"> - <article class="grid-body"> - <a - class="img-banner" - href="https://osawards.com/javascript/2020" - target="_blank" - rel="noopener noreferrer" - > - <img - src="/img/JSAwardWinner.png" - alt="2020 JavaScript Open Source Award Winner banner" - /> - </a> + <article class="snow-view-main"> + <div class="content"> + <article class="grid-body"> + <a class="img-banner" href="https://osawards.com/javascript/2020" target="_blank" + rel="noopener noreferrer"> + <img src="/img/JSAwardWinner.png" alt="2020 JavaScript Open Source Award Winner banner" /> + </a> - <div class="content markdown-body feature-list"> - <div class="feature-list-top"> - <p> - <strong - >Snowpack is a lightning-fast frontend build tool, designed - for the modern web.</strong - > - It is an alternative to heavier, more complex bundlers like - webpack or Parcel in your development workflow. Snowpack - leverages JavaScript's native module system (<a - href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import" - >known as ESM</a - >) to avoid unnecessary work and stay fast no matter how big - your project grows. - </p> - <p> - Once you try it, it's impossible to go back to anything else. - </p> - </div> + <div class="content markdown-body feature-list"> + <div class="feature-list-top"> + <p> + <strong>Snowpack is a lightning-fast frontend build tool, designed + for the modern web.</strong> + It is an alternative to heavier, more complex bundlers like + webpack or Parcel in your development workflow. Snowpack + leverages JavaScript's native module system (<a + href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import">known + as + ESM</a>) to avoid unnecessary work and stay fast no matter how big + your project grows. + </p> + <p> + Once you try it, it's impossible to go back to anything else. + </p> + </div> - <ul class="feature-list-bullets"> - <li class="feature-list-bullet"> - <h3>Instant startup</h3> - Snowpack's unbundled web development server - <strong>starts up in 50ms or less</strong> - and stays fast in large projects. - </li> - <li class="feature-list-bullet"> - <h3>Build once, cache forever</h3> - Snowpack never builds the same file twice. Powered by - JavaScript’s native module system (ESM) in the browser. - </li> - <li class="feature-list-bullet"> - <h3>HMR feat. Fast Refresh</h3> - No refresh required. See changes reflected instantly in the - browser with - <a href="/concepts/hot-module-replacement" - >HMR + Fast Refresh</a - > - for React, Preact & Svelte. - </li> - <li class="feature-list-bullet"> - <h3>Out-of-the-box support</h3> - Enjoy Snowpack's built-in support for JSX, TypeScript, React, - Preact, CSS Modules - <a href="/reference/supported-files">and more.</a> - </li> - <li class="feature-list-bullet"> - <h3>Optimize for production</h3> - Build for production with built-in optimizations and plugin - support for your favorite bundlers. - </li> - <li class="feature-list-bullet"> - <h3>Plugins? Plugins!</h3> - Babel? Sass? MDX? Browse the entire - <a href="/plugins">Snowpack Plugin Catalog</a> - to connect your favorite build tool (or - <a href="/reference/plugins">create your own!</a>) - </li> - </ul> + <ul class="feature-list-bullets"> + <li class="feature-list-bullet"> + <h3>Instant startup</h3> + Snowpack's unbundled web development server + <strong>starts up in 50ms or less</strong> + and stays fast in large projects. + </li> + <li class="feature-list-bullet"> + <h3>Build once, cache forever</h3> + Snowpack never builds the same file twice. Powered by + JavaScript’s native module system (ESM) in the browser. + </li> + <li class="feature-list-bullet"> + <h3>HMR feat. Fast Refresh</h3> + No refresh required. See changes reflected instantly in the + browser with + <a href="/concepts/hot-module-replacement">HMR + Fast Refresh</a> + for React, Preact & Svelte. + </li> + <li class="feature-list-bullet"> + <h3>Out-of-the-box support</h3> + Enjoy Snowpack's built-in support for JSX, TypeScript, React, + Preact, CSS Modules + <a href="/reference/supported-files">and more.</a> + </li> + <li class="feature-list-bullet"> + <h3>Optimize for production</h3> + Build for production with built-in optimizations and plugin + support for your favorite bundlers. + </li> + <li class="feature-list-bullet"> + <h3>Plugins? Plugins!</h3> + Babel? Sass? MDX? Browse the entire + <a href="/plugins">Snowpack Plugin Catalog</a> + to connect your favorite build tool (or + <a href="/reference/plugins">create your own!</a>) + </li> + </ul> - <div class="feature-list-buttons"> - <a - href="/tutorials/quick-start" - class="button button-primary feature-list-button" - >Get started</a - > - <a - href="/concepts/how-snowpack-works" - class="button feature-list-button" - >Learn more</a - > - </div> + <div class="feature-list-buttons"> + <a href="/tutorials/quick-start" class="button button-primary feature-list-button">Get started</a> + <a href="/concepts/how-snowpack-works" class="button feature-list-button">Learn more</a> + </div> + </div> + </article> </div> </article> - </div> - </article> - </section> -</div> + </section> + </div> + </BaseLayout> + <!-- Place this tag in your head or just before your close body tag. --> + <script async="async" defer="defer" src="https://buttons.github.io/buttons.js"></script> +</body> -<!-- Place this tag in your head or just before your close body tag. --> -<script - async="async" - defer="defer" - src="https://buttons.github.io/buttons.js" -></script> +</html>
\ No newline at end of file diff --git a/examples/snowpack/astro/pages/news.astro b/examples/snowpack/astro/pages/news.astro index 3cbe694b5..492313d5e 100644 --- a/examples/snowpack/astro/pages/news.astro +++ b/examples/snowpack/astro/pages/news.astro @@ -1,78 +1,86 @@ --- - import Card from '../components/Card.jsx'; - import CompanyLogo from '../components/CompanyLogo.jsx'; - import NewsAssets from '../components/NewsAssets.svelte'; - import NewsTitle from '../components/NewsTitle.vue'; - - export const layout = 'layouts/main.astro'; - - import news from '../data/news.json'; - import users from '../data/users.json'; - - export async function setup({ context, request, fetch }) { - const pokemonData = await fetch(`https://pokeapi.co/api/v2/pokemon/ditto`); - return { - context: { - title: 'Community & News', - description: "Snowpack community news and companies that use Snowpack.", - // Using Snowpack? Want to be featured on snowpack.dev? - // Add your project, organization, or company to the end of this list! - news, - users, - pokemonData: await pokemonData.json(), - } - } - } +import Card from '../components/Card.jsx'; +import CompanyLogo from '../components/CompanyLogo.jsx'; +import NewsAssets from '../components/NewsAssets.svelte'; +import NewsTitle from '../components/NewsTitle.vue'; +import BaseHead from '../components/BaseHead.astro'; +import MainLayout from '../components/MainLayout.astro'; + +// Using Snowpack? Want to be featured on snowpack.dev? +// Add your project, organization, or company to the end of this list! +import news from '../data/news.json'; +import users from '../data/users.json'; + +let title = 'Community & News'; +let description = 'Snowpack community news and companies that use Snowpack.'; +let pokemonData; + +export async function setup({ context, request, fetch }) { + const pokemonDataReq = await fetch(`https://pokeapi.co/api/v2/pokemon/ditto`); + pokemonData = await pokemonDataReq.json(); + return {}; +} --- -<NewsTitle title={context.title} /> - -<p> - Get the latest news, blog posts, and tutorials on Snowpack. <a href="/feed.xml">Also available via RSS.</a> -</p> - -<p> - Got something that you think we should feature? - <a href="https://github.com/snowpackjs/snowpack/edit/main/www/_data/news.js">Submit it!</a> -</p> - -<p> - In case you're curious, the best pokemon is <strong>{context.pokemonData.name}.</strong> -</p> - -<div class="card-grid card-grid-3"> - <article class="discord-banner"> - <a href="https://discord.gg/snowpack" style="flex-shrink: 0; height: 48px;"><img alt="Join us on Discord!" - src="https://img.shields.io/discord/712696926406967308.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2" - style="height: 48px; border: none; margin-right: 1rem; filter: brightness(1.2) contrast(1.5);" /></a> - <div>Join us on Discord to discuss Snowpack, meet other developers in our community, and show off what you’re - working on!</div> - </article> - - {context.news.reverse().map((item: any) => - <Card:dynamic item={item} />)} -</div> - -<div class="content"> - - <h3>Who's Using Snowpack?</h3> - - <div class="company-logos"> - - {context.users.map((user) => - <CompanyLogo user={user} />)} - - <a href="https://github.com/snowpackjs/snowpack/edit/main/www/_template/news.md" target="_blank" - title="Add Your Project/Company!" class="add-company-button"> - <svg style="height: 22px; margin-right: 8px;" aria-hidden="true" focusable="false" data-prefix="fas" - data-icon="plus" class="company-logo" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"> - <path fill="currentColor" - d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"> - </path> - </svg> - Add your logo - </a> - </div> - - <NewsAssets /> -</div>
\ No newline at end of file +<html> + +<head> + <BaseHead title={title} description={description} permalink="TODO" /> +</head> + +<body> + <MainLayout> + <NewsTitle title={title} /> + <p> + Get the latest news, blog posts, and tutorials on Snowpack. <a href="/feed.xml">Also available via RSS.</a> + </p> + + <p> + Got something that you think we should feature? + <a href="https://github.com/snowpackjs/snowpack/edit/main/www/_data/news.js">Submit it!</a> + </p> + + <p> + In case you're curious, the best pokemon is <strong>{pokemonData.name}.</strong> + </p> + + <div class="card-grid card-grid-3"> + <article class="discord-banner"> + <a href="https://discord.gg/snowpack" style="flex-shrink: 0; height: 48px;"><img alt="Join us on Discord!" + src="https://img.shields.io/discord/712696926406967308.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2" + style="height: 48px; border: none; margin-right: 1rem; filter: brightness(1.2) contrast(1.5);" /></a> + <div>Join us on Discord to discuss Snowpack, meet other developers in our community, and show off what you’re + working on!</div> + </article> + + {news.reverse().map((item: any) => + <Card:dynamic item={item} />)} + </div> + + <div class="content"> + + <h3>Who's Using Snowpack?</h3> + + <div class="company-logos"> + + {users.map((user) => + <CompanyLogo user={user} />)} + + <a href="https://github.com/snowpackjs/snowpack/edit/main/www/_template/news.md" target="_blank" + title="Add Your Project/Company!" class="add-company-button"> + <svg style="height: 22px; margin-right: 8px;" aria-hidden="true" focusable="false" data-prefix="fas" + data-icon="plus" class="company-logo" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"> + <path fill="currentColor" + d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"> + </path> + </svg> + Add your logo + </a> + </div> + + <NewsAssets /> + </div> + </MainLayout> +</body> + +</html>
\ No newline at end of file diff --git a/examples/snowpack/astro/pages/plugins.astro b/examples/snowpack/astro/pages/plugins.astro index cf66f8885..24a5d1bde 100644 --- a/examples/snowpack/astro/pages/plugins.astro +++ b/examples/snowpack/astro/pages/plugins.astro @@ -1,70 +1,72 @@ --- - import news from '../data/news.json'; - import users from '../data/users.json'; - import PluginSearchPage from '../components/PluginSearchPage.jsx'; +import PluginSearchPage from '../components/PluginSearchPage.jsx'; +import BaseHead from '../components/BaseHead.astro'; +import MainLayout from '../components/MainLayout.astro'; - export const layout = 'layouts/main.astro'; - - export function setup({ context }) { - return { - context: { - title: 'The Snowpack Plugin Catalog', - description: - 'Snowpack plugins allow for configuration-minimal tooling integration.', - }, - }; - } +let title = 'The Snowpack Plugin Catalog'; +let description = 'Snowpack plugins allow for configuration-minimal tooling integration.'; --- -<style lang="scss"> - .intro { - margin-top: 1rem; - margin-bottom: 1rem; - line-height: 1.5; - text-align: left; +<html> - a { - color: #2e5e82; +<head> + <BaseHead title={title} description={description} permalink="TODO" /> + <style lang="scss"> + .intro { + margin-top: 1rem; + margin-bottom: 1rem; + line-height: 1.5; + text-align: left; + + a { + color: #2e5e82; + } } - } - .subheading { - margin-top: -2.5rem; - margin-bottom: 0; - color: #2e5e82; - font-weight: 500; - font-size: 1em; - font-family: 'Overpass', sans-serif; - letter-spacing: -0.02em; - text-align: left; + .subheading { + margin-top: -2.5rem; + margin-bottom: 0; + color: #2e5e82; + font-weight: 500; + font-size: 1em; + font-family: 'Overpass', sans-serif; + letter-spacing: -0.02em; + text-align: left; - @media (min-width: 600px) { - font-size: 1.5em; + @media (min-width: 600px) { + font-size: 1.5em; + } } - } - .zero-heading { - margin-top: 1.5rem; - margin-bottom: 1.5rem; - font-weight: 700; - font-size: 1.4em; - text-align: left; + .zero-heading { + margin-top: 1.5rem; + margin-bottom: 1.5rem; + font-weight: 700; + font-size: 1.4em; + text-align: left; - @media (min-width: 600px) { - font-size: 1.5em; + @media (min-width: 600px) { + font-size: 1.5em; + } } - } -</style> + </style> +</head> + +<body> + <MainLayout> + <h2 class="content-title">{ title }</h2> -<h2 class="content-title">{ context.title }</h2> + <h3 class="pluginPage-subheading"> + Customize Snowpack with optimized build plugins. + </h3> + <p class="pluginPage-intro"> + To learn more about our plugin system, check out the + <a href="/reference/plugins">Plugin API.</a><br />Can't find what you need? + <a href="/reference/plugins">Creating your own plugin is easy!</a> + </p> -<h3 class="pluginPage-subheading"> - Customize Snowpack with optimized build plugins. -</h3> -<p class="pluginPage-intro"> - To learn more about our plugin system, check out the - <a href="/reference/plugins">Plugin API.</a><br />Can't find what you need? - <a href="/reference/plugins">Creating your own plugin is easy!</a> -</p> + <PluginSearchPage:dynamic /> + </MainLayout> +</body> -<PluginSearchPage:dynamic /> +</html> diff --git a/examples/snowpack/astro/pages/proof-of-concept-dynamic/[slug].astro b/examples/snowpack/astro/pages/proof-of-concept-dynamic/[slug].astro index c81ed0d94..2b05bcf66 100644 --- a/examples/snowpack/astro/pages/proof-of-concept-dynamic/[slug].astro +++ b/examples/snowpack/astro/pages/proof-of-concept-dynamic/[slug].astro @@ -1,23 +1,34 @@ --- - import Subnav from '../components/Subnav.astro'; - import { content as Menu } from '../components/Menu.astro'; - // import contentful from 'skypack:contentful'; +import Subnav from '../components/Subnav.astro'; +import Menu from '../components/Menu.astro'; +import BaseHead from '../components/BaseHead.astro'; +import BaseLayout from '../components/BaseLayout.astro'; +// import contentful from 'skypack:contentful'; - export default async function ({ params }) { - const entry = await contentful.getEntry(params.slug); - return { title: entry.fields.title, description: entry.fields.description, layout: 'layouts/base.astro', props: { entry } }; - } +let title = 'Community & News'; +let description = 'Snowpack community news and companies that use Snowpack.'; +let entry; + +export default async function ({ params }) { + entry = await contentful.getEntry(params.slug); + return { title: entry.fields.title, description: entry.fields.description, layout: 'layouts/base.astro', props: { entry } }; +} --- -<div class="container"> - <section class="snow-view__docs has-subnav"> +<html> + +<head> + <BaseHead title={title} description={description} permalink="TODO" /> +</head> +<body> + <MainLayout> + <div class="container"> + <section class="snow-view__docs has-subnav"> <aside id="nav-primary" class="snow-view-nav"> <Menu /> </aside> - - <Subnav title={context.title} headers={context.content.headers} /> - + <Subnav title={context.title} headers={context.content.headers} /> <article class="snow-view-main"> <div class="content"> <h2 class="content-title"> @@ -30,6 +41,9 @@ </div> </div> </article> + </section> + </div> + </MainLayout> +</body> - </section> -</div>
\ No newline at end of file +</html>
\ No newline at end of file diff --git a/src/@types/astro.ts b/src/@types/astro.ts index 9ec2aec53..8a92983f8 100644 --- a/src/@types/astro.ts +++ b/src/@types/astro.ts @@ -11,7 +11,7 @@ export interface AstroConfig { dist: string; projectRoot: URL; astroRoot: URL; - extensions?: Record<string, ValidExtensionPlugins> + extensions?: Record<string, ValidExtensionPlugins>; } export interface JsxItem { @@ -21,7 +21,7 @@ export interface JsxItem { export interface TransformResult { script: string; - head: JsxItem | undefined; + props: string[]; items: JsxItem[]; } diff --git a/src/codegen/index.ts b/src/codegen/index.ts index d248b2a60..2eb289887 100644 --- a/src/codegen/index.ts +++ b/src/codegen/index.ts @@ -99,20 +99,17 @@ const defaultExtensions: Readonly<Record<string, ValidExtensionPlugins>> = { '.astro': 'astro', '.jsx': 'react', '.vue': 'vue', - '.svelte': 'svelte' + '.svelte': 'svelte', }; function getComponentWrapper(_name: string, { type, url }: ComponentInfo, compileOptions: CompileOptions) { - const { - resolve, - extensions = defaultExtensions - } = compileOptions; + const { resolve, extensions = defaultExtensions } = compileOptions; const [name, kind] = _name.split(':'); const plugin = extensions[type] || defaultExtensions[type]; - if(!plugin) { + if (!plugin) { throw new Error(`No supported plugin found for extension ${type}`); } @@ -142,7 +139,9 @@ function getComponentWrapper(_name: string, { type, url }: ComponentInfo, compil case 'react': { if (kind === 'dynamic') { return { - wrapper: `__react_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.js'))}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve('react')}', '${resolve('react-dom')}')`, + wrapper: `__react_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.js'))}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve( + 'react' + )}', '${resolve('react-dom')}')`, wrapperImport: `import {__react_dynamic} from '${internalImport('render/react.js')}';`, }; } else { @@ -215,6 +214,9 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro // Compile scripts as TypeScript, always const script = compileScriptSafe(ast.module ? ast.module.content : ''); + // Collect all exported variables for props + const scannedExports = eslexer.parse(script)[1].filter((n) => n !== 'setup' && n !== 'layout'); + // Todo: Validate that `h` and `Fragment` aren't defined in the script const [scriptImports] = eslexer.parse(script, 'optional-sourcename'); const components = Object.fromEntries( @@ -380,7 +382,7 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro return { script: script + '\n' + Array.from(additionalImports).join('\n'), - head: headItem, items, + props: scannedExports, }; } diff --git a/src/dev.ts b/src/dev.ts index 5c80133a7..efa7f1f6c 100644 --- a/src/dev.ts +++ b/src/dev.ts @@ -72,4 +72,4 @@ export default async function (astroConfig: AstroConfig) { function formatErrorForBrowser(error: Error) { // TODO make this pretty. return error.toString(); -}
\ No newline at end of file +} diff --git a/src/frontend/render/react.ts b/src/frontend/render/react.ts index d55d30c00..cd037c35f 100644 --- a/src/frontend/render/react.ts +++ b/src/frontend/render/react.ts @@ -3,13 +3,7 @@ import ReactDOMServer from 'react-dom/server'; export function __react_static(ReactComponent: any) { return (attrs: Record<string, any>, ...children: any): string => { - let html = ReactDOMServer.renderToString( - React.createElement( - ReactComponent, - attrs, - children - ) - ); + let html = ReactDOMServer.renderToString(React.createElement(ReactComponent, attrs, children)); return html; }; } diff --git a/src/micromark-encode.ts b/src/micromark-encode.ts index d205d13e3..e3b328224 100644 --- a/src/micromark-encode.ts +++ b/src/micromark-encode.ts @@ -32,4 +32,4 @@ const plugin: HtmlExtension = { }, }; -export { plugin as encodeMarkdown };
\ No newline at end of file +export { plugin as encodeMarkdown }; diff --git a/src/runtime.ts b/src/runtime.ts index 889224548..aff5ee7d2 100644 --- a/src/runtime.ts +++ b/src/runtime.ts @@ -69,6 +69,7 @@ async function load(config: RuntimeConfig, rawPathname: string | undefined): Pro href: fullurl.toString(), }, children: [], + props: {}, })) as string; return { @@ -103,7 +104,7 @@ export async function createRuntime(astroConfig: AstroConfig, logging: LogOption // Workaround for SKY-251 const astroPlugOptions: { resolve?: (s: string) => string; - extensions?: Record<string, string> + extensions?: Record<string, string>; } = { extensions }; if (existsSync(new URL('./package-lock.json', projectRoot))) { const pkgLockStr = await readFile(new URL('./package-lock.json', projectRoot), 'utf-8'); @@ -128,10 +129,7 @@ export async function createRuntime(astroConfig: AstroConfig, logging: LogOption }, packageOptions: { knownEntrypoints: ['preact-render-to-string'], - external: [ - '@vue/server-renderer', - 'node-fetch' - ], + external: ['@vue/server-renderer', 'node-fetch'], }, }); const snowpack = await startSnowpackServer({ diff --git a/src/transform2.ts b/src/transform2.ts index 27956fb9f..47c3659e7 100644 --- a/src/transform2.ts +++ b/src/transform2.ts @@ -52,7 +52,7 @@ async function convertMdToJsx( contents: string, { compileOptions, filename, fileID }: { compileOptions: CompileOptions; filename: string; fileID: string } ): Promise<TransformResult> { - const { data: _frontmatterData, content } = matter(contents); + const { data: frontmatterData, content } = matter(contents); const { headers, headersExtension } = createMarkdownHeadersCollector(); const mdHtml = micromark(content, { allowDangerousHtml: true, @@ -60,31 +60,27 @@ async function convertMdToJsx( htmlExtensions: [gfmHtml, encodeMarkdown, headersExtension], }); - const setupContext = { - ..._frontmatterData, - content: { - frontmatter: _frontmatterData, - headers, - source: content, - html: mdHtml, - }, + // TODO: Warn if reserved word is used in "frontmatterData" + const contentData: any = { + ...frontmatterData, + headers, + source: content, + html: mdHtml, }; let imports = ''; - for(let [ComponentName, specifier] of Object.entries(_frontmatterData.import || {})) { + for (let [ComponentName, specifier] of Object.entries(frontmatterData.import || {})) { imports += `import ${ComponentName} from '${specifier}';\n`; } // </script> can't be anywhere inside of a JS string, otherwise the HTML parser fails. // Break it up here so that the HTML parser won't detect it. - const stringifiedSetupContext = JSON.stringify(setupContext).replace(/\<\/script\>/g, `</scrip" + "t>`); + const stringifiedSetupContext = JSON.stringify(contentData).replace(/\<\/script\>/g, `</scrip" + "t>`); - const raw = `--- + const raw = `--- ${imports} - ${_frontmatterData.layout ? `export const layout = ${JSON.stringify(_frontmatterData.layout)};` : ''} - export function setup({context}) { - return {context: ${stringifiedSetupContext} }; - } + ${frontmatterData.layout ? `const __layout = ${JSON.stringify(frontmatterData.layout)};` : ''} + const __content = ${stringifiedSetupContext}; --- <section>${mdHtml}</section>`; @@ -115,11 +111,10 @@ export async function compileComponent( { compileOptions = defaultCompileOptions, filename, projectRoot }: { compileOptions: CompileOptions; filename: string; projectRoot: string } ): Promise<CompileResult> { const sourceJsx = await transformFromSource(source, { compileOptions, filename, projectRoot }); - const headItem = sourceJsx.head; - const headItemJsx = !headItem ? 'null' : headItem.jsx; // sort <style> tags first // TODO: remove these and inject in <head> + const isPage = path.extname(filename) === '.md' || sourceJsx.items.some((item) => item.name === 'html'); sourceJsx.items.sort((a, b) => (a.name === 'style' && b.name !== 'style' ? -1 : 0)); // return template @@ -127,61 +122,47 @@ export async function compileComponent( // <script astro></script> ${sourceJsx.script} -// \`__render()\`: Render the contents of the Astro module. "<slot:*>" elements are not -// included (see below). +// \`__render()\`: Render the contents of the Astro module. import { h, Fragment } from '${internalImport('h.js')}'; -export function __slothead(children, context) { return h(Fragment, null, ${headItemJsx}); } -function __render(props, children, context) { return h(Fragment, null, ${sourceJsx.items.map(({ jsx }) => jsx).join(',')}); } +function __render(props, ...children) { + ${sourceJsx.props.map((p) => `${p} = props.${p} ?? ${p};`).join('\n')} + return h(Fragment, null, ${sourceJsx.items.map(({ jsx }) => jsx).join(',')}); +} export default __render; `; - if (headItemJsx) { + if (isPage) { modJsx += ` // \`__renderPage()\`: Render the contents of the Astro module as a page. This is a special flow, // triggered by loading a component directly by URL. -// If the page exports a defined "layout", then load + render those first. "context", "astro:head", -// and "slot:body" should all inherit from parent layouts, merging together in the correct order. -export async function __renderPage({request, children}) { +export async function __renderPage({request, children, props}) { + const currentChild = { - __slothead, - __render, setup: typeof setup === 'undefined' ? (passthrough) => passthrough : setup, - layout: typeof layout === 'undefined' ? undefined : layout, + layout: typeof __layout === 'undefined' ? undefined : __layout, + content: typeof __content === 'undefined' ? undefined : __content, + __render, }; - // find all layouts, going up the layout chain. + const fetch = (await import('node-fetch')).default; + await currentChild.setup({request, fetch}); + const childBodyResult = await currentChild.__render(props, children); + + // find layout, if one was given. if (currentChild.layout) { - const layoutComponent = (await import('/_astro/layouts/' + layout.replace(/.*layouts\\//, "").replace(/\.astro$/, '.js'))); + const layoutComponent = (await import('/_astro/layouts/' + currentChild.layout.replace(/.*layouts\\//, "").replace(/\.astro$/, '.js'))); return layoutComponent.__renderPage({ request, - children: [currentChild, ...children], + props: {content: currentChild.content}, + children: [childBodyResult], }); } - - const isRoot = true; - const merge = (await import('deepmerge')).default; - const fetch = (await import('node-fetch')).default; - // call all children setup scripts, in order, and return. - let mergedContext = {}; - for (const child of [currentChild, ...children]) { - const childSetupResult = await child.setup({request, fetch, context: mergedContext}); - mergedContext = childSetupResult.context ? merge(mergedContext, childSetupResult.context) : mergedContext; - } - - Object.freeze(mergedContext); - - let headResult; - let bodyResult; - for (const child of children.reverse()) { - headResult = await child.__slothead([headResult], mergedContext); - bodyResult = await child.__render(undefined, [bodyResult], mergedContext); - } - return h(Fragment, null, [ - h("head", null, currentChild.__slothead([headResult], mergedContext)), - h("body", null, currentChild.__render(undefined, [bodyResult], mergedContext)), - ]); + return childBodyResult; };\n`; + } else { + modJsx += ` +export async function __renderPage() { throw new Error("No <html> page element found!"); }\n`; } return { diff --git a/test/fixtures/astro-basic/astro/pages/index.astro b/test/fixtures/astro-basic/astro/pages/index.astro index d4f6fc5a1..e6b8a1235 100644 --- a/test/fixtures/astro-basic/astro/pages/index.astro +++ b/test/fixtures/astro-basic/astro/pages/index.astro @@ -1,13 +1,14 @@ --- export function setup() { - return { - props: {} - } + return {props: {}} } --- -<astro:head> - <!-- Head Stuff --> -</astro:head> - -<h1>Hello world!</h1>
\ No newline at end of file +<html> + <head> + <!-- Head Stuff --> + </head> + <body> + <h1>Hello world!</h1> + </body> +</html> diff --git a/test/fixtures/astro-markdown/astro/layouts/content.astro b/test/fixtures/astro-markdown/astro/layouts/content.astro index 52f79400c..925a243a9 100644 --- a/test/fixtures/astro-markdown/astro/layouts/content.astro +++ b/test/fixtures/astro-markdown/astro/layouts/content.astro @@ -1,3 +1,10 @@ -<div class="container"> - <slot></slot> -</div>
\ No newline at end of file +<html> + <head> + <!-- Head Stuff --> + </head> + <body> + <div class="container"> + <slot></slot> + </div> + </body> +</html> diff --git a/test/fixtures/astro-markdown/astro/pages/index.astro b/test/fixtures/astro-markdown/astro/pages/index.astro index d4f6fc5a1..e6b8a1235 100644 --- a/test/fixtures/astro-markdown/astro/pages/index.astro +++ b/test/fixtures/astro-markdown/astro/pages/index.astro @@ -1,13 +1,14 @@ --- export function setup() { - return { - props: {} - } + return {props: {}} } --- -<astro:head> - <!-- Head Stuff --> -</astro:head> - -<h1>Hello world!</h1>
\ No newline at end of file +<html> + <head> + <!-- Head Stuff --> + </head> + <body> + <h1>Hello world!</h1> + </body> +</html> diff --git a/test/fixtures/react-component/astro/pages/index.astro b/test/fixtures/react-component/astro/pages/index.astro index 5debf6380..01ccdb33e 100644 --- a/test/fixtures/react-component/astro/pages/index.astro +++ b/test/fixtures/react-component/astro/pages/index.astro @@ -2,9 +2,11 @@ import Hello from '../components/Hello.jsx'; --- -<astro:head> - <!-- Head Stuff --> -</astro:head> - -<h1>My page</h1> -<Hello name="world" />
\ No newline at end of file +<html> + <head> + <!-- Head Stuff --> + </head> + <body> + <Hello name="world" /> + </body> +</html>
\ No newline at end of file diff --git a/test/snowpack-integration.test.js b/test/snowpack-integration.test.js index ebe21f274..e14d94a73 100644 --- a/test/snowpack-integration.test.js +++ b/test/snowpack-integration.test.js @@ -72,7 +72,7 @@ SnowpackDev('Can load every page', async () => { } const result = await runtime.load(pathname); if (result.statusCode === 500) { - failed.push(result); + failed.push({...result, pathname}); continue; } assert.equal(result.statusCode, 200, `Loading ${pathname}`); |