-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improvements to build and dev when building for subpaths #3156
Conversation
🦋 Changeset detectedLatest commit: c13a936 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
4a70a34
to
6adf1f1
Compare
614cde1
to
4ada547
Compare
@@ -111,6 +111,25 @@ async function handle404Response( | |||
if (pathname === '/' && !pathname.startsWith(devRoot)) { | |||
html = subpathNotUsedTemplate(devRoot, pathname); | |||
} else { | |||
// HACK: redirect without the base path for assets in publicDir | |||
const redirectTo = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not too happy with doing a redirect here...
We currently handle base paths ourselves and don't let Vite do it. In dev, that means Vite sends us a 404 on assets that are in public
Longer term it might be the right move to lean on Vite for base
config.
I tried this locally hoping that would do the trick and the main hurdle is that Astro.request
will never be given context on the base path since Vite strips that out. That kind of makes sense actually Astro.request.url
would always match the src/pages
directory structure, but would be a breaking change from current behavior
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so as a general rule, we usually don't want to redirect in dev since the developer might accidentally rely on that behavior during dev, and then ship to prod with broken code. Not sure I 100% understand what's going on here so can't say for sure, just as long as you're accounting for the goal: "don't implement helpful behavior in dev that might not exist in prod. It's usually better to error."
Now having said that, we do default trailingSlash
to ignore
, so maybe developer convenience is also worth taking into account.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit of a weird case for sure!
Assets in public
will hit a 404 in dev. public/images/penguin.png
should be referenced as src="/subpath/images/penguin.png"
but Vite will 404 there, this redirect will only redirect if the requests pathname matches /{subpath}/...
The redirect strips off the subpath and sends that as the 302 location, letting the browser find the image in public
even though templates will use /subpath/...
for the <img src>
} | ||
|
||
export function joinPaths(...paths: (string | undefined)[]) { | ||
return paths.filter(isString).map(trimSlashes).join('/'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer being explicit and using filter(x => isString(x))
rather than filter(isString)
. Ditto with trimSlashes
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typescript doesn't figure out type narrowing with inline functions 🤔
// TS recognizes that only strings pass the filter
paths.filter(isString).map(trimSlashes)
// TS ignores the filter type and errors that `trimSlashes` is being called with `string | undefined`
paths.filter(x => isString(x)).map(x => trimSlashes(x))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, this is oddly the "TS-approved" way to do it, afaik
const site = astroConfig.base && astroConfig.base !== './' | ||
? joinPaths(astroConfig.site?.toString() || 'http:https://localhost/', astroConfig.base) | ||
: astroConfig.site; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the fix I expected. Are we checking that astroConfig.site
doesn't also end with base
? Maybe that's validated when we load the config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep! We already throw an error if the site
includes a URL path
[config] Astro found issue(s) with your configuration:
! site "site" must be a valid URL origin (ex: "https://example.com") but cannot contain a URL path (ex: "https://example.com/blog"). Use "base" to configure your deployed URL path.
@@ -90,7 +94,7 @@ describe('Static build', () => { | |||
const links = $('link[rel=stylesheet]'); | |||
for (const link of links) { | |||
const href = $(link).attr('href'); | |||
const data = await fixture.readFile(addLeadingSlash(href)); | |||
const data = await fixture.readFile(removeBasePath(addLeadingSlash(href))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... how does this work? Are the assets emitted at /subpath/assets
or /assets
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assets are built to /dist
, the main astro build
bug here was that injected scripts and links didn't include the subpath
This test finds a stylesheet similar to <link rel="stylesheet" href="/subpath/assets/chunk.css">
and strips off the subpath when verifying the file exists (mimicing the behavior once it's deployed to a subpath in production)
Now that I understand the behavior of site/base better, this all makes sense to me. 👍 |
…)" This reverts commit 637919c.
…)" This reverts commit 637919c.
…)" This reverts commit 637919c.
…)" This reverts commit 637919c.
…)" This reverts commit 637919c.
* Revert "Improvements to build and dev when building for subpaths (#3156)" This reverts commit 637919c. * letting Vite handle base paths * test updates to expect Astro.request.url to no longer include subpaths * bringing back the fix for including subpaths in injects scripts and styles * fixing the static-build test to handle subpaths for injected CSS * fixing asset import URLs when using base subpaths * chore: fixing typo in the comments * Astro needs to manage base in dev to maintain Astro.request.url * fix: reverting dev routing tests to expect existing behavior * reverting Astro global test to verify existing behavior * chore: adding changeset * test: update static-build tests to verify the subpath is used in asset imports
…tro#3178) * Revert "Improvements to build and dev when building for subpaths (withastro#3156)" This reverts commit 637919c. * letting Vite handle base paths * test updates to expect Astro.request.url to no longer include subpaths * bringing back the fix for including subpaths in injects scripts and styles * fixing the static-build test to handle subpaths for injected CSS * fixing asset import URLs when using base subpaths * chore: fixing typo in the comments * Astro needs to manage base in dev to maintain Astro.request.url * fix: reverting dev routing tests to expect existing behavior * reverting Astro global test to verify existing behavior * chore: adding changeset * test: update static-build tests to verify the subpath is used in asset imports
) * `astro build` should include the `base` provided in astro config * test: updating build test to expect the base path in links/scripts * ignore the default "base" value when building links/scripts * fix: handling config that provides a base but no site * fix: config.site was being ignored since it's a URL not a string * hack: handle base path in dev for /public assets * fix: dev redirect needs to ignore base default of ./ * fix: extra safety checks for the base path redirect * refactor: simplifying it to remove the regex * one last safety check - only redirect GET and use a 302 status * fix: lost the leading slash when redirecting * nit: adding comments to the test explaining how base is verified * Remove extra console.log * Adds a changeset Co-authored-by: unknown <[email protected]>
…tro#3178) * Revert "Improvements to build and dev when building for subpaths (withastro#3156)" This reverts commit 637919c. * letting Vite handle base paths * test updates to expect Astro.request.url to no longer include subpaths * bringing back the fix for including subpaths in injects scripts and styles * fixing the static-build test to handle subpaths for injected CSS * fixing asset import URLs when using base subpaths * chore: fixing typo in the comments * Astro needs to manage base in dev to maintain Astro.request.url * fix: reverting dev routing tests to expect existing behavior * reverting Astro global test to verify existing behavior * chore: adding changeset * test: update static-build tests to verify the subpath is used in asset imports
Changes
Fixes a bug in
astro build
that was breaking injected links and styles in projects deployed to subpaths[x] fixes a bug where
astro build
wasn't prepending the base path for injected links and styles[x] updates the
dev
server to handle thebase
path when assets frompublic
are requestedTesting
Updated static-build test suite to expect injected style links to include the
base
path fromastro.config.js
Docs
N/A