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

fix(gatsby): Wrong route resolved by findPageByPath function #34070

Merged
merged 6 commits into from
Jan 4, 2022
Merged

fix(gatsby): Wrong route resolved by findPageByPath function #34070

merged 6 commits into from
Jan 4, 2022

Conversation

tlgimenes
Copy link
Contributor

@tlgimenes tlgimenes commented Nov 24, 2021

Description

This PR uses reach router's best matching route algorithm to resolve pages in findPageByPath function so we resolve to the best matching route instead of the first match.

Motivation

I'm playing around with Gatsby v4 and the File System Route API I ended up writing a project with the following pages directory:

./src/pages/
├── 404.tsx
├── 500.tsx
├── [...].tsx
├── [slug]
│   └── p
│       └── index.tsx
├── index.tsx

Both [...].tsx and [slug]/p/index.tsx pages use SSR rendering mode.
My intended behavior with this routing layout is for routes like /banana/p and /apple/p to be resolved to the [slug]/p/index.tsx page and routes like /ananas or /ananas/yellow to be resolved to the [...].tsx page.

I noticed that when running gatsby build && gatsby serve, the project worked as intended, but when running gatsby develop or when deploying it on both Netlify and Gatsby Cloud, my /banana/p and /apple/p where being resolved to the [...].tsx page.

Looking on both Netlify and Gatsby implemetations, I've noticed that, for resolving pages, they use this findPageByPath function. This function was not respecting reach router's best matching algorithm which led to the wrong page being resolved to.
This PR fixes this problem by using reach router's pick function. A drawback of this solution is that it may lead to some performance regressions since we parse and pick the best route for each function call. However, I believe the impact should be minimal since usually the number of routes to match should not be huge (~10 routes).

I'm open for other solutions and I hope this PR serves as a guide to fix this problem.
Thanks!

@gatsbot gatsbot bot added the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label Nov 24, 2021
@tlgimenes tlgimenes changed the title fix(gatsby): Use best matching route fix(gatsby): Wrong route resolved by findPageByPath function Nov 26, 2021
@KyleAMathews
Copy link
Contributor

This makes sense!

Could you add some new tests that show how this fixed routing for the scenarios you described that don't currently work?

@tlgimenes
Copy link
Contributor Author

tlgimenes commented Dec 3, 2021

Hey, thanks for the reply @KyleAMathews.

I wasn't really sure where to add the tests so I added them on e2e-tests/production-runtime at the SSR section. I added the following pages layout to this e2e test:

$ tree -L 4 ./e2e-tests/production-runtime/src/pages/ssr/path-ranking/
./e2e-tests/production-runtime/src/pages/ssr/path-ranking/
├── [...].js
└── [p1]
    ├── [p2].js
    └── page.js

On cypress, I added tests that open the following path and check if they resolve to the right file:

visit /p1 -> resolve to file [...].js
visit /p1/p2 -> resolve to file /[p1]/p2].js
visit /p1/page -> resolve to file /[p1]/page.js
visit /p1/p2/p3 -> resolve to file [...].js

Finally, I checked that the new version works correctly, whereas the master version fails on these tests.

Let me know if you think on different solutions or different places to put those tests. Thanks!

@wardpeet wardpeet requested a review from pieh December 3, 2021 20:37
@tlgimenes
Copy link
Contributor Author

Hi @pieh, any news about this one?

Let me know if you need any changes, Thanks!

@heynemann
Copy link

Just to add some color to this PR, this unlocks large enterprise clients (think very large multi-country enterprises) for VTEX. Our team bet on Gatsby and we're super happy with it. This PR would allow the team to move forward with migrating our clients to Gatsby V4, thus further improving their experience.

Is there anything we can do to help with the reviewing process? We're here to help!

Thanks for all your hard work and for providing such an incredible tool. We're very excited and confident in our bet in Gatsby.

@pieh pieh self-assigned this Jan 4, 2022
@pieh pieh added topic: core Relates to Gatsby's core (e.g. page loading, reporter, state machine) and removed status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer labels Jan 4, 2022
@pieh
Copy link
Contributor

pieh commented Jan 4, 2022

This looks correct, I will just expand our existing unit tests as well.

While I will very likely merge as-is. This will need some iteration in the future to make it more performant and just consume less memory (memory usage note is actually more about what we already have than changes in this PR). When findPageByPath is used by engines (DSG / SSR) and we "fall back" to matchPath handling we do load all routes from LMDB store into memory and this is not great in general. Instead we should make use of match-paths.json we generate in https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/bootstrap/requires-writer.ts (actually it might be good idea to write out 2 variants of it - one that we have that also contain overlapping static pages - needed for browser runtime and new one that just contain match-paths ordered by specifity). This way we never will have to pull all the pages in memory with engines (maybe this can also be used with non-engines usages, but that becomes more tricky and we already have pages in memory then, so it's just CPU overhead and this is only used in gatsby develop IIRC)

Copy link
Contributor

@pieh pieh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @tlgimenes for implementing the fix and adding E2E test cases to make sure it works and there will be no regressions in the future!

@pieh pieh merged commit 0cc5a5a into gatsbyjs:master Jan 4, 2022
@pieh
Copy link
Contributor

pieh commented Jan 4, 2022

This change was just released in @next channel (gatsby@4.5.0-next.4) and will be available in next stable release (~week from now)

moonmeister added a commit to moonmeister/gatsby that referenced this pull request Jan 5, 2022
* master: (125 commits)
  chore(release): Publish next
  fix(gatsby): createNode return promise (gatsbyjs#34399)
  chore(release): Publish next
  fix(gatsby): Wrong route resolved by findPageByPath function (gatsbyjs#34070)
  fix(deps): update typescript to v5 (major) (gatsbyjs#33786)
  chore(docs): Update processing external images guide (gatsbyjs#34388)
  chore(deps): update dependency aws-sdk to ^2.1048.0 (gatsbyjs#34365)
  chore(deps): update dependency autoprefixer to ^10.4.1 for gatsby-plugin-sass (gatsbyjs#34357)
  chore(deps): update formatting & linting (gatsbyjs#34370)
  fix(deps): update minor and patch dependencies for gatsby-source-drupal (gatsbyjs#34375)
  fix(deps): update dependency eslint-plugin-react to ^7.28.0 (gatsbyjs#34372)
  fix(deps): update dependency resolve-url-loader to ^3.1.4 for gatsby-plugin-sass (gatsbyjs#34361)
  chore(deps): update dependency typescript to ^4.5.4 (gatsbyjs#34358)
  chore(docs): Fix links to shared layout component (gatsbyjs#34330)
  chore: Fix typo (gatsbyjs#34349)
  chore(examples): use mobx v6 in using-mobx example (gatsbyjs#34351)
  chore(deps): update dependency rewire to v6 for gatsby-plugin-offline (gatsbyjs#34376)
  chore(deps): update dependency msw to ^0.36.3 for gatsby-core-utils (gatsbyjs#34367)
  chore(deps): update dependency msw to ^0.36.3 for gatsby-plugin-gatsby-cloud (gatsbyjs#34368)
  fix(deps): update dependency graphql to ^15.8.0 for gatsby-codemods (gatsbyjs#34373)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: core Relates to Gatsby's core (e.g. page loading, reporter, state machine)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants