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

feat: new routing system runtime implementation and changes #206

Merged

Conversation

james-elicx
Copy link
Contributor

@james-elicx james-elicx commented Apr 29, 2023

This PR does the following:

  • Implements a new routing system designed around the Vercel build output.
  • Replaces the old routing implementation in the _worker.js template.
  • Removes the old build-time logic that is no longer necessary.
  • Adds tests for the new functionality.
  • Fixes a bug where we were unable to fix functions that had valid squashed versions.
  • Allows building a worker file when no functions are found.

I know that we previously discussed doing 3 PRs, with the third PR being the one where the redundant build-time logic is removed and the routing system is enabled, however, Dario and I agreed that it would probably be best to do it in this PR instead.

Some of the functionality that this PR also introduces support for is as follows:

  • next.config.js: rewrites, redirects, custom headers.
  • middleware: redirects, rewrites, request header overrides, response manipulation, etc.
  • build output config route properties: dest, headers, continue, check, status.
  • correct dynamic/catch-all parameter handling.
  • statically generated routes.
Overview of routing
  • Call the function to start finding a match for the request. The matching function is recursive and calls itself again every time it enters a new phase.
    • Starts matching from the none phase.
    • For each route in the current phase.
      • Checks the src value for a match, and extracts the dynamic parameters.
      • Checks override and reset the response status and headers if it exists
      • Checks for middlewarePath, calls the middleware function, and processes the response.
      • Checks for headers and adds them to the response.
      • Checks for status and sets the response status.
      • Checks for dest and updates the path for matching with the new destination, applying the dynamic parameters from earlier.
      • Checks for check if the path is not an external URL.
        • If the rewritten path is equal to the previous path, enter the next phase i the current is not miss.
        • otherwise, enter the none phase.
      • Checks for continue to know if routing should continue.
    • If the route is found in the build output, it returns the match.
    • Decides what happens next, based on the current phase.
      • hit phase or for URLs / redirects -> return the match.
      • miss phase -> update status and enter hit phase to update headers.
      • error phase -> enter hit phase to update headers.
    • If routing should continue, it decides what should happen next for the following phases.
      • none phase -> enter filesystem phase.
      • filesystem phase -> enter rewrite phase.
      • rewrite phase -> enter resource phase.
      • resource phase -> enter miss phase.
  • If the final status is an error, it calls matching with the error phase to find the custom error page.
  • Serves a match.
    • If the match is a URL / redirect, it redirects to the URL.
    • It runs the entrypoint for the route.
    • Headers and status codes from routing are applied to the response.
    • The response gets returned.

I have tested this with some of the apps I have, but I warmly welcome others to test the prerelease against their projects.

fixes #185
fixes #177
fixes #163
fixes #21
fixes #70
fixes #129

@changeset-bot
Copy link

changeset-bot bot commented Apr 29, 2023

🦋 Changeset detected

Latest commit: ba7a8fc

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

This PR includes changesets to release 1 package
Name Type
@cloudflare/next-on-pages Minor

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
Copy link
Contributor

github-actions bot commented Apr 29, 2023

🧪 A prerelease is available for testing 🧪

You can install this latest build in your project with:

npm install --save-dev https://prerelease-registry.devprod.cloudflare.dev/next-on-pages/runs/4873321970/npm-package-next-on-pages-206

Or you can immediately run this with npx:

npx https://prerelease-registry.devprod.cloudflare.dev/next-on-pages/runs/4873321970/npm-package-next-on-pages-206

Copy link
Member

@dario-piotrowicz dario-piotrowicz left a comment

Choose a reason for hiding this comment

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

Needless to say, very awesome stuff thanks a lot ❤️

First round of comments 🙏 😅

Copy link
Member

@dario-piotrowicz dario-piotrowicz left a comment

Choose a reason for hiding this comment

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

second round of comments 😅

@james-elicx I put there some comments regarding checkRouteMatch and related, but I still need to double check things later and step through the function (just letting you know, the comments should still be valid regardless but I might put new ones if I notice that something isn't working as expected 🙂)

@james-elicx
Copy link
Contributor Author

james-elicx commented May 1, 2023

Note that I have just added a commit that fixes an issue where tryToFixInvalidFunctions() was unable to function correctly when fixing functions for squashed route groups.

Since we were adding just the file name to the invalidFunctions map instead of the relative path, when it tried to format the path and check that a matching one exists in the functionsMap, it was unable to find one.

Instead, we need to add the relative path to the invalidFunctions map so that it is able to check for valid squashed functions in the functionsMap properly.

This does also have the other benefit of providing users with more useful information about which routes were invalid functions when printing an error about invalid functions.

@dario-piotrowicz dario-piotrowicz force-pushed the james/routing-system-runtime branch from 15dfd98 to 198a2eb Compare May 2, 2023 16:44
Copy link
Member

@dario-piotrowicz dario-piotrowicz left a comment

Choose a reason for hiding this comment

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

Awesome stuff 🤩 🤩 🤩

Thanks so very much for this incredible effort/improvement ❤️

@dario-piotrowicz dario-piotrowicz merged commit 87e183b into cloudflare:main May 4, 2023
@james-elicx james-elicx deleted the james/routing-system-runtime branch May 4, 2023 10:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment