next-routes
next-routes copied to clipboard
Support now 2.0
Now 2.0 has been released: https://zeit.co/blog/now-2
Specifically, the next.js docs encourage not using a file that specifies all the routes:
It might be tempting to use the now/node-server Builder, as seen in the example above, to quickly deploy your app as a Lambda without any code changes.
Keep in mind, however, that one of the benefits of the serverless model, as the name implies, is not only not to manage servers, but also not to think in terms of the server abstraction.
In other words, if you are writing new Server() (in whatever language you prefer), you might be missing out on the granularity benefits of serverless.
For example, many people have throughout the years provided examples on how to deploy express, a Node.js framework, to AWS Lambda:
app.get('/', myFunction) app.get('/2nd-route', myOtherFunction) app.get('/third-route', myThirdFunction)
With Now, you can split this into three discrete underlying Lambdas instead, which allows for:
- Reduced surface of error
- Faster cold boot times thanks to smaller bundle sizes ("code splitting" for the backend)
- Per-route scalability
- Faster build and, therefore, total deployment times
As seen above, the code changes required to leave servers behind altogether are very minimal, while the benefits very significant.
- https://zeit.co/docs/v2/platform/upgrade-to-2-0#don-t-rush-to-upgrade/serverless-is-better-without-servers
The alternative proposed is to use a now.json#routes
config: https://zeit.co/docs/v2/deployments/configuration#routes
{
"builds": [
{ "src": "*.html", "use": "@now/static" },
{ "src": "*.js", "use": "@now/node" },
],
"routes": [
{ "src": "/custom-page", "headers": {"cache-control": "s-maxage=1000"}, "dest": "index.html" },
{ "src": "/api", "dest": "my-api.js" },
{ "src": "/users/(?<id>[^/]", "dest": "users-api.js?id=$id" },
{ "src": "/.*", "dest": "https://my-old-site.com"},
{ "src": "/legacy", "status": 404},
{ "src": "/redirect", "status": 301, "headers": { "Location": "https://zeit.co/" } }
]
}
However, this loses the ability to do reverse-route lookups which I love from next-routes
.
Is there a way to interop the two concepts and reap benefits of both?
We just manage to build it for Now 2.0 as a POC. Sharing the solution here and if no one beats us to it we will try to do a PR with a better solution asap.
const fs = require("fs");
const nextRoutes = require("../routes");
const nowConfig = require("../now.json");
if(!nowConfig.routes) {
nowConfig.routes = []
}
nextRoutes.routes.forEach((route) => {
if (nowConfig.routes.filter(e => e.src === route.regex.source).length === 0) {
nowConfig.routes.push({
src: route.regex.source,
dest: route.page
})
}
})
fs.writeFile('now.json', JSON.stringify(nowConfig, false, 2), (err) => {
if (err) {
console.error(err);
return;
};
console.log("now.json has been updated");
});
The idea is simply to fetch routing and update now.json
with it. That would keep it backwards compatible with link generation using named routes in this package.
We wrote a simple CLI tool for this based on the above POC. https://www.npmjs.com/package/next-routes-now
I created my own routes middleware to use Now 2.0 json routing format here