Zones, Monorepo, and Modules

Nov 2021

Multi-Zones

2 (apps) become 1

one domain, many apps

const nextConfig = {
  // ...
  async rewrites() {
    return [
      {
        source: '/get-started',
        destination: SOCIAL_URL,
      },
      {
        source: '/get-started/:path*',
        destination: `${SOCIAL_URL}/:path*`,
      },
    ]
  },
}

why?

browser-cache

unified solutions

multiple teams

products, pipelines, roadmaps, ...

is based on domain

headers, redirects, cookies, storage, ...

Multi-zone rules

Main app includes all rewrites

Secondary apps set their `basePath` accordingly

All pages are unique across zones

monorepository

Architectural decisions

focus on solutions, not tooling

2 types of Monorepo

Monolithic

packages depend on each other

De-coupled

packages are independent

Monolithic

less tooling

De-coupled

more tooling

longer build

less-autonomy

autonomy

shorter build

Build one app at a time

git diff --quiet HEAD^ HEAD ./

Manage dependencies

npm

yarn

{
  "private": true,
  "workspaces": [
    "apps/*"
  ]
}

modules

Strategies

external import

URL import

dynamic

lazy load dependencies

import from external directory

import from external server

dynamic imports

import dynamic from 'next/dynamic'
const DynamicComponent = dynamic(() => import('../components/hello'))
const DynamicComponent = dynamic(() =>
  import('@components/hello').then((mod) => mod.Hello)
)
const DynamicComponentWithNoSSR = dynamic(
  () => import('@components/hello3'),
  { ssr: false }
)

dynamic imports

const DynamicLazyComponent = dynamic(
  () => import('@components/hello4'),
  { suspense: true }
)
function Home() {
  return (
    <div>
      <Suspense fallback={`loading`}>
        <DynamicLazyComponent />
      </Suspense>
    </div>
  )
}

external imports

const nextConfig = {
  // ...
  experimental: {
    externalDir: true
  }
}

tsconfig

composite: true

URL imports

const nextConfig = {
  reactStrictMode: true,
  experimental: {
    urlImports: ['https://cdn.skypack.dev/'],
  }
}
import confetti from 'https://cdn.skypack.dev/canvas-confetti'

server components

Experimental

React 18 (beta)

Next.js (x2)

Server Components

module.exports = {
  experimental: {
    concurrentFeatures: true,
    serverComponents: true,
  },
}

Server Page

import React, { Suspense } from 'react'

import Profile from '../components/profile.server'
import Content from '../components/content.client'

export default function Home() {
  return (
    <div>
      <h1>Welcome to React Server Components</h1>
      <Suspense fallback={'Loading...'}>
        <Profile />
      </Suspense>
      <Content />
    </div>
  )
}

server / client

.server.tsx

renders on the server

.client.tsx

renders on the client

.tsx

universal

examples

Made with Slides.com