next-route-typesafe v0.0.10
next-route-typesafe
next/link, next/router를 빠르게 입력하기위해 타입을 추론해주는 library 이며 pages폴더를 탐색하여 url path를 추출합니다. 상황에 맞게 type safe 하게 사용 할 수 있고 autocomplete을 위한 타입 추론용으로 사용할 수 있습니다.
Install
yarn add next-route-typesafeUsage
- root에
route.config.js추가const config = { mode: 'single', strict: false, }; generate-routes-type실행
generate-routes-type를 실행하고나면 root에 next/router, next/link의 type 재정의 파일(next-routes-overriding.d.ts)과 page 하위에서 추출한 전체 url path를 저장하고 있는 type 정의 파일(routes.d.ts)이 하나씩 추가됩니다.
위 사진에서 route.d.ts가 page 하위에서 추출한 전체 url path type이고, next-router-overriding.d.ts가 next/router, next/link의 type 재정의 파일입니다
route.config.js의
mode가 monorepo일때는 달라집니다.
Config(route.config.js) option
| Name | Description | Type |
|---|---|---|
basePath | mode가 monorepo일때 사용하며 추출된 url path들의 key값을 제거할때 사용합니다 | string(optional) |
ignorePath | pages folder가 있지만 link로 추출되길 원하지 않는 directory가 있을때 사용합니다. | string[](optional) |
strict | link로 추출된 타입 이외에 string도 허용할지 여부입니다.(default:false) | boolean(optional) |
mode | project의 구조형태 입니다. | 'monorepo' \| 'single'(required) |
basePath
mode가 monorepon일때 link의 타입이 {[serivceName]: Links} 형태로 추출되는데 여기서 serviceName의 특정 부분을 제거할때 사용합니다.
basePath: undefined'apps/serviceA': | '/a' | '/b' | '/a/[query]' 'apps/serviceB': '/' | '/post/[postNo]' | '/search'; 'apps/serviceC': | '/demo' | '/' | '/submit';basePath: "apps"'serviceA': |'/a' |'/b' |'/a/[query]' 'serviceB':'/' |'/post/[postNo]' |'/search'; 'serviceC': |'/demo' |'/' |'/submit';
strict
link type으로 string을 허용할지 여부를 결정하는 option 입니다. (autocomplete를 위한 타입 추론용으로 사용할 수 있습니다.)
strict:trueLink component href prop에 오로지 추출된url path만 전달할 수 있습니다.<Link href="string" />형태로 사용시path param이 없는 path만 전달할 수 있습니다<Link href="/a/b" />(✅ correct)<Link href="/a/[b]" />(❌ error)
<Link href={{pathname:"string", query:{...}}} />형태로 사용시pathname에path param여부에 따라query값의 필수 여부가 결정되고,path param이외의 값을query에 전달할시 모두query string으로 바뀝니다.<Link href={{pathname:"/a/b"}} />(✅ correct)<Link href={{pathname:"/a/b", query:{qs:22} }} />(✅ correct)<Link href={{pathname:"/a/[b], query:{b:"required", token:"it is query string" }}} />(✅ correct)<Link href={{pathname:"/a/[b]}} />(❌ errorquery에 b값을 필수로 전달 해줘야 합니다)
strict:falseLink component href prop의 값으로 추출된url path과string type모두를 전달할 수 있습니다<Link href={{pathname:"/a/b"}} />(✅ correct)<Link href={{pathname:"/a/[b]"}} />(✅ correct)<Link href="/a/b" />(✅ correct)<Link href="/a/[b]" />(✅ correct)<Link href={44} />(❌ error)
next/link,next/router,generateLink api에서도 똑같은rule이 적용됩니다.
mode
monorepo일때와 single일때 생성되는 파일의 위치가 달라집니다.
monorepo
프로젝트 구조가 다음과 같을때
apps
- serviveA
- ...
- pages
- a
- c
- [userId]
- b
- [token]
- ...
- package.json
- serviceB
- ...
- pages
- ....
- package.json
package.json
...타입은 다음과같이 만들어집니다.
serviceA:
|'/'
|'/a'
|'/a/c'
|'/a/c/[userId]'
|'/b/[token]',
serviceB:
|'/'
| ...type이 만들어 지는 위치는 root에 전체 url path type(route.d.ts)파일 하나가 추가되고, ignore에 포함되지않은 Next.js의 각 root에 next/link, next/router의 type을 overriding하는 타입파일(routes-overriding.d.ts)하나가 추가됩니다
```ts
apps
- serviceA
- ...
- package.json
- `routes-overriding.d.ts(+)`
- serviceB
- ...
- package.json
- `routes-overriding.d.ts(+)`
package.json
`routes.d.ts(+)`
```single
프로젝트 구조가 다음과 같을때
src
- pages
- a
- c
- [userId]
- b
- [token]
- ...
package.json
...타입은 다음과같이 만들어집니다.
type LinkType =
| '/'
| '/a'
| '/a/c'
| '/a/c/[userId]'
| '/b/[token]'
| ...root에 url path type(routes.d.ts)과 next/link, next/router의 type을 overriding하는 타입파일(next-router-overriding.d.t)들이 추가됩니다.
```ts
- ...
- package.json
- `routes.d.ts(+)`
- `next-router-overriding.d.ts(+)`
```API
link를 만들어주는 함수이며 generate함수 모두 parameter로 url path가 기본적으로 추론이되고 strict 값에 따라 type이 달라집니다
isStrict:false- 추론된 값 이외의
string type도 전달할 수 있습니다
- 추론된 값 이외의
isStrict:true- 추론된 값만 사용이 가능하며
path param([id]의 형태])가 있을시에는{pathname:string, query:{}}의 형태로만 사용해야 합니다
- 추론된 값만 사용이 가능하며
| Name | Description |
|---|---|
generateServiceLink | mode가 monorepo일때 사용하며 추출된 다른 Next.js package의 link를 만들때 사용합니다 |
generateInternalLink | 현재위치의 package에 해당하는 link를 만들때 사용합니다. |
generateServiceLink
mode가 monorepo일때 사용하며 추출된 다른 Next.js package의 link를 만들때 사용합니다
Usage
import {generateServiceLink} from 'next-route-typesafe';
const generateLink = generateServiceLink({serviceA: "https://www.serviceA.com", ...})
function ReactElement() {
return (
// generateLink("serviceA", "/a") = "https://www.serviceA.com/a/test?qa=55"
<Link href={generateLink("serviceA", {pathname:"/a/[id]", query:{id:"test", qs:55}})}>
<div>move</div>
</div>
);
}API
generateServiceLink(originMapping): (link: string | {pathname:string, query?:{}} ) => string- parameters
originMapping- 전체 package들의 origin 값 입니다. (ex, {serviceA:"https://www.serviceA.com", serviceB:"https..." ...})
- return
(link: string | {pathname:string, query?:{}} ) => stringlink- 추출된
url path이 추론되며{pathname:string, query?:{}}형태로도 사용할수 있습니다(<Link/>의 href,router.push()의parameter type과 동일합니다)
- 추출된
generateInternalLink
현재위치의 package에 해당하는 link를 만들때 사용합니다.
Usage
import {generateInternalLink} from 'next-route-typesafe';
function ReactElement() {
return (
// generateInternalLink({pathname:"/a/[id]", query: {id:22}}) = "/a/22
<Link href={generateInternalLink({pathname:"/a/[id]", query: {id:22}})}>
<a>move</a>
</div>
);
}API
generateInternalLink(link: string | {pathname:string, query?:{}} ): string- parameters
link- 추출된
url path가 추론되며{pathname:string, query?:{}}형태로도 사용할수 있습니다(<Link/>의 href,router.push()의parameter type과 동일합니다)
- 추출된