diff --git a/.changeset/young-rice-sort.md b/.changeset/young-rice-sort.md new file mode 100644 index 000000000..1bdb8160d --- /dev/null +++ b/.changeset/young-rice-sort.md @@ -0,0 +1,9 @@ +--- +'astro': minor +--- + +**[BREAKING CHANGE]** stop bundling, building, and processing public files. This fixes an issue where we weren't actually honoring the "do not process" property of the public directory. + +If you were using the `public/` directory as expected and not using it to build files for you, then this should not be a breaking change. However, will notice that these files are no longer bundled. + +If you were using the `public/` directory to build files (for example, like `public/index.scss`) then you can expect this to no longer work. As per the correct Astro documentation. diff --git a/examples/blog-multiple-authors/public/global.scss b/examples/blog-multiple-authors/public/global.css similarity index 100% rename from examples/blog-multiple-authors/public/global.scss rename to examples/blog-multiple-authors/public/global.css diff --git a/examples/blog/public/blog.scss b/examples/blog/public/blog.css similarity index 100% rename from examples/blog/public/blog.scss rename to examples/blog/public/blog.css diff --git a/examples/blog/public/global.css b/examples/blog/public/global.css new file mode 100644 index 000000000..3566fce27 --- /dev/null +++ b/examples/blog/public/global.css @@ -0,0 +1,95 @@ +:root { + --font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --font-mono: 'IBM Plex Mono', Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace; + --color-green: #17c083; +} + +* { + box-sizing: border-box; + margin: 0; +} + +html { + display: grid; + width: 100%; + max-width: 100vw; + overflow: hidden; + height: 100%; + background-color: #000014; +} + +html, +body { + padding: 0; + font-size: clamp(14px, calc(1rem + (3vw - 1.2rem)), 20px); + font-family: var(--font-sans); + font-weight: 400; + background-image: radial-gradient(87.7% 87.7% at 85.6% 18.14%, #111827 0%, #000014 100%); + background-repeat: no-repeat; + color: #f3f4f6; +} + +body { + position: relative; + display: grid; + place-items: center; + min-width: 100%; + max-width: 100vw; + min-height: 100vh; + overflow-x: hidden; +} + +.visually-hidden { + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; +} + +a { + position: relative; + text-decoration: none; + color: var(--color-green); + padding: 0.05em 0.125em; + margin: -0.05em -0.125em; + transition: color 120ms cubic-bezier(0.23, 1, 0.32, 1); + z-index: 0; + display: inline-block; +} + +a:hover, a:focus { + color: black; +} + +a:hover::before, a:focus::before { + transform: scaleY(1); + background: var(--color-green); +} + +a:visited { + color: var(--color-green); +} + +a:visited:hover, a:visited:focus { + color: black; +} + +a::before { + transform-origin: bottom center; + content: ''; + display: block; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + inset: 0; + background: var(--color-green); + pointer-events: none; + transform: scaleY(0.05); + transition: transform 120ms cubic-bezier(0.23, 1, 0.32, 1), background 120ms cubic-bezier(0.23, 1, 0.32, 1); + z-index: -1; +} \ No newline at end of file diff --git a/examples/blog/public/global.scss b/examples/blog/public/global.scss deleted file mode 100644 index 5aea52933..000000000 --- a/examples/blog/public/global.scss +++ /dev/null @@ -1,93 +0,0 @@ -:root { - --font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; - --font-mono: 'IBM Plex Mono', Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', - 'Liberation Mono', 'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace; - --color-green: #17c083; -} - -* { - box-sizing: border-box; - margin: 0; -} -html { - display: grid; - width: 100%; - max-width: 100vw; - overflow: hidden; - height: 100%; - background-color: #000014; -} -html, -body { - padding: 0; - font-size: clamp(14px, calc(1rem + (3vw - 1.2rem)), 20px); - font-family: var(--font-sans); - font-weight: 400; - background-image: radial-gradient(87.7% 87.7% at 85.6% 18.14%, #111827 0%, #000014 100%); - background-repeat: no-repeat; - color: #f3f4f6; -} -body { - position: relative; - display: grid; - place-items: center; - min-width: 100%; - max-width: 100vw; - min-height: 100vh; - overflow-x: hidden; -} -.visually-hidden { - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px; -} -a { - position: relative; - text-decoration: none; - color: var(--color-green); - padding: 0.05em 0.125em; - margin: -0.05em -0.125em; - transition: color 120ms cubic-bezier(0.23, 1, 0.32, 1); - z-index: 0; - display: inline-block; - - &:hover, - &:focus { - color: rgba(0, 0, 0, 1); - - &::before { - transform: scaleY(1); - background: var(--color-green); - } - } - - &:visited { - // color: var(--color-green); - color: var(--color-green); - &:hover, - &:focus { - color: rgba(0, 0, 0, 1); - } - } - - &::before { - transform-origin: bottom center; - content: ''; - display: block; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - inset: 0; - background: var(--color-green); - pointer-events: none; - transform: scaleY(0.05); - transition: transform 120ms cubic-bezier(0.23, 1, 0.32, 1), background 120ms cubic-bezier(0.23, 1, 0.32, 1); - z-index: -1; - } -} diff --git a/examples/portfolio/src/components/MainHead.astro b/examples/portfolio/src/components/MainHead.astro index 3a542edc5..df3c4f7a3 100644 --- a/examples/portfolio/src/components/MainHead.astro +++ b/examples/portfolio/src/components/MainHead.astro @@ -6,7 +6,6 @@ const { title = 'Jeanine White: Personal Site' } = Astro.props; {title} - - + diff --git a/examples/portfolio/public/global.scss b/examples/portfolio/src/scss/global.scss similarity index 100% rename from examples/portfolio/public/global.scss rename to examples/portfolio/src/scss/global.scss diff --git a/examples/with-markdown/public/styles/prism.scss b/examples/with-markdown/public/global.css similarity index 50% rename from examples/with-markdown/public/styles/prism.scss rename to examples/with-markdown/public/global.css index 29a3cf5d8..7cb613d30 100644 --- a/examples/with-markdown/public/styles/prism.scss +++ b/examples/with-markdown/public/global.css @@ -1,69 +1,69 @@ pre, code { - color: #d4d4d4; - font-size: 14px; - font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; - line-height: 1.5; - direction: ltr; - white-space: pre; - text-align: left; - text-shadow: none; - word-break: normal; - word-spacing: normal; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; + color: #d4d4d4; + font-size: 14px; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + line-height: 1.5; + direction: ltr; + white-space: pre; + text-align: left; + text-shadow: none; + word-break: normal; + word-spacing: normal; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; } pre::selection, code::selection { - text-shadow: none; - background: #b3d4fc; + text-shadow: none; + background: #b3d4fc; } @media print { - pre, + pre, code { - text-shadow: none; - } + text-shadow: none; + } } pre { - margin: 0.5rem 0 16px; - padding: 0.8rem 1rem 0.9rem; - overflow: auto; - background: #282a36; - border-radius: 4px; + margin: 0.5rem 0 16px; + padding: 0.8rem 1rem 0.9rem; + overflow: auto; + background: #282a36; + border-radius: 4px; } :not(pre) > code { - padding: 0.1em 0.3em; - color: #db4c69; - background: #f9f2f4; - border-radius: 0.3em; - white-space: pre-wrap; + padding: 0.1em 0.3em; + color: #db4c69; + background: #f9f2f4; + border-radius: 0.3em; + white-space: pre-wrap; } /********************************************************* * Tokens */ .namespace { - opacity: 0.7; + opacity: 0.7; } .token.comment, .token.prolog, .token.doctype, .token.cdata { - color: #6a9955; + color: #6a9955; } .token.punctuation { - color: #d4d4d4; + color: #d4d4d4; } .token.property, @@ -73,7 +73,7 @@ pre { .token.constant, .token.symbol, .token.deleted { - color: #b5cea8; + color: #b5cea8; } .token.selector, @@ -82,7 +82,7 @@ pre { .token.char, .token.builtin, .token.inserted { - color: #ce9178; + color: #ce9178; } .token.operator, @@ -90,86 +90,86 @@ pre { .token.url, .language-css .token.string, .style .token.string { - color: #d4d4d4; - background: rgb(45, 55, 72); + color: #d4d4d4; + background: #2d3748; } .token.atrule, .token.attr-value, .token.keyword { - color: #c586c0; + color: #c586c0; } .token.function { - color: #dcdcaa; + color: #dcdcaa; } .token.regex, .token.important, .token.variable { - color: #d16969; + color: #d16969; } .token.important, .token.bold { - font-weight: bold; + font-weight: bold; } .token.italic { - font-style: italic; + font-style: italic; } .token.constant { - color: #9cdcfe; + color: #9cdcfe; } .token.class-name { - color: #4ec9b0; + color: #4ec9b0; } .token.parameter { - color: #9cdcfe; + color: #9cdcfe; } .token.interpolation { - color: #9cdcfe; + color: #9cdcfe; } .token.punctuation.interpolation-punctuation { - color: #569cd6; + color: #569cd6; } .token.boolean { - color: #569cd6; + color: #569cd6; } .token.property { - color: #9cdcfe; + color: #9cdcfe; } .token.selector { - color: #d7ba7d; + color: #d7ba7d; } .token.tag { - color: #569cd6; + color: #569cd6; } .token.attr-name { - color: #9cdcfe; + color: #9cdcfe; } .token.attr-value { - color: #ce9178; + color: #ce9178; } .token.entity { - color: #4ec9b0; - cursor: unset; + color: #4ec9b0; + cursor: unset; } .token.namespace { - color: #4ec9b0; + color: #4ec9b0; } /********************************************************* @@ -177,52 +177,59 @@ pre { */ pre[class*='language-javascript'], code[class*='language-javascript'] { - color: #4ec9b0; + color: #4ec9b0; } pre[class*='language-css'], code[class*='language-css'] { - color: #ce9178; + color: #ce9178; } pre[class*='language-html'], code[class*='language-html'] { - color: #d4d4d4; + color: #d4d4d4; } .language-html .token.punctuation { - color: #808080; + color: #808080; } /********************************************************* * Line highlighting */ pre[data-line] { - position: relative; + position: relative; } pre > code { - position: relative; - z-index: 1; + position: relative; + z-index: 1; } .line-highlight { - position: absolute; - right: 0; - left: 0; - z-index: 0; - margin-top: 1em; - padding: inherit 0; - line-height: inherit; - white-space: pre; - background: #f7ebc6; - box-shadow: inset 5px 0 0 #f7d87c; - pointer-events: none; + position: absolute; + right: 0; + left: 0; + z-index: 0; + margin-top: 1em; + padding: inherit 0; + line-height: inherit; + white-space: pre; + background: #f7ebc6; + box-shadow: inset 5px 0 0 #f7d87c; + pointer-events: none; } pre[class*='language-bash'] .token.function { - color: #d4d4d4; + color: #d4d4d4; } + .token.comment { - color: #fff7; + color: #fff7; } + +body { + max-width: 900px; + margin: auto; +} + diff --git a/examples/with-markdown/public/styles/global.scss b/examples/with-markdown/public/styles/global.scss deleted file mode 100644 index 5d758a003..000000000 --- a/examples/with-markdown/public/styles/global.scss +++ /dev/null @@ -1,6 +0,0 @@ -@use "./prism.scss"; - -body { - max-width: 900px; - margin: auto; -} diff --git a/examples/with-markdown/src/layouts/main.astro b/examples/with-markdown/src/layouts/main.astro index c0e71dd45..548cbd2ca 100644 --- a/examples/with-markdown/src/layouts/main.astro +++ b/examples/with-markdown/src/layouts/main.astro @@ -9,7 +9,7 @@ const { content } = Astro.props; {content.title} - + diff --git a/packages/astro/src/build.ts b/packages/astro/src/build.ts index 6f60c862a..28c9c90b7 100644 --- a/packages/astro/src/build.ts +++ b/packages/astro/src/build.ts @@ -149,7 +149,7 @@ ${stack} astroRuntime.load(url).then((result) => { if (result.statusCode !== 200) { if (result.statusCode === 404) { - throw new Error(`${buildState[id].srcPath.href}: could not find "${path.basename(url)}"`); + throw new Error(`${buildState[id].srcPath.href}: could not find "${url}"`); } // there shouldn’t be a build error here throw (result as any).error || new Error(`unexpected status ${result.statusCode} when loading ${url}`); diff --git a/packages/astro/src/build/bundle/css.ts b/packages/astro/src/build/bundle/css.ts index 2cd59f24d..6da84da02 100644 --- a/packages/astro/src/build/bundle/css.ts +++ b/packages/astro/src/build/bundle/css.ts @@ -5,7 +5,7 @@ import { performance } from 'perf_hooks'; import shorthash from 'shorthash'; import cheerio from 'cheerio'; import esbuild from 'esbuild'; -import { getDistPath, getSrcPath, stopTimer } from '../util.js'; +import { getDistPath, getSrcPath, IS_ASTRO_FILE_URL, stopTimer } from '../util.js'; import { debug } from '../../logger.js'; // config @@ -46,7 +46,9 @@ export async function bundleCSS({ for (const pageUrl of sortedPages) { const { css } = depTree[pageUrl]; for (const cssUrl of css.keys()) { - if (cssMap.has(cssUrl)) { + if (!IS_ASTRO_FILE_URL.test(cssUrl)) { + // do not add to cssMap, leave as-is. + } else if (cssMap.has(cssUrl)) { // scenario 1: if multiple URLs require this CSS, upgrade to common chunk cssMap.set(cssUrl, COMMON_URL); } else { @@ -83,7 +85,7 @@ export async function bundleCSS({ await Promise.all( Object.keys(buildState).map(async (id) => { if (buildState[id].contentType !== 'text/css') return; - const { code } = await esbuild.transform(buildState[id].contents as string, { + const { code } = await esbuild.transform(buildState[id].contents.toString(), { loader: 'css', minify: true, }); diff --git a/packages/astro/src/build/bundle/js.ts b/packages/astro/src/build/bundle/js.ts index 7340d396b..4deecb30a 100644 --- a/packages/astro/src/build/bundle/js.ts +++ b/packages/astro/src/build/bundle/js.ts @@ -6,6 +6,7 @@ import { fileURLToPath } from 'url'; import { rollup } from 'rollup'; import { terser } from 'rollup-plugin-terser'; import { createBundleStats, addBundleStats, BundleStatsMap } from '../stats.js'; +import { IS_ASTRO_FILE_URL } from '../util.js'; interface BundleOptions { dist: URL; @@ -24,12 +25,13 @@ export function collectJSImports(buildState: BuildOutput): Set { /** Bundle JS action */ export async function bundleJS(imports: Set, { astroRuntime, dist }: BundleOptions): Promise { const ROOT = 'astro:root'; + const validImports = [...imports].filter((url) => IS_ASTRO_FILE_URL.test(url)); const root = ` - ${[...imports].map((url) => `import '${url}';`).join('\n')} + ${validImports.map((url) => `import '${url}';`).join('\n')} `; const inputOptions: InputOptions = { - input: [...imports], + input: validImports, plugins: [ { name: 'astro:build', diff --git a/packages/astro/src/build/util.ts b/packages/astro/src/build/util.ts index 3c74086e2..e3f2aaa17 100644 --- a/packages/astro/src/build/util.ts +++ b/packages/astro/src/build/util.ts @@ -5,6 +5,12 @@ import fs from 'fs'; import path from 'path'; import { URL } from 'url'; +/** + * Only Astro-handled imports need bundling. Any other imports are considered + * a part of `public/`, and should not be touched. + */ +export const IS_ASTRO_FILE_URL = /^\/(_astro|_astro_frontend|_snowpack)\//; + /** Normalize URL to its canonical form */ export function canonicalURL(url: string, base?: string): URL { let pathname = url.replace(/\/index.html$/, ''); // index.html is not canonical diff --git a/packages/astro/src/runtime.ts b/packages/astro/src/runtime.ts index 165df0a02..4145753ed 100644 --- a/packages/astro/src/runtime.ts +++ b/packages/astro/src/runtime.ts @@ -283,7 +283,7 @@ async function createSnowpack(astroConfig: AstroConfig, options: CreateSnowpackO }; const mountOptions = { - ...(existsSync(astroConfig.public) ? { [fileURLToPath(astroConfig.public)]: '/' } : {}), + ...(existsSync(astroConfig.public) ? { [fileURLToPath(astroConfig.public)]: { url: '/', static: true, resolve: false } } : {}), [fileURLToPath(frontendPath)]: '/_astro_frontend', [fileURLToPath(src)]: '/_astro/src', // must be last (greediest) }; diff --git a/packages/astro/test/astro-public.test.js b/packages/astro/test/astro-public.test.js new file mode 100644 index 000000000..c60227282 --- /dev/null +++ b/packages/astro/test/astro-public.test.js @@ -0,0 +1,21 @@ +import { suite } from 'uvu'; +import * as assert from 'uvu/assert'; +import { setup, setupBuild } from './helpers.js'; + +const Public = suite('Public'); + +setup(Public, './fixtures/astro-public'); +setupBuild(Public, './fixtures/astro-public'); + +Public('css and js files do not get bundled', async ({ build, readFile }) => { + await build().catch((err) => { + assert.ok(!err, 'Error during the build'); + }); + + let indexHtml = await readFile('/index.html'); + assert.ok(indexHtml.includes('')); + assert.ok(indexHtml.includes('')); + assert.ok(indexHtml.includes('')); +}); + +Public.run(); diff --git a/packages/astro/test/fixtures/astro-public/public/example.css b/packages/astro/test/fixtures/astro-public/public/example.css new file mode 100644 index 000000000..e69de29bb diff --git a/packages/astro/test/fixtures/astro-public/public/example.js b/packages/astro/test/fixtures/astro-public/public/example.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/astro/test/fixtures/astro-public/public/images/twitter.png b/packages/astro/test/fixtures/astro-public/public/images/twitter.png new file mode 100644 index 000000000..ad4cae1e9 Binary files /dev/null and b/packages/astro/test/fixtures/astro-public/public/images/twitter.png differ diff --git a/packages/astro/test/fixtures/astro-public/snowpack.config.json b/packages/astro/test/fixtures/astro-public/snowpack.config.json new file mode 100644 index 000000000..8f034781d --- /dev/null +++ b/packages/astro/test/fixtures/astro-public/snowpack.config.json @@ -0,0 +1,3 @@ +{ + "workspaceRoot": "../../../../../" +} diff --git a/packages/astro/test/fixtures/astro-public/src/pages/index.astro b/packages/astro/test/fixtures/astro-public/src/pages/index.astro new file mode 100644 index 000000000..1bb4b37e7 --- /dev/null +++ b/packages/astro/test/fixtures/astro-public/src/pages/index.astro @@ -0,0 +1,10 @@ + + + This Site + + + + + + + \ No newline at end of file diff --git a/www/src/components/BlogHead.astro b/www/src/components/BlogHead.astro index 30dc2f4ed..57168a494 100644 --- a/www/src/components/BlogHead.astro +++ b/www/src/components/BlogHead.astro @@ -4,4 +4,4 @@ import BaseHead from './BaseHead.astro'; const { title, description, canonicalURL } = Astro.props; --- - \ No newline at end of file + \ No newline at end of file diff --git a/www/src/pages/blog/index.astro b/www/src/pages/blog/index.astro index 41f4d3f77..22a22cdb2 100644 --- a/www/src/pages/blog/index.astro +++ b/www/src/pages/blog/index.astro @@ -12,7 +12,7 @@ let lang = 'en'; - +