summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.eslintrc.cjs3
-rw-r--r--.github/workflows/nodejs.yml7
-rw-r--r--examples/snowpack/astro/pages/concepts/build-pipeline.md2
-rw-r--r--examples/snowpack/astro/pages/concepts/dev-server.md2
-rw-r--r--examples/snowpack/astro/pages/concepts/hot-module-replacement.md2
-rw-r--r--examples/snowpack/astro/pages/concepts/how-snowpack-works.md2
-rw-r--r--examples/snowpack/astro/pages/guides/babel.md2
-rw-r--r--examples/snowpack/astro/pages/guides/connecting-tools.md2
-rw-r--r--examples/snowpack/astro/pages/guides/hmr.md2
-rw-r--r--examples/snowpack/astro/pages/guides/https-ssl-certificates.md2
-rw-r--r--examples/snowpack/astro/pages/guides/jest.md2
-rw-r--r--examples/snowpack/astro/pages/guides/optimize-and-bundle.md2
-rw-r--r--examples/snowpack/astro/pages/guides/plugins.md2
-rw-r--r--examples/snowpack/astro/pages/guides/postcss.md2
-rw-r--r--examples/snowpack/astro/pages/guides/preact.md2
-rw-r--r--examples/snowpack/astro/pages/guides/react-global-imports.md2
-rw-r--r--examples/snowpack/astro/pages/guides/react-loadable-components.md2
-rw-r--r--examples/snowpack/astro/pages/guides/routing.md2
-rw-r--r--examples/snowpack/astro/pages/guides/sass.md2
-rw-r--r--examples/snowpack/astro/pages/guides/server-side-render.md2
-rw-r--r--examples/snowpack/astro/pages/guides/streaming-imports.md2
-rw-r--r--examples/snowpack/astro/pages/guides/tailwind-css.md2
-rw-r--r--examples/snowpack/astro/pages/guides/testing.md2
-rw-r--r--examples/snowpack/astro/pages/guides/upgrade-guide.md2
-rw-r--r--examples/snowpack/astro/pages/guides/vue.md2
-rw-r--r--examples/snowpack/astro/pages/guides/wasm.md2
-rw-r--r--examples/snowpack/astro/pages/guides/web-test-runner.md2
-rw-r--r--examples/snowpack/astro/pages/guides/web-worker.md2
-rw-r--r--examples/snowpack/astro/pages/guides/workbox.md2
-rw-r--r--examples/snowpack/astro/pages/posts/2020-05-26-snowpack-2-0-release.md2
-rw-r--r--examples/snowpack/astro/pages/posts/2020-07-30-snowpack-2-7-release.md2
-rw-r--r--examples/snowpack/astro/pages/posts/2020-12-03-snowpack-3-release-candidate.md2
-rw-r--r--examples/snowpack/astro/pages/posts/2021-01-13-snowpack-3-0.md2
-rw-r--r--examples/snowpack/astro/pages/reference/cli-command-line-interface.md2
-rw-r--r--examples/snowpack/astro/pages/reference/common-error-details.md2
-rw-r--r--examples/snowpack/astro/pages/reference/configuration.md62
-rw-r--r--examples/snowpack/astro/pages/reference/environment-variables.md2
-rw-r--r--examples/snowpack/astro/pages/reference/hot-module-replacement.md2
-rw-r--r--examples/snowpack/astro/pages/reference/javascript-interface.md2
-rw-r--r--examples/snowpack/astro/pages/reference/plugins.md2
-rw-r--r--examples/snowpack/astro/pages/reference/supported-files.md2
-rw-r--r--examples/snowpack/astro/pages/tutorials/getting-started.md2
-rw-r--r--examples/snowpack/astro/pages/tutorials/quick-start.md2
-rw-r--r--examples/snowpack/astro/pages/tutorials/react.md2
-rw-r--r--examples/snowpack/astro/pages/tutorials/svelte.md2
-rw-r--r--snowpack-plugin.cjs8
-rw-r--r--src/@types/astro.ts2
-rw-r--r--src/compiler/codegen.ts34
-rw-r--r--src/compiler/index.ts15
-rw-r--r--src/compiler/optimize/styles.ts36
-rw-r--r--src/parser/interfaces.ts2
-rw-r--r--src/runtime.ts85
-rw-r--r--test/astro-styles-ssr.test.js25
-rw-r--r--test/fixtures/astro-markdown/astro/pages/post.md4
54 files changed, 202 insertions, 165 deletions
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 8cdfdc2f3..1ffaca73c 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -3,12 +3,15 @@ module.exports = {
extends: ['plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['@typescript-eslint', 'prettier'],
rules: {
+ '@typescript-eslint/ban-ts-comment': 'warn',
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/no-var-requires': 'off',
+ 'no-shadow': 'warn',
'prettier/prettier': 'error',
'prefer-const': 'off',
'prefer-rest-params': 'off',
+ 'require-jsdoc': 'warn',
},
};
diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
index 0808ce599..369d07563 100644
--- a/.github/workflows/nodejs.yml
+++ b/.github/workflows/nodejs.yml
@@ -27,3 +27,10 @@ jobs:
npm test
env:
CI: true
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v1
+ - uses: actions/setup-node@v1
+ - run: npm ci
+ - run: npm run lint
diff --git a/examples/snowpack/astro/pages/concepts/build-pipeline.md b/examples/snowpack/astro/pages/concepts/build-pipeline.md
index 2ff7e58a2..b996273a4 100644
--- a/examples/snowpack/astro/pages/concepts/build-pipeline.md
+++ b/examples/snowpack/astro/pages/concepts/build-pipeline.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: The Build Pipeline
description: Snowpack Build creates a production-ready website with or without a bundler
---
diff --git a/examples/snowpack/astro/pages/concepts/dev-server.md b/examples/snowpack/astro/pages/concepts/dev-server.md
index 5fad2d99f..2566d760d 100644
--- a/examples/snowpack/astro/pages/concepts/dev-server.md
+++ b/examples/snowpack/astro/pages/concepts/dev-server.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: The Dev Server
description: Snowpack's dev server is fast because it only rebuilds the files you change. Powered by ESM (ES modules).
---
diff --git a/examples/snowpack/astro/pages/concepts/hot-module-replacement.md b/examples/snowpack/astro/pages/concepts/hot-module-replacement.md
index 58d510c3c..868bbd9a7 100644
--- a/examples/snowpack/astro/pages/concepts/hot-module-replacement.md
+++ b/examples/snowpack/astro/pages/concepts/hot-module-replacement.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: HMR + Fast Refresh
description: Snowpack's ESM-powered unbundled development means near-instant single file builds that only take 10-25ms to load and update in the browser.
---
diff --git a/examples/snowpack/astro/pages/concepts/how-snowpack-works.md b/examples/snowpack/astro/pages/concepts/how-snowpack-works.md
index 186c5037b..7b89c4dbd 100644
--- a/examples/snowpack/astro/pages/concepts/how-snowpack-works.md
+++ b/examples/snowpack/astro/pages/concepts/how-snowpack-works.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: How Snowpack Works
description: Snowpack serves your application unbundled during development. Each file is built only once and is cached until it changes.
---
diff --git a/examples/snowpack/astro/pages/guides/babel.md b/examples/snowpack/astro/pages/guides/babel.md
index ecb3108a3..6c024d150 100644
--- a/examples/snowpack/astro/pages/guides/babel.md
+++ b/examples/snowpack/astro/pages/guides/babel.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: 'Babel'
tags: communityGuide
published: true
diff --git a/examples/snowpack/astro/pages/guides/connecting-tools.md b/examples/snowpack/astro/pages/guides/connecting-tools.md
index d0208ea43..239a35116 100644
--- a/examples/snowpack/astro/pages/guides/connecting-tools.md
+++ b/examples/snowpack/astro/pages/guides/connecting-tools.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: The Snowpack Guide to connecting your favorite tools
description: 'How do you use your favorite tools in Snowpack? This Guide will help you get started'
published: true
diff --git a/examples/snowpack/astro/pages/guides/hmr.md b/examples/snowpack/astro/pages/guides/hmr.md
index daf38cc5c..f1a967e31 100644
--- a/examples/snowpack/astro/pages/guides/hmr.md
+++ b/examples/snowpack/astro/pages/guides/hmr.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Hot Module Replacement (HMR)
description: Enable Snowpack's Hot Module Replacement (HMR) on your development server.
published: false
diff --git a/examples/snowpack/astro/pages/guides/https-ssl-certificates.md b/examples/snowpack/astro/pages/guides/https-ssl-certificates.md
index bd311a07c..512c6524f 100644
--- a/examples/snowpack/astro/pages/guides/https-ssl-certificates.md
+++ b/examples/snowpack/astro/pages/guides/https-ssl-certificates.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: SSL Certificates
description: How to use HTTPs during development and generate SSL certifcates for your Snowpack build.
---
diff --git a/examples/snowpack/astro/pages/guides/jest.md b/examples/snowpack/astro/pages/guides/jest.md
index 98199f6ec..8b8edb0a3 100644
--- a/examples/snowpack/astro/pages/guides/jest.md
+++ b/examples/snowpack/astro/pages/guides/jest.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: 'Jest'
tags: communityGuide
img: '/img/logos/jest.svg'
diff --git a/examples/snowpack/astro/pages/guides/optimize-and-bundle.md b/examples/snowpack/astro/pages/guides/optimize-and-bundle.md
index 162a9cffe..442ec3c05 100644
--- a/examples/snowpack/astro/pages/guides/optimize-and-bundle.md
+++ b/examples/snowpack/astro/pages/guides/optimize-and-bundle.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Optimize & Bundle for Production
published: true
description: How to optimize your Snowpack build for production, with or without a bundler.
diff --git a/examples/snowpack/astro/pages/guides/plugins.md b/examples/snowpack/astro/pages/guides/plugins.md
index 60818562f..f78b71617 100644
--- a/examples/snowpack/astro/pages/guides/plugins.md
+++ b/examples/snowpack/astro/pages/guides/plugins.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Creating Your Own Plugin
description: Learn the basics of our Plugin API through working examples.
---
diff --git a/examples/snowpack/astro/pages/guides/postcss.md b/examples/snowpack/astro/pages/guides/postcss.md
index f3fe0212a..3d8c26b84 100644
--- a/examples/snowpack/astro/pages/guides/postcss.md
+++ b/examples/snowpack/astro/pages/guides/postcss.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: 'PostCSS'
tags: communityGuide
published: true
diff --git a/examples/snowpack/astro/pages/guides/preact.md b/examples/snowpack/astro/pages/guides/preact.md
index 1dd700ed8..060ff1e89 100644
--- a/examples/snowpack/astro/pages/guides/preact.md
+++ b/examples/snowpack/astro/pages/guides/preact.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Preact
tags: communityGuide
img: '/img/logos/preact.svg'
diff --git a/examples/snowpack/astro/pages/guides/react-global-imports.md b/examples/snowpack/astro/pages/guides/react-global-imports.md
index 7286337ab..46e3f9054 100644
--- a/examples/snowpack/astro/pages/guides/react-global-imports.md
+++ b/examples/snowpack/astro/pages/guides/react-global-imports.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: React + babel-plugin-import-global
published: false
---
diff --git a/examples/snowpack/astro/pages/guides/react-loadable-components.md b/examples/snowpack/astro/pages/guides/react-loadable-components.md
index 4d5575327..d22931b9b 100644
--- a/examples/snowpack/astro/pages/guides/react-loadable-components.md
+++ b/examples/snowpack/astro/pages/guides/react-loadable-components.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: React + Loadable Components
published: false
---
diff --git a/examples/snowpack/astro/pages/guides/routing.md b/examples/snowpack/astro/pages/guides/routing.md
index b63830aad..3c5ea6ed4 100644
--- a/examples/snowpack/astro/pages/guides/routing.md
+++ b/examples/snowpack/astro/pages/guides/routing.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Routing
published: true
description: This guide will walk you through some common routing scenarios and how to configure the routes option to support them in development.
diff --git a/examples/snowpack/astro/pages/guides/sass.md b/examples/snowpack/astro/pages/guides/sass.md
index 3da5c9f7c..e7588b8b0 100644
--- a/examples/snowpack/astro/pages/guides/sass.md
+++ b/examples/snowpack/astro/pages/guides/sass.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: 'Sass'
tags: communityGuide
published: true
diff --git a/examples/snowpack/astro/pages/guides/server-side-render.md b/examples/snowpack/astro/pages/guides/server-side-render.md
index 8c698f9fb..77b72f979 100644
--- a/examples/snowpack/astro/pages/guides/server-side-render.md
+++ b/examples/snowpack/astro/pages/guides/server-side-render.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Server-Side Rendering (SSR)
description: This guide will walk you through three different options for setting up Snowpack with your own custom server.
published: true
diff --git a/examples/snowpack/astro/pages/guides/streaming-imports.md b/examples/snowpack/astro/pages/guides/streaming-imports.md
index 39f167f1f..cf8673ecb 100644
--- a/examples/snowpack/astro/pages/guides/streaming-imports.md
+++ b/examples/snowpack/astro/pages/guides/streaming-imports.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Streaming Imports
published: true
stream: Fetch your npm dependencies on-demand from a remote ESM CDN.
diff --git a/examples/snowpack/astro/pages/guides/tailwind-css.md b/examples/snowpack/astro/pages/guides/tailwind-css.md
index ce8597b0b..a0643b69e 100644
--- a/examples/snowpack/astro/pages/guides/tailwind-css.md
+++ b/examples/snowpack/astro/pages/guides/tailwind-css.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: 'Tailwind CSS'
tags: communityGuide
published: true
diff --git a/examples/snowpack/astro/pages/guides/testing.md b/examples/snowpack/astro/pages/guides/testing.md
index f33c3324e..c632c2f87 100644
--- a/examples/snowpack/astro/pages/guides/testing.md
+++ b/examples/snowpack/astro/pages/guides/testing.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Testing
published: true
description: How to choose and use a JavaScript test runner for your Snowpack site.
diff --git a/examples/snowpack/astro/pages/guides/upgrade-guide.md b/examples/snowpack/astro/pages/guides/upgrade-guide.md
index 098e1c812..58942350e 100644
--- a/examples/snowpack/astro/pages/guides/upgrade-guide.md
+++ b/examples/snowpack/astro/pages/guides/upgrade-guide.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Snowpack Upgrade Guide
published: true
description: How to upgrade to Snowpack v3 from older versions of Snowpack.
diff --git a/examples/snowpack/astro/pages/guides/vue.md b/examples/snowpack/astro/pages/guides/vue.md
index 95b56d8f6..599a3def5 100644
--- a/examples/snowpack/astro/pages/guides/vue.md
+++ b/examples/snowpack/astro/pages/guides/vue.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Vue
tags: communityGuide
img: '/img/logos/vue.png'
diff --git a/examples/snowpack/astro/pages/guides/wasm.md b/examples/snowpack/astro/pages/guides/wasm.md
index 66119afbd..1e7ab5ac4 100644
--- a/examples/snowpack/astro/pages/guides/wasm.md
+++ b/examples/snowpack/astro/pages/guides/wasm.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: 'WASM'
tags: communityGuide
published: true
diff --git a/examples/snowpack/astro/pages/guides/web-test-runner.md b/examples/snowpack/astro/pages/guides/web-test-runner.md
index 43e77e357..8962f5001 100644
--- a/examples/snowpack/astro/pages/guides/web-test-runner.md
+++ b/examples/snowpack/astro/pages/guides/web-test-runner.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: '@web/test-runner'
tags: communityGuide
img: '/img/logos/modern-web.svg'
diff --git a/examples/snowpack/astro/pages/guides/web-worker.md b/examples/snowpack/astro/pages/guides/web-worker.md
index afb87b3da..ed64c22d6 100644
--- a/examples/snowpack/astro/pages/guides/web-worker.md
+++ b/examples/snowpack/astro/pages/guides/web-worker.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: 'Web Workers'
tags: communityGuide
published: true
diff --git a/examples/snowpack/astro/pages/guides/workbox.md b/examples/snowpack/astro/pages/guides/workbox.md
index f74eadd18..5572a8fdb 100644
--- a/examples/snowpack/astro/pages/guides/workbox.md
+++ b/examples/snowpack/astro/pages/guides/workbox.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Workbox
tags: communityGuide
description: The Workbox CLI integrates well with Snowpack.
diff --git a/examples/snowpack/astro/pages/posts/2020-05-26-snowpack-2-0-release.md b/examples/snowpack/astro/pages/posts/2020-05-26-snowpack-2-0-release.md
index 76b9098c0..989ed8b69 100644
--- a/examples/snowpack/astro/pages/posts/2020-05-26-snowpack-2-0-release.md
+++ b/examples/snowpack/astro/pages/posts/2020-05-26-snowpack-2-0-release.md
@@ -1,5 +1,5 @@
---
-layout: layouts/post.astro
+layout: ../../layouts/post.astro
bannerVideo: '/img/extra-space-4.mp4'
permalink: '/posts/2020-05-26-snowpack-2-0-release/'
title: Snowpack v2.0
diff --git a/examples/snowpack/astro/pages/posts/2020-07-30-snowpack-2-7-release.md b/examples/snowpack/astro/pages/posts/2020-07-30-snowpack-2-7-release.md
index 6ef94ab69..8eecf3158 100644
--- a/examples/snowpack/astro/pages/posts/2020-07-30-snowpack-2-7-release.md
+++ b/examples/snowpack/astro/pages/posts/2020-07-30-snowpack-2-7-release.md
@@ -1,5 +1,5 @@
---
-layout: layouts/post.astro
+layout: ../../layouts/post.astro
title: Snowpack 2.7
description: 'A new plugin API plus smaller, faster production builds.'
tagline: v2.7.0 release post
diff --git a/examples/snowpack/astro/pages/posts/2020-12-03-snowpack-3-release-candidate.md b/examples/snowpack/astro/pages/posts/2020-12-03-snowpack-3-release-candidate.md
index b5c4d5bab..392d554d6 100644
--- a/examples/snowpack/astro/pages/posts/2020-12-03-snowpack-3-release-candidate.md
+++ b/examples/snowpack/astro/pages/posts/2020-12-03-snowpack-3-release-candidate.md
@@ -1,5 +1,5 @@
---
-layout: layouts/post.astro
+layout: ../../layouts/post.astro
title: 'Snowpack v3.0 Release Candidate'
tagline: New features to change the way you build for the web.
description: 'New features to change the way you build for the web. Snowpack v3.0 will release on January 6th, 2021 (the one-year anniversary of its original launch post). This is our biggest release yet with some serious new features, including a new way to load npm packages on-demand that lets you skip the `npm install` step entirely.'
diff --git a/examples/snowpack/astro/pages/posts/2021-01-13-snowpack-3-0.md b/examples/snowpack/astro/pages/posts/2021-01-13-snowpack-3-0.md
index bfc1d8fb6..b6dd9b1be 100644
--- a/examples/snowpack/astro/pages/posts/2021-01-13-snowpack-3-0.md
+++ b/examples/snowpack/astro/pages/posts/2021-01-13-snowpack-3-0.md
@@ -1,5 +1,5 @@
---
-layout: layouts/post.astro
+layout: ../../layouts/post.astro
title: 'Snowpack v3.0'
description: Snowpack v3.0 is here! Our biggest release yet with some serious new features, including pre-bundled streaming imports, built-in bundling & optimizations, new JavaScript APIs, and more.'
date: 2021-01-13
diff --git a/examples/snowpack/astro/pages/reference/cli-command-line-interface.md b/examples/snowpack/astro/pages/reference/cli-command-line-interface.md
index af4dc4d43..338eee415 100644
--- a/examples/snowpack/astro/pages/reference/cli-command-line-interface.md
+++ b/examples/snowpack/astro/pages/reference/cli-command-line-interface.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Command Line API
description: The Snowpack Command Line tool's API, commands, and flags.
---
diff --git a/examples/snowpack/astro/pages/reference/common-error-details.md b/examples/snowpack/astro/pages/reference/common-error-details.md
index 066b82f40..c25be136d 100644
--- a/examples/snowpack/astro/pages/reference/common-error-details.md
+++ b/examples/snowpack/astro/pages/reference/common-error-details.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Common Error Details
description: How to troubleshoot common issues and error messagesm, plus our resources for getting help.
---
diff --git a/examples/snowpack/astro/pages/reference/configuration.md b/examples/snowpack/astro/pages/reference/configuration.md
index 60afba42d..1469b4cbb 100644
--- a/examples/snowpack/astro/pages/reference/configuration.md
+++ b/examples/snowpack/astro/pages/reference/configuration.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: snowpack.config.js
description: The Snowpack configuration API reference.
---
@@ -20,7 +20,7 @@ To generate a basic configuration file scaffold in your Snowpack project run `sn
## root
-**Type**: `string`
+**Type**: `string`
**Default**: `/`
Specify the root of a project using Snowpack. (Previously: `config.cwd`)
@@ -47,7 +47,7 @@ Can be a relative file path, an npm package, or a file within an npm package. Yo
## exclude
-**Type**: `string[]`
+**Type**: `string[]`
**Default**: `['**/node_modules/**/*']`
Exclude any files from the Snowpack pipeline.
@@ -151,28 +151,28 @@ Configure the Snowpack dev server.
### devOptions.secure
-**Type**: `boolean`
+**Type**: `boolean`
**Default**: `false`
Toggles whether Snowpack dev server should use HTTPS with HTTP2 enabled.
### devOptions.hostname
-**Type**: `string`
+**Type**: `string`
**Default**: `localhost`
The hostname that the dev server is running on. Snowpack uses this information to configure the HMR websocket and properly open your browser on startup (see: [`devOptions.open`](#devoptions.open)).
### devOptions.port
-**Type**: `number`
+**Type**: `number`
**Default**: `8080`
The port the dev server runs on.
### devOptions.fallback
-**Type**: `string`
+**Type**: `string`
**Default**: `"index.html"`
The HTML file to serve for non-resource routes.
@@ -183,7 +183,7 @@ When using the Single-Page Application (SPA) pattern, this is the HTML "shell" f
### devOptions.open
-**Type**: `string`
+**Type**: `string`
**Default**: `"**Default**"`
Configures how the dev server opens in the browser when it starts.
@@ -192,7 +192,7 @@ Any installed browser, e.g., "chrome", "firefox", "brave". Set "none" to disable
### devOptions.output
-**Type**: `"stream" | "dashboard"`
+**Type**: `"stream" | "dashboard"`
**Default**: `"dashboard"`
Set the output mode of the `dev` console:
@@ -202,35 +202,35 @@ Set the output mode of the `dev` console:
### devOptions.hmr
-**Type**: `boolean`
+**Type**: `boolean`
**Default**: `true`
Toggles HMR on the Snowpack dev server.
### devOptions.hmrDelay
-**Type**: `number` (milliseconds)
+**Type**: `number` (milliseconds)
**Default**: `0`
Milliseconds to delay HMR-triggered browser update.
### devOptions.hmrPort
-**Type**: `number`
+**Type**: `number`
**Default**: [`devOptions.port`](#devoptions.port)
The port where Snowpack's HMR Websocket runs.
### devOptions.hmrErrorOverlay
-**Type**: `boolean`
+**Type**: `boolean`
**Default**: `true`
Toggles a browser overlay that displays JavaScript runtime errors when running HMR.
### devOptions.out
-**Type**: `string`
+**Type**: `string`
**Default**: `"build"`
_NOTE:_ Deprecated, see `buildOptions.out`.
@@ -249,7 +249,7 @@ Configure how npm packages are installed and used.
### packageOptions.external
-**Type**: `string[]`
+**Type**: `string[]`
**Example**: `"external": ["fs"]`
Mark some imports as external. Snowpack will ignore these imports and leave them as-is in your final build.
@@ -258,7 +258,7 @@ This is an advanced feature: Bare imports are not supported in any major browser
### packageOptions.source
-**Type**: `"local" | "remote"`
+**Type**: `"local" | "remote"`
**Default**: `"local"`
**Example**: `"source": "local"`
@@ -278,7 +278,7 @@ Known dependencies to install with Snowpack. Used for installing packages any de
#### packageOptions.polyfillNode
-**Type**: `boolean`
+**Type**: `boolean`
**Default**: `false`
This will automatically polyfill any Node.js dependencies as much as possible for the browser
@@ -313,7 +313,7 @@ This option is only supported in `source="local"` mode. `source="remote"` does n
#### packageOptions.packageLookupFields
-**Type**: `string[]`
+**Type**: `string[]`
**Example**: `"packageLookupFields": ["svelte"]`
Set custom lookup fields for dependency `package.json` file entrypoints, in addition to the defaults like "module", "main", etc.
@@ -322,7 +322,7 @@ This option is only supported in `source="local"` mode. `source="remote"` does n
#### packageOptions.packageExportLookupFields
-**Type**: `string[]`
+**Type**: `string[]`
**Example**: `"packageExportLookupFields": ["svelte"]`
Set custom lookup fields for dependency `package.json` ["exports" mappings.](https://nodejs.org/api/packages.html#packages_package_entry_points)
@@ -351,7 +351,7 @@ Enable streaming package imports. Load dependencies from our remote CDN. Manage
#### packageOptions.origin
-**Type**: `string`
+**Type**: `string`
**Default**: `https://pkg.snowpack.dev`
The remote origin to import packages from. When you import a new package, Snowpack will fetch those resources from this URL.
@@ -360,14 +360,14 @@ Currently, the origin must implement a specific response format that Snowpack ca
#### packageOptions.cache
-**Type**: `string`
+**Type**: `string`
**Default**: `.snowpack`
The location of your project cache folder, relative to the project root. Snowpack will save cached data to this folder. For example, if `packageOptions.types` is set to true, Snowpack will save TypeScript types to a `types` directory within this folder.
#### packageOptions.types
-**Type**: `boolean`
+**Type**: `boolean`
**Default**: `false`
If true, Snowpack will download TypeScript types for every package.
@@ -387,7 +387,7 @@ The local directory that we output your final build to.
### buildOptions.baseUrl
-**Type**: `string`
+**Type**: `string`
**Default**: `/`
In your HTML, replace all instances of `%PUBLIC_URL%` with this
@@ -396,7 +396,7 @@ Inspired by the same [Create React App](https://create-react-app.dev/docs/using-
### buildOptions.clean
-**Type**: `boolean`
+**Type**: `boolean`
**Default**: `true`
Set to `false` to prevent Snowpack from deleting the build output folder (`buildOptions.out`) between builds.
@@ -411,7 +411,7 @@ _NOTE:_ Deprecated, see `buildOptions.metaUrlPath`.
### buildOptions.metaUrlPath
-**Type**: `string`
+**Type**: `string`
**Default**: `_snowpack`
Rename the default directory for Snowpack metadata. In every build, Snowpack creates meta files for loading things like [HMR](/concepts/hot-module-replacement), [Environment Variables](/reference/environment-variables), and your built npm packages.
@@ -420,7 +420,7 @@ When you build your project, this will be a path on disk relative to the `buildO
### buildOptions.sourcemap
-**Type**: `boolean`
+**Type**: `boolean`
**Default**: `false`
Generates source maps.
@@ -429,14 +429,14 @@ Generates source maps.
### buildOptions.watch
-**Type**: `boolean`
+**Type**: `boolean`
**Default**: `false`
Run Snowpack's build pipeline through a file watcher. This option works best for local development when you have a custom frontend server (ex: Rails, PHP, etc.) and the Snowpack dev server cannot be used.
### buildOptions.htmlFragments
-**Type**: `boolean`
+**Type**: `boolean`
**Default**: `false`
Toggles whether HTML fragments are transformed like full HTML pages.
@@ -445,14 +445,14 @@ HTML fragments are HTML files not starting with "<!doctype html>".
### buildOptions.jsxFactory
-**Type**: `string`
+**Type**: `string`
**Default**: `React.createElement` (or `h` if Preact import is detected)
Set the name of the function used to create JSX elements.
### buildOptions.jsxFragment
-**Type**: `string`
+**Type**: `string`
**Default**: `React.Fragment` (or `Fragment` if Preact import is detected)
Set the name of the function used to create JSX fragments.
@@ -463,7 +463,7 @@ Configure your tests.
### testOptions.files
-**Type**: `string[]`
+**Type**: `string[]`
**Default**: `["__tests__/**/*", "**/*.@(spec|test).*"]`
Specifies your test files. If `NODE_ENV` is set to "test", Snowpack includes these files in your site build and scan them for installable dependencies. Otherwise, Snowpack excludes these files.
diff --git a/examples/snowpack/astro/pages/reference/environment-variables.md b/examples/snowpack/astro/pages/reference/environment-variables.md
index 66bd8a91f..1a4c40794 100644
--- a/examples/snowpack/astro/pages/reference/environment-variables.md
+++ b/examples/snowpack/astro/pages/reference/environment-variables.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Environment Variables
description: Using environment variables with Snowpack
---
diff --git a/examples/snowpack/astro/pages/reference/hot-module-replacement.md b/examples/snowpack/astro/pages/reference/hot-module-replacement.md
index a18c8dcca..0b95cebf9 100644
--- a/examples/snowpack/astro/pages/reference/hot-module-replacement.md
+++ b/examples/snowpack/astro/pages/reference/hot-module-replacement.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Hot Module Replacement (HMR) API
description: Snowpack implements HMR via the esm-hmr spec, an attempted standard for ESM-based Hot Module Replacement (HMR).
---
diff --git a/examples/snowpack/astro/pages/reference/javascript-interface.md b/examples/snowpack/astro/pages/reference/javascript-interface.md
index 26f7c59e7..ad3048240 100644
--- a/examples/snowpack/astro/pages/reference/javascript-interface.md
+++ b/examples/snowpack/astro/pages/reference/javascript-interface.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: JavaScript API
description: Snowpack's JavaScript API is for anyone who wants to integrate with some custom build pipeline or server-side rendering engine.
---
diff --git a/examples/snowpack/astro/pages/reference/plugins.md b/examples/snowpack/astro/pages/reference/plugins.md
index 71425d52f..3e38f2b6e 100644
--- a/examples/snowpack/astro/pages/reference/plugins.md
+++ b/examples/snowpack/astro/pages/reference/plugins.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Plugin API
description: The Snowpack Plugin API and how to use it.
---
diff --git a/examples/snowpack/astro/pages/reference/supported-files.md b/examples/snowpack/astro/pages/reference/supported-files.md
index 48b148967..c111247dc 100644
--- a/examples/snowpack/astro/pages/reference/supported-files.md
+++ b/examples/snowpack/astro/pages/reference/supported-files.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Supported Files
description: Snowpack ships with built-in support for many file types including json, js, ts, jsx, css, css modules, and images.
---
diff --git a/examples/snowpack/astro/pages/tutorials/getting-started.md b/examples/snowpack/astro/pages/tutorials/getting-started.md
index 57a317134..85037db89 100644
--- a/examples/snowpack/astro/pages/tutorials/getting-started.md
+++ b/examples/snowpack/astro/pages/tutorials/getting-started.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: 'Starting a New Project'
description: This guide shows you how to set up Snowpack from scratch in a Node.js project. Along the way learn key concepts of Snowpack and unbundled development.
---
diff --git a/examples/snowpack/astro/pages/tutorials/quick-start.md b/examples/snowpack/astro/pages/tutorials/quick-start.md
index 183fafa32..a3960453f 100644
--- a/examples/snowpack/astro/pages/tutorials/quick-start.md
+++ b/examples/snowpack/astro/pages/tutorials/quick-start.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../../layouts/content.astro
title: Quick Start
description: A very basic guide for developers who want to run Snowpack as quickly as possible.
---
diff --git a/examples/snowpack/astro/pages/tutorials/react.md b/examples/snowpack/astro/pages/tutorials/react.md
index 036d4d295..7364f03cc 100644
--- a/examples/snowpack/astro/pages/tutorials/react.md
+++ b/examples/snowpack/astro/pages/tutorials/react.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content-with-cover.astro
+layout: ../../layouts/content-with-cover.astro
title: 'Getting Started with React'
description: 'Get started with this in-depth tutorial on how to build React applications and websites with Snowpack and developer tools like React Fast Refresh'
date: 2020-12-01
diff --git a/examples/snowpack/astro/pages/tutorials/svelte.md b/examples/snowpack/astro/pages/tutorials/svelte.md
index cffe1dd88..c25f2bcdb 100644
--- a/examples/snowpack/astro/pages/tutorials/svelte.md
+++ b/examples/snowpack/astro/pages/tutorials/svelte.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content-with-cover.astro
+layout: ../../layouts/content-with-cover.astro
title: 'Getting Started with Svelte'
description: 'Get started with this in-depth tutorial on how to build Svelte applications and websites with Snowpack'
date: 2020-12-01
diff --git a/snowpack-plugin.cjs b/snowpack-plugin.cjs
index dcb714ea6..4a4db8efd 100644
--- a/snowpack-plugin.cjs
+++ b/snowpack-plugin.cjs
@@ -9,7 +9,7 @@ module.exports = function (snowpackConfig, { resolve, extensions, astroConfig }
knownEntrypoints: ['deepmerge'],
resolve: {
input: ['.astro', '.md'],
- output: ['.js'],
+ output: ['.js', '.css'],
},
async load({ filePath }) {
const { compileComponent } = await transformPromise;
@@ -21,7 +21,11 @@ module.exports = function (snowpackConfig, { resolve, extensions, astroConfig }
extensions,
};
const result = await compileComponent(contents, { compileOptions, filename: filePath, projectRoot });
- return result.contents;
+ const output = {
+ '.js': result.contents,
+ };
+ if (result.css) output['.css'] = result.css;
+ return output;
},
};
};
diff --git a/src/@types/astro.ts b/src/@types/astro.ts
index ee6a79eab..5790c4b78 100644
--- a/src/@types/astro.ts
+++ b/src/@types/astro.ts
@@ -25,9 +25,11 @@ export interface TransformResult {
script: string;
imports: string[];
items: JsxItem[];
+ css?: string;
}
export interface CompileResult {
result: TransformResult;
contents: string;
+ css?: string;
}
diff --git a/src/compiler/codegen.ts b/src/compiler/codegen.ts
index 70620111d..63fc44dfb 100644
--- a/src/compiler/codegen.ts
+++ b/src/compiler/codegen.ts
@@ -21,7 +21,7 @@ interface Attribute {
end: number;
type: 'Attribute';
name: string;
- value: any;
+ value: TemplateNode[] | boolean;
}
interface CodeGenOptions {
@@ -41,7 +41,8 @@ function getAttributes(attrs: Attribute[]): Record<string, string> {
result[attr.name] = JSON.stringify(attr.value);
continue;
}
- if (attr.value === false) {
+ if (attr.value === false || attr.value === undefined) {
+ // note: attr.value shouldn’t be `undefined`, but a bad transform would cause a compile error here, so prevent that
continue;
}
if (attr.value.length > 1) {
@@ -59,7 +60,7 @@ function getAttributes(attrs: Attribute[]): Record<string, string> {
')';
continue;
}
- const val: TemplateNode = attr.value[0];
+ const val = attr.value[0];
if (!val) {
result[attr.name] = '(' + val + ')';
continue;
@@ -72,7 +73,7 @@ function getAttributes(attrs: Attribute[]): Record<string, string> {
result[attr.name] = JSON.stringify(getTextFromAttribute(val));
continue;
default:
- throw new Error('UNKNOWN V');
+ throw new Error(`UNKNOWN: ${val.type}`);
}
}
return result;
@@ -253,7 +254,7 @@ async function acquireDynamicComponentImports(plugins: Set<ValidExtensionPlugins
return importMap;
}
-export async function codegen(ast: Ast, { compileOptions, filename }: CodeGenOptions): Promise<TransformResult> {
+export async function codegen(ast: Ast, { compileOptions, filename, fileID }: CodeGenOptions): Promise<TransformResult> {
const { extensions = defaultExtensions, astroConfig } = compileOptions;
await eslexer.init;
@@ -334,6 +335,21 @@ export async function codegen(ast: Ast, { compileOptions, filename }: CodeGenOpt
let collectionItem: JsxItem | undefined;
let currentItemName: string | undefined;
let currentDepth = 0;
+ let css: string[] = [];
+
+ walk(ast.css, {
+ enter(node: TemplateNode) {
+ if (node.type === 'Style') {
+ css.push(node.content.styles); // if multiple <style> tags, combine together
+ this.skip();
+ }
+ },
+ leave(node: TemplateNode) {
+ if (node.type === 'Style') {
+ this.remove(); // this will be optimized in a global CSS file; remove so it‘s not accidentally inlined
+ }
+ },
+ });
walk(ast.html, {
enter(node: TemplateNode) {
@@ -419,9 +435,9 @@ export async function codegen(ast: Ast, { compileOptions, filename }: CodeGenOpt
return;
}
case 'Style': {
- const attributes = getAttributes(node.attributes);
- items.push({ name: 'style', jsx: `h("style", ${attributes ? generateAttributes(attributes) : 'null'}, ${JSON.stringify(node.content.styles)})` });
- break;
+ css.push(node.content.styles); // if multiple <style> tags, combine together
+ this.skip();
+ return;
}
case 'Text': {
const text = getTextFromAttribute(node);
@@ -469,6 +485,7 @@ export async function codegen(ast: Ast, { compileOptions, filename }: CodeGenOpt
}
return;
case 'Style': {
+ this.remove(); // this will be optimized in a global CSS file; remove so it‘s not accidentally inlined
return;
}
default:
@@ -481,5 +498,6 @@ export async function codegen(ast: Ast, { compileOptions, filename }: CodeGenOpt
script: script,
imports: Array.from(importExportStatements),
items,
+ css: css.length ? css.join('\n\n') : undefined,
};
}
diff --git a/src/compiler/index.ts b/src/compiler/index.ts
index 8104ef4b4..1afa97c87 100644
--- a/src/compiler/index.ts
+++ b/src/compiler/index.ts
@@ -10,7 +10,6 @@ import { CompileResult, TransformResult } from '../@types/astro';
import { parse } from '../parser/index.js';
import { createMarkdownHeadersCollector } from '../micromark-collect-headers.js';
import { encodeMarkdown } from '../micromark-encode.js';
-import { defaultLogOptions } from '../logger.js';
import { optimize } from './optimize/index.js';
import { codegen } from './codegen.js';
@@ -75,14 +74,14 @@ async function convertMdToJsx(
const raw = `---
${imports}
- ${frontmatterData.layout ? `export const __layout = ${JSON.stringify(frontmatterData.layout)};` : ''}
+ ${frontmatterData.layout ? `import {__renderPage as __layout} from '${frontmatterData.layout}';` : 'const __layout = undefined;'}
export const __content = ${stringifiedSetupContext};
---
<section>${mdHtml}</section>`;
const convertOptions = { compileOptions, filename, fileID };
- return convertAstroToJsx(raw, convertOptions);
+ return await convertAstroToJsx(raw, convertOptions);
}
type SupportedExtensions = '.astro' | '.md';
@@ -94,9 +93,9 @@ async function transformFromSource(
const fileID = path.relative(projectRoot, filename);
switch (path.extname(filename) as SupportedExtensions) {
case '.astro':
- return convertAstroToJsx(contents, { compileOptions, filename, fileID });
+ return await convertAstroToJsx(contents, { compileOptions, filename, fileID });
case '.md':
- return convertMdToJsx(contents, { compileOptions, filename, fileID });
+ return await convertMdToJsx(contents, { compileOptions, filename, fileID });
default:
throw new Error('Not Supported!');
}
@@ -108,8 +107,6 @@ export async function compileComponent(
): Promise<CompileResult> {
const sourceJsx = await transformFromSource(source, { compileOptions, filename, projectRoot });
const isPage = path.extname(filename) === '.md' || sourceJsx.items.some((item) => item.name === 'html');
- // sort <style> tags first
- sourceJsx.items.sort((a, b) => (a.name === 'style' && b.name !== 'style' ? -1 : 0));
// return template
let modJsx = `
@@ -144,8 +141,7 @@ export async function __renderPage({request, children, props}) {
// find layout, if one was given.
if (currentChild.layout) {
- const layoutComponent = (await import('/_astro/layouts/' + currentChild.layout.replace(/.*layouts\\//, "").replace(/\.astro$/, '.js')));
- return layoutComponent.__renderPage({
+ return currentChild.layout({
request,
props: {content: currentChild.content},
children: [childBodyResult],
@@ -162,5 +158,6 @@ export async function __renderPage() { throw new Error("No <html> page element f
return {
result: sourceJsx,
contents: modJsx,
+ css: sourceJsx.css,
};
}
diff --git a/src/compiler/optimize/styles.ts b/src/compiler/optimize/styles.ts
index fa32445ba..b833f9e70 100644
--- a/src/compiler/optimize/styles.ts
+++ b/src/compiler/optimize/styles.ts
@@ -26,7 +26,7 @@ const getStyleType: Map<string, StyleType> = new Map([
]);
const SASS_OPTIONS: Partial<sass.Options> = {
- outputStyle: 'compressed',
+ outputStyle: process.env.NODE_ENV === 'production' ? 'compressed' : undefined,
};
/** HTML tags that should never get scoped classes */
const NEVER_SCOPED_TAGS = new Set<string>(['html', 'head', 'body', 'script', 'style', 'link', 'meta']);
@@ -95,11 +95,10 @@ async function transformStyle(code: string, { type, filename, scopedClass }: { t
return { css, type: styleType };
}
+/** Style optimizer */
export default function ({ filename, fileID }: { filename: string; fileID: string }): Optimizer {
const styleNodes: TemplateNode[] = []; // <style> tags to be updated
const styleTransformPromises: Promise<StyleTransformResult>[] = []; // async style transform results to be finished in finalize();
- let rootNode: TemplateNode; // root node which needs <style> tags
-
const scopedClass = `astro-${hashFromFilename(fileID)}`; // this *should* generate same hash from fileID every time
return {
@@ -124,15 +123,7 @@ export default function ({ filename, fileID }: { filename: string; fileID: strin
return;
}
- // 2. find the root node to inject the <style> tag in later
- // TODO: remove this when we are injecting <link> tags into <head>
- if (node.name === 'head') {
- rootNode = node; // If this is <head>, this is what we want. Always take this if found. However, this may not always exist (it won’t for Component subtrees).
- } else if (!rootNode) {
- rootNode = node; // If no <head> (yet), then take the first element we come to and assume it‘s the “root” (but if we find a <head> later, then override this per the above)
- }
-
- // 3. add scoped HTML classes
+ // 2. add scoped HTML classes
if (NEVER_SCOPED_TAGS.has(node.name)) return; // only continue if this is NOT a <script> tag, etc.
// Note: currently we _do_ scope web components/custom elements. This seems correct?
@@ -175,10 +166,6 @@ export default function ({ filename, fileID }: { filename: string; fileID: strin
scopedClass,
})
);
-
- // TODO: we should delete the old untransformed <style> node after we’re done.
- // However, the svelte parser left it in ast.css, not ast.html. At the final step, this just gets ignored, so it will be deleted, in a sense.
- // If we ever end up scanning ast.css for something else, then we’ll need to actually delete the node (or transform it to the processed version)
},
},
},
@@ -186,14 +173,9 @@ export default function ({ filename, fileID }: { filename: string; fileID: strin
async finalize() {
const styleTransforms = await Promise.all(styleTransformPromises);
- if (!rootNode) {
- throw new Error(`No root node found`); // TODO: remove this eventually; we should always find it, but for now alert if there’s a bug in our code
- }
-
- // 1. transform <style> tags
styleTransforms.forEach((result, n) => {
if (styleNodes[n].attributes) {
- // 1b. Inject final CSS
+ // 1. Replace with final CSS
const isHeadStyle = !styleNodes[n].content;
if (isHeadStyle) {
// Note: <style> tags in <head> have different attributes/rules, because of the parser. Unknown why
@@ -202,22 +184,22 @@ export default function ({ filename, fileID }: { filename: string; fileID: strin
styleNodes[n].content.styles = result.css;
}
- // 3b. Update <style> attributes
+ // 2. Update <style> attributes
const styleTypeIndex = styleNodes[n].attributes.findIndex(({ name }: any) => name === 'type');
+ // add type="text/css"
if (styleTypeIndex !== -1) {
styleNodes[n].attributes[styleTypeIndex].value[0].raw = 'text/css';
styleNodes[n].attributes[styleTypeIndex].value[0].data = 'text/css';
} else {
styleNodes[n].attributes.push({ name: 'type', type: 'Attribute', value: [{ type: 'Text', raw: 'text/css', data: 'text/css' }] });
}
+ // remove lang="*"
const styleLangIndex = styleNodes[n].attributes.findIndex(({ name }: any) => name === 'lang');
if (styleLangIndex !== -1) styleNodes[n].attributes.splice(styleLangIndex, 1);
+ // TODO: add data-astro for later
+ // styleNodes[n].attributes.push({ name: 'data-astro', type: 'Attribute', value: true });
}
});
-
- // 2. inject finished <style> tags into root node
- // TODO: pull out into <link> tags for deduping
- rootNode.children = [...styleNodes, ...(rootNode.children || [])];
},
};
}
diff --git a/src/parser/interfaces.ts b/src/parser/interfaces.ts
index 89c99aa20..848f48ec9 100644
--- a/src/parser/interfaces.ts
+++ b/src/parser/interfaces.ts
@@ -53,7 +53,7 @@ export interface Parser {
html: Node;
css: Node;
js: Node;
- meta_tags: {};
+ meta_tags: Map<string, string>;
}
export interface Script extends BaseNode {
diff --git a/src/runtime.ts b/src/runtime.ts
index 42024eff4..f36ef1225 100644
--- a/src/runtime.ts
+++ b/src/runtime.ts
@@ -1,8 +1,8 @@
-import type { SnowpackDevServer, ServerRuntime as SnowpackServerRuntime, LoadResult as SnowpackLoadResult, SnowpackConfig } from 'snowpack';
+import type { SnowpackDevServer, ServerRuntime as SnowpackServerRuntime, SnowpackConfig } from 'snowpack';
import type { AstroConfig } from './@types/astro';
import type { LogOptions } from './logger';
import type { CompileError } from './parser/utils/error.js';
-import { info } from './logger.js';
+import { debug, info } from './logger.js';
import { existsSync } from 'fs';
import { loadConfiguration, logger as snowpackLogger, startServer as startSnowpackServer } from 'snowpack';
@@ -39,7 +39,6 @@ async function load(config: RuntimeConfig, rawPathname: string | undefined): Pro
const selectedPageLoc = new URL(`./pages/${selectedPage}.astro`, astroRoot);
const selectedPageMdLoc = new URL(`./pages/${selectedPage}.md`, astroRoot);
- const selectedPageUrl = `/_astro/pages/${selectedPage}.js`;
// Non-Astro pages (file resources)
if (!existsSync(selectedPageLoc) && !existsSync(selectedPageMdLoc)) {
@@ -62,49 +61,61 @@ async function load(config: RuntimeConfig, rawPathname: string | undefined): Pro
}
}
- try {
- const mod = await snowpackRuntime.importModule(selectedPageUrl);
- let html = (await mod.exports.__renderPage({
- request: {
- host: fullurl.hostname,
- path: fullurl.pathname,
- href: fullurl.toString(),
- },
- children: [],
- props: {},
- })) as string;
-
- // inject styles
- // TODO: handle this in compiler
- const styleTags = Array.isArray(mod.css) && mod.css.length ? mod.css.reduce((markup, url) => `${markup}\n<link rel="stylesheet" type="text/css" href="${url}" />`, '') : ``;
- if (html.indexOf('</head>') !== -1) {
- html = html.replace('</head>', `${styleTags}</head>`);
- } else {
- html = styleTags + html;
- }
+ for (const url of [`/_astro/pages/${selectedPage}.astro.js`, `/_astro/pages/${selectedPage}.md.js`]) {
+ try {
+ const mod = await snowpackRuntime.importModule(url);
+ debug(logging, 'resolve', `${reqPath} -> ${url}`);
+ let html = (await mod.exports.__renderPage({
+ request: {
+ host: fullurl.hostname,
+ path: fullurl.pathname,
+ href: fullurl.toString(),
+ },
+ children: [],
+ props: {},
+ })) as string;
+
+ // inject styles
+ // TODO: handle this in compiler
+ const styleTags = Array.isArray(mod.css) && mod.css.length ? mod.css.reduce((markup, href) => `${markup}\n<link rel="stylesheet" type="text/css" href="${href}" />`, '') : ``;
+ if (html.indexOf('</head>') !== -1) {
+ html = html.replace('</head>', `${styleTags}</head>`);
+ } else {
+ html = styleTags + html;
+ }
- return {
- statusCode: 200,
- contents: html,
- };
- } catch (err) {
- switch (err.code) {
- case 'parse-error': {
- return {
- statusCode: 500,
- type: 'parse-error',
- error: err,
- };
+ return {
+ statusCode: 200,
+ contents: html,
+ };
+ } catch (err) {
+ // if this is a 404, try the next URL (will be caught at the end)
+ const notFoundError = err.toString().startsWith('Error: Not Found');
+ if (notFoundError) {
+ continue;
}
- default: {
+
+ if (err.code === 'parse-error') {
return {
statusCode: 500,
- type: 'unknown',
+ type: 'parse-error',
error: err,
};
}
+ return {
+ statusCode: 500,
+ type: 'unknown',
+ error: err,
+ };
}
}
+
+ // couldn‘t find match; 404
+ return {
+ statusCode: 404,
+ type: 'unknown',
+ error: new Error(`Could not locate ${selectedPage}`),
+ };
}
export interface AstroRuntime {
diff --git a/test/astro-styles-ssr.test.js b/test/astro-styles-ssr.test.js
index 9ee67f69b..2342fcda4 100644
--- a/test/astro-styles-ssr.test.js
+++ b/test/astro-styles-ssr.test.js
@@ -8,6 +8,16 @@ const StylesSSR = suite('Styles SSR');
let runtime;
+/** Basic CSS minification; removes some flakiness in testing CSS */
+function cssMinify(css) {
+ return css
+ .trim() // remove whitespace
+ .replace(/\n\s*/g, '') // collapse lines
+ .replace(/\s*\{/g, '{') // collapse selectors
+ .replace(/:\s*/g, ':') // collapse attributes
+ .replace(/;}/g, '}'); // collapse block
+}
+
StylesSSR.before(async () => {
const astroConfig = await loadConfig(new URL('./fixtures/astro-styles-ssr', import.meta.url).pathname);
@@ -54,12 +64,15 @@ StylesSSR('CSS Module support in .astro', async () => {
let scopedClass;
// test 1: <style> tag in <head> is transformed
- const css = $('style')
- .html()
- .replace(/\.astro-[A-Za-z0-9-]+/, (match) => {
- scopedClass = match;
- return match;
- }); // remove class hash (should be deterministic / the same every time, but even still don‘t cause this test to flake)
+ const css = cssMinify(
+ $('style')
+ .html()
+ .replace(/\.astro-[A-Za-z0-9-]+/, (match) => {
+ scopedClass = match; // get class hash from result
+ return match;
+ })
+ );
+
assert.equal(css, `.wrapper${scopedClass}{margin-left:auto;margin-right:auto;max-width:1200px}`);
// test 2: element received .astro-XXXXXX class (this selector will succeed if transformed correctly)
diff --git a/test/fixtures/astro-markdown/astro/pages/post.md b/test/fixtures/astro-markdown/astro/pages/post.md
index 3a97cf4ec..58ebdc945 100644
--- a/test/fixtures/astro-markdown/astro/pages/post.md
+++ b/test/fixtures/astro-markdown/astro/pages/post.md
@@ -1,5 +1,5 @@
---
-layout: layouts/content.astro
+layout: ../layouts/content.astro
title: My Blog Post
description: This is a post about some stuff.
import:
@@ -10,4 +10,4 @@ import:
<div id="first">Some content</div>
-<Example /> \ No newline at end of file
+<Example />