diff options
28 files changed, 246 insertions, 191 deletions
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 index d5891f6b4..d5891f6b4 100644 --- a/examples/blog-multiple-authors/public/global.scss +++ b/examples/blog-multiple-authors/public/global.css diff --git a/examples/blog/public/blog.scss b/examples/blog/public/blog.css index 2cee5a81a..2cee5a81a 100644 --- a/examples/blog/public/blog.scss +++ b/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>{title}</title> <link rel="icon" type="image/x-icon" href="/favicon.ico" /> - -<link rel="stylesheet" type="text/css" href="/global.css"> +<link rel="stylesheet" type="text/css" href="/_astro/src/scss/global.css"> <link rel="preconnect" href="https://fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;400;700;900&display=swap" rel="stylesheet"> diff --git a/examples/portfolio/public/global.scss b/examples/portfolio/src/scss/global.scss index b5a95caf2..b5a95caf2 100644 --- a/examples/portfolio/public/global.scss +++ b/examples/portfolio/src/scss/global.scss diff --git a/examples/with-markdown/public/styles/prism.scss b/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; <link rel="icon" type="image/x-icon" href="/favicon.ico" /> <title>{content.title}</title> - <link rel="stylesheet" href="/styles/global.css"> + <link rel="stylesheet" href="/global.css"> </head> <body> <slot/> 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<string> { /** Bundle JS action */ export async function bundleJS(imports: Set<string>, { astroRuntime, dist }: BundleOptions): Promise<BundleStatsMap> { 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('<script src="/example.js"></script>')); + assert.ok(indexHtml.includes('<link href="/example.css" ref="stylesheet">')); + assert.ok(indexHtml.includes('<img src="/images/twitter.png">')); +}); + +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 --- /dev/null +++ b/packages/astro/test/fixtures/astro-public/public/example.css 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 --- /dev/null +++ b/packages/astro/test/fixtures/astro-public/public/example.js diff --git a/packages/astro/test/fixtures/astro-public/public/images/twitter.png b/packages/astro/test/fixtures/astro-public/public/images/twitter.png Binary files differnew file mode 100644 index 000000000..ad4cae1e9 --- /dev/null +++ b/packages/astro/test/fixtures/astro-public/public/images/twitter.png 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 @@ +<html lang="en"> +<head> + <title>This Site</title> + <link href="/example.css" ref="stylesheet"/> + <script src="/example.js"></script> +</head> +<body> + <img src="/images/twitter.png" /> +</body> +</html>
\ 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; --- <BaseHead title={title} description={description} canonicalURL={canonicalURL} /> -<link rel="stylesheet" href="/blog.css" />
\ No newline at end of file +<link rel="stylesheet" href={Astro.resolve('../../scss/blog.css')} />
\ 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'; <html lang={ lang ?? 'en' }> <head> <BaseHead title={title} description={description} permalink={permalink} /> - <link rel="stylesheet" href="/blog.css" /> + <link rel="stylesheet" href={Astro.resolve('../../scss/blog.css')} /> <style> body { diff --git a/www/src/pages/blog/introducing-astro.astro b/www/src/pages/blog/introducing-astro.astro index 8cf6a9eb6..3f7e13f4c 100644 --- a/www/src/pages/blog/introducing-astro.astro +++ b/www/src/pages/blog/introducing-astro.astro @@ -19,7 +19,7 @@ let lang = 'en'; <html lang={ lang ?? 'en' }> <head> <BaseHead title={title} description={description} permalink={permalink} /> - <link rel="stylesheet" href="/blog.css" /> + <link rel="stylesheet" href={Astro.resolve('../../scss/blog.css')} /> </head> <body> diff --git a/www/src/pages/index.astro b/www/src/pages/index.astro index 6ef6ad710..ea4f8b38b 100644 --- a/www/src/pages/index.astro +++ b/www/src/pages/index.astro @@ -18,7 +18,7 @@ let lang = 'en'; <html lang={ lang ?? 'en' }> <head> <BaseHead title={title} description={description} permalink={permalink} /> - <link rel="stylesheet" href="/global.css" /> + <link rel="stylesheet" href={Astro.resolve('../scss/global.css')} /> </head> <body> diff --git a/www/public/blog.scss b/www/src/scss/blog.scss index 3be4f48ec..3be4f48ec 100644 --- a/www/public/blog.scss +++ b/www/src/scss/blog.scss diff --git a/www/public/code.scss b/www/src/scss/code.scss index ec0e8dea2..ec0e8dea2 100644 --- a/www/public/code.scss +++ b/www/src/scss/code.scss diff --git a/www/public/global.scss b/www/src/scss/global.scss index 111e5bac3..111e5bac3 100644 --- a/www/public/global.scss +++ b/www/src/scss/global.scss |