summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fred K. Schott <fkschott@gmail.com> 2021-03-24 16:01:28 -0700
committerGravatar GitHub <noreply@github.com> 2021-03-24 16:01:28 -0700
commita72ab10c623022860691d6a095b74dea70cc6f69 (patch)
tree0d94c752ae0d63027ec91a1fbf745a93745be6ee
parent3c24faa8cab428b17ba2f8e083f5296b1b931fe1 (diff)
downloadastro-a72ab10c623022860691d6a095b74dea70cc6f69.tar.gz
astro-a72ab10c623022860691d6a095b74dea70cc6f69.tar.zst
astro-a72ab10c623022860691d6a095b74dea70cc6f69.zip
Redesign pages, remove layout nesting (#24)
* wip * new svelte-style prop declaration is working * got it working! * revert h changes * format * style lang update
-rw-r--r--examples/snowpack/astro/components/BaseHead.astro38
-rw-r--r--examples/snowpack/astro/components/BaseLayout.astro20
-rw-r--r--examples/snowpack/astro/components/MainLayout.astro23
-rw-r--r--examples/snowpack/astro/components/Nav.astro4
-rw-r--r--examples/snowpack/astro/components/Subnav.astro14
-rw-r--r--examples/snowpack/astro/layouts/base.astro62
-rw-r--r--examples/snowpack/astro/layouts/content-with-cover.astro134
-rw-r--r--examples/snowpack/astro/layouts/content.astro66
-rw-r--r--examples/snowpack/astro/layouts/main.astro21
-rw-r--r--examples/snowpack/astro/layouts/post.astro233
-rw-r--r--examples/snowpack/astro/pages/404.astro35
-rw-r--r--examples/snowpack/astro/pages/guides.astro137
-rw-r--r--examples/snowpack/astro/pages/index.astro206
-rw-r--r--examples/snowpack/astro/pages/news.astro158
-rw-r--r--examples/snowpack/astro/pages/plugins.astro112
-rw-r--r--examples/snowpack/astro/pages/proof-of-concept-dynamic/[slug].astro42
-rw-r--r--src/@types/astro.ts4
-rw-r--r--src/codegen/index.ts18
-rw-r--r--src/dev.ts2
-rw-r--r--src/frontend/render/react.ts8
-rw-r--r--src/micromark-encode.ts2
-rw-r--r--src/runtime.ts8
-rw-r--r--src/transform2.ts91
-rw-r--r--test/fixtures/astro-basic/astro/pages/index.astro17
-rw-r--r--test/fixtures/astro-markdown/astro/layouts/content.astro13
-rw-r--r--test/fixtures/astro-markdown/astro/pages/index.astro17
-rw-r--r--test/fixtures/react-component/astro/pages/index.astro14
-rw-r--r--test/snowpack-integration.test.js2
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}`);