Next.js,
Monorepo & Vercel
Why Next?
- First JS framework with multiple site generating strategies
- CSR (Client-side rendering)
- SSR (Server-side rendering)
- SSG (Static Site Generator)
- Later... ISR (Incremental static regeneration)
- As of v13, caching strategies replaces the above
- Isomorphic, JS on client and server
- Support for serverless/edge functions
- Really a server framework with a React app on top
Pages router
-
pages/
- index.tsx
- items/
- index.tsx
- [id].tsx
- api/
- index.tsx
- [id].tsx
- components/
- home-components.tsx
App router
-
app/
- page.tsx
- home-components.tsx
- items/
- page.tsx
- [id]/
- page.tsx
- api/
- route.tsx
Data fetching and rendering
Illustrations from:
https://www.flavienbonvin.com/data-building-strategy-for-nextjs-app/
const Page = ({ data }) => {
// Render data...
}
// This gets called on every request
export async function getServerSideProps({id}) {
// Fetch data from external API
const res = await fetch(`https://.../${id}`)
const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}
export default Page
// This function gets called at build time
export async function getStaticPaths() {
const res = await fetch('https://.../posts')
const posts = await res.json()
// Get the paths we want to pre-render based on posts
const paths = posts.map((post) => ({
params: { slug: post.slug },
}))
return { paths, fallback: false }
}
export async function getStaticProps() {
const res = await fetch(‘https://.../posts’)
const posts = await res.json()
return {
props: {
posts,
},
// Next.js will attempt to regenerate the page:
// - When a request comes in
// - At most once every 10 seconds
revalidate: 10, // In seconds
}
}
ISR
v13 Cache strategy
v13 Data fetching
// app/page.tsx
async function getData() {
const res = await fetch('https://api.example.com/...');
// The return value is *not* serialized
// You can return Date, Map, Set, etc.
// Recommendation: handle errors
if (!res.ok) {
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data');
}
return res.json();
}
export default async function Page() {
const data = await getData();
if(!data) { notFound() }
return <main></main>;
}
What is a monorepo?
uib-ub-monorepo
Why monorepo?
- My motivation: splitting UI from Apps
- Sharing code, tooling and CI/CD config is easier
- Easy to add features and fixes across apps
- Updating shared packages is easy
- Incentivize the team to share code and collaborate
Coordinate projects is hard, "leke alene, sammen" makes it easier!
Plan to share functions and APIs and maybe more later. The monorepo will hopefully make refactoring and maintenance easier.
Turborepo
Experience with Lerna (Tarjes private monorepo, "Muna")
Why we choose Turborepo...
because Tarje already decided...
- Build tool for Javascript/Typescript
- Caching the outputs for quicker builds
- Keeps track of and visualizes dependencies
turbo|npm run dev
Not the most comprehensive tool,
but just what we need and plays nice with Vercel. And we can change to another monorepo build tool if necessary.
- linting setup (next vs nuxt)
- tsconfig shared between next apps
- experimenting with ignore build settings (new branches needs to build everything, following commits can/will be ignored)
- git strategies (branching, conventional commits, merging/rebasing)
- agreement on no branch stealing, git-bastards will be kicked out!
- gitlab vs github workflow
- naming patterns for branches and apps
- using github UI for merging
- github projects
Setup at DU
Link shortener
Docs
API
CHC-*
SPS-*
New Marcus frontend
Exhibitions
Termportalen
Ordbøkene
Shared Apps
ESLint
TSConfig
Tailwind-ui
Utils
Packages
Shared
- all apps built and deployed the same way, all devs know the process
- agreement on best-practice is easier
- dont have learn each app and its quirks
- DU have a forest of repos and it has become hard to understand dependencies and "connections"
- all have access to everything, not always a good thing
- branches can be protected...
- monorepo and github is great
- Not having enterprise services at UiB forces use of Github
- nice too work together on something finally, knowing someone is reading the messages...
Experiences so far...
- Nuxt remote caching not working???
- Relying on the mercy of the big players when it comes making our work easier/possible
- Turborepo have no feature for importing old repos (...we failed/decided not to make it work)
- only one build at a time, $ for concurrency
- one monorepo, many OSs can lead to issues
- nuxt image problems and turborepo?
- multiple React versions is a pain
- ...
New problems?
Shared API
Shared design systems
Add shared analytics? Ordbøkene?
DU have reorganized and have focus groups for fullstack stuff and architecture. Hopefully we will strengthen collaboration, control and planning.
Lets have a look at the repo!
Future plans
Vercel simplified
Web app
Serverless API endpoints
Vercel and NREC
NREC
FUSEKI
NREC
KIBANA
ES
SANITY
token
token
(at build time)
Frontend
Api
ITA
Postgres
NREC
API
XATA
token
Vercel - limitations (for pros)
- Max 45 minute build time
- 6000 deployments per day
- Unlimited functions (unlimited API endpoints)
- 1mill Edge function invocations
- 1000 GB/Hours serverless functions
- 60 seconds execution time (serverless)
- 30 seconds execution time (edge)
- Max 10 team members
- 60 Vercel projects per git repo (monorepo)
About 250$ worth of AWS/Cloudflare resources for free
Vercel - Limitations per month
- 1 TB bandwidth
- 400 hours build time
More the more complicated limitations: https://vercel.com/docs/concepts/limits/overview
Privacy & GDPR
Fun topic, guess someone already brought it up...
UB have started the process on creating the necessary documents explaining our choices...
For now, we have no user information.
Vercel will not be the place for all apps created by DU, partly dictated by Shrems II.
Monorepo & Vercel
By Tarje Lavik
Monorepo & Vercel
- 111