Last active
February 10, 2023 08:54
-
-
Save tricoder42/bbfcc9a946db105cf2d13b51d78b268c to your computer and use it in GitHub Desktop.
Revisions
-
tricoder42 revised this gist
May 14, 2019 . 1 changed file with 6 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -77,12 +77,18 @@ export default () => { ## Summary ✅ this can be build on top of current Next.js API ✅ centralized route config with minimal footprint in bundle ✅ global server handler is used only for development. Pages in production can be served in serverless fashion. 🚫 requires extra compile step to prepare `now.json` and `links.ts` ## Implementation details Current implementation of helpers which I use in previous examples. Not important for the concept. ### `makeRouteConfig` Little helper to create routeConfig object. -
tricoder42 revised this gist
May 14, 2019 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,7 +7,7 @@ I believe the automation is the last step to make it completely seamless. This is the only file that needs to be wrote manually. ```ts //route.config.ts const routeConfig = { @@ -52,10 +52,10 @@ declare const ArticleLink = React.ElementType<CustomLinkProps<AboutLinkParams>> ```json { "routes": [ { "src": "/about", "dest": "/about.js" }, { "src": "/article/(?<id>[^/]*)", "dest": "/article.js?id=$id" }, ] } ``` -
tricoder42 created this gist
May 14, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,143 @@ I'm using this approach to have centralized route config in Next.js. I don't have the fully automated solution. Right now I'm writing route configs and links manually to figure out if it works and what are the drawbacks. I believe the automation is the last step to make it completely seamless. ## 1. Define routes in centralized config This is the only file that needs to be wrote manually. ``` //route.config.ts const routeConfig = { // url: filename inside `pages` '/about': '/about', '/article/:id': '/article', } ``` ## 2. Links and route configs are generated Only imported Links/routes are included in bundle, everything else is stripped down using tree-shaking. Each route is transformed into `routeConfig` and custom `Link` component. `routeConfig` can be used for imperative routing (e.g. `Router.push`), while custom `Link` is used in JSX for declarative routing. ```ts // links.ts // generated from route.config.ts export const about = makeRouteConfig("/about") export const AboutLink = makeLink(about) export const article = makeRouteConfig("/article/:id", "/article") export const ArticleLink = makeLink(article) ``` As a bonus, links can be typechecked: ```ts // links.d.ts interface CustomLinkProps<Params> extends LinkProps { params: Params } interface ArticleLinkParams {} declare const ArticleLink = React.ElementType<CustomLinkProps<AboutLinkParams>> ``` ## 3. now.json is generated as well ```json { "routes": { { "src": "/about", "dest": "/about.js" }, { "src": "/article/(?<id>[^/]*)", "dest": "/article.js?id=$id" }, } } ``` ## 4. Example ```ts // pages/index.ts import { AboutLink, ArticleLink } from "../links" export default () => { <nav> <AboutLink>About</AboutLink> <ArticleLink params={{id: "42"}}>Answering the ultimate question</ArticleLink> </nav> } ``` ## Summary ✅ this can be build on top of current Next.js API ✅ centralized route config with minimal footprint in bundle ✅ global server handler is used only for development. Pages in production can be served in serverless fashion. 🚫 requires extra compile step to prepare `now.json` and `links.ts` ## Implementation details ### `makeRouteConfig` Little helper to create routeConfig object. ```ts export interface RouteConfig { path: string as: string } export function makeRouteConfig(as: string, path?: string): RouteConfig { if (process.env.NODE_ENV !== "production") { if (!as.startsWith("/")) { throw Error(`path ${as} should start with /`) } } return { as, path: path != null ? path : as } } ``` ### `makeLink` Factory to make custom `Link` with `href` and `as` attributes filled automatically based on `routeConfig` object ```ts import * as React from "react" import Link, { LinkProps } from "next/link" import { reverse, RouteConfig } from "accent/core/routes" export interface RouteLinkProps extends LinkProps { params?: { [key: string]: string } } // Create customized Link component, which fills `href` and `as` props based on routeConfig export const makeLink = (routeConfig: RouteConfig) => ({ params, children, ...linkProps }: RouteLinkProps) => { const href = { pathname: routeConfig.path, query: params } const as = params == null ? routeConfig.as : reverse(routeConfig, params) return ( <Link href={href} as={as} {...linkProps}> {children} </Link> ) } ```