Skip to content
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

Merged
merged 14 commits into from
Apr 21, 2022

Conversation

tony-sull
Copy link
Contributor

@tony-sull tony-sull commented Apr 20, 2022

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 the base path when assets from public are requested

Testing

Updated static-build test suite to expect injected style links to include the base path from astro.config.js

Docs

N/A

@changeset-bot
Copy link

changeset-bot bot commented Apr 20, 2022

🦋 Changeset detected

Latest commit: c13a936

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
astro Patch

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

@github-actions github-actions bot added pkg: astro Related to the core `astro` package (scope) test labels Apr 20, 2022
@tony-sull tony-sull marked this pull request as draft April 20, 2022 12:53
@tony-sull tony-sull marked this pull request as ready for review April 20, 2022 15:23
@tony-sull tony-sull changed the title Include base path when building injected scripts and links Improvements to build and dev when building for subpaths Apr 20, 2022
@@ -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 =
Copy link
Contributor Author

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

Copy link
Member

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.

Copy link
Contributor Author

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>

packages/astro/test/static-build.test.js Outdated Show resolved Hide resolved
}

export function joinPaths(...paths: (string | undefined)[]) {
return paths.filter(isString).map(trimSlashes).join('/');
Copy link
Member

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.

Copy link
Contributor Author

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))

Copy link
Member

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

Comment on lines +181 to +183
const site = astroConfig.base && astroConfig.base !== './'
? joinPaths(astroConfig.site?.toString() || 'http:https://localhost/', astroConfig.base)
: astroConfig.site;
Copy link
Member

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.

Copy link
Contributor Author

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)));
Copy link
Member

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?

Copy link
Contributor Author

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)

@matthewp
Copy link
Contributor

Now that I understand the behavior of site/base better, this all makes sense to me. 👍

@matthewp matthewp merged commit 637919c into main Apr 21, 2022
@matthewp matthewp deleted the fix/build-subpaths branch April 21, 2022 18:03
@github-actions github-actions bot mentioned this pull request Apr 21, 2022
tony-sull pushed a commit that referenced this pull request Apr 22, 2022
tony-sull pushed a commit that referenced this pull request May 2, 2022
tony-sull pushed a commit that referenced this pull request May 3, 2022
tony-sull pushed a commit that referenced this pull request May 3, 2022
tony-sull pushed a commit that referenced this pull request May 4, 2022
tony-sull pushed a commit that referenced this pull request May 5, 2022
* 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
nonphoto pushed a commit to nonphoto/astro that referenced this pull request May 6, 2022
…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
SiriousHunter pushed a commit to SiriousHunter/astro that referenced this pull request Feb 3, 2023
)

* `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]>
SiriousHunter pushed a commit to SiriousHunter/astro that referenced this pull request Feb 3, 2023
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: astro Related to the core `astro` package (scope)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants