React Day 1: Auth MFE (Vite + TS + Router + MSW) — End-to-End, Line-by-Line

React Day 1: Auth MFE (Vite + TS + Router + MSW) — End-to-End, Line-by-Line

React Day 1: Auth MFE (Vite + TS + Router + MSW) — End-to-End, Line-by-Line

Beginner-friendly, Windows/PowerShell ready. Each example is independent and copy-pasteable.

Pro tip: Use the Copy buttons on code blocks. Each block contains the full code you need for that file at that step.

Introduction

React shifts you from imperative DOM manipulation to a declarative UI mindset. In this lab we’ll build a tiny Auth-flavored MFE using Vite + TS, add navigation with React Router, and mock APIs with MSW. Every step keeps a working app so you’re never stuck.

Why this stack? Vite gives instant feedback (HMR), TypeScript adds safety, React Router models SPA navigation, and MSW lets you develop features without a real backend.

React Fundamentals — 10-minute Primer

  • Component: A function that returns UI (JSX). Small, reusable building blocks.
  • JSX: HTML-like syntax in TS/JS that compiles to React.createElement calls.
  • State: Component “memory”. Updating it triggers a re-render (e.g., useState).
  • Props: Inputs from parent → child (like function parameters).
  • Events: onClick, onChange etc. call handlers to update state.
  • Effects: useEffect for side-effects (fetching, subscriptions).
  • React vs DOM: You describe what to render; React updates the DOM efficiently.
  • Declarative vs Imperative: Declarative says “show this list”; Imperative says “find UL, append LIs”.
  • Routing: Client routes map URLs → components without full page reloads.
  • Mocking: MSW intercepts fetch so you can build confidently offline.

Prerequisites & Setup (PowerShell)

Prerequisites

  • Node.js 18+ (prefer 20)
  • Git (optional but recommended)
  • VS Code or IntelliJ IDEA (Community)
  • Basic terminal/PowerShell comfort

Quick Verify

node -v
npm -v
git --version

Workspace & First Project

# 1) Create workspace
PS C:\mycode\react> mkdir day1; cd day1

# 2) Scaffold Vite + React + TS for ex1
PS C:\mycode\react\day1> npm create vite@latest ex1-basic-template -- --template react-ts
# Tip: Press "No" for extra options if asked.

# 3) Install & run
PS C:\mycode\react\day1\ex1-basic-template> npm install
PS C:\mycode\react\day1\ex1-basic-template> npm run dev

# 4) Open http://localhost:5173

Folder Structure (for all examples in this session)

This structure spans the entire session. Each example lives in its own folder.

day1/
  ex1-basic-template/
  ex2-hello-component/
  ex3-hello-props/
  ex4-counter-state/
  ex5-compose-components/
  ex6-router-setup/
  ex7-router-links/
  ex8-msw-setup/
  ex9-users-fetch/
  ex10-users-route/

Architecture: What we are building (with diagram)

A small MFE-like React SPA with pages (Home, About, Users). The Users page fetches from /api/users, intercepted by MSW to return fake JSON. This gives you reliable, repeatable flows without a real backend.

flowchart LR
  subgraph Browser["React MFE (Vite+TS)"]
    A[Components
JSX + State + Props] R[React Router] U[Users Page] C[Counter] end subgraph MockLayer["MSW (Mock Service Worker)"] M[Mock handlers
GET /api/users, POST /api/auth/login] end A --> R R --> U A --> C U -- fetch --> M M -- respond --> U

Before you start the examples

  1. Copy the previous example into a new folder (keeps each milestone intact).
  2. Open the new folder and npm install if needed.
  3. Replace file contents with the full code blocks below (they’re complete for each file).
  4. Run npm run dev, verify, then move to the next example.
# Pattern for each step (Windows PowerShell)
PS C:\mycode\react\day1> robocopy <prev-example> <next-example> /e
PS C:\mycode\react\day1\<next-example>> npm install
PS C:\mycode\react\day1\<next-example>> npm run dev
Heads up: If Vite can’t find files after copying, stop and restart the dev server.

10 Examples (ex1 → ex10)

ex1 — Basic Vite + TS Template

Goal: Create a minimal React+TS app with Vite as the baseline.

Setup (PowerShell)

PS C:\mycode\react\day1> npm create vite@latest ex1-basic-template -- --template react-ts
PS C:\mycode\react\day1\ex1-basic-template> npm install
PS C:\mycode\react\day1\ex1-basic-template> npm run dev

Concept & Flow

Vite scaffolds a fast dev server, TypeScript config, and a simple React entry. We’ll use this as our seed.

Files (Full code — copy/paste)

src/main.tsx

// main.tsx — React entry point
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>
)

src/App.tsx

// App.tsx — minimal component returning UI
export default function App() {
  return (
    <div style={{ padding: 24 }}>
      <h1>Hello Vite + React + TS</h1>
      <p className="muted">Baseline template</p>
    </div>
  )
}

Key insights

  • Key files: index.html, src/main.tsx, src/App.tsx
  • Why TS + Vite: speed + safety while learning
  • Quick test: Edit the <h1> and see HMR

Exercises + L1 BDD

  • Exercise: Add a styled subtitle.
  • L1 BDD: Script asserts dev server responds on 5173 (simple curl).

ex2 — Hello Component

Goal: Create and render a reusable component.

Setup (PowerShell)

PS C:\mycode\react\day1> robocopy ex1-basic-template ex2-hello-component /e
PS C:\mycode\react\day1\ex2-hello-component> npm install
PS C:\mycode\react\day1\ex2-hello-component> npm run dev

Concept & Flow

Components are functions returning JSX. We add <Hello/> and render it from App.

Files (Full code — copy/paste)

src/Hello.tsx

// Hello.tsx — simplest possible component
export default function Hello() {
  return <h2>Hello React</h2>
}

src/App.tsx

import Hello from "./Hello"

export default function App() {
  return (
    <div style={{ padding: 24 }}>
      <h1>ex2 — Hello Component</h1>
      <Hello />
    </div>
  )
}

Key insights

  • Components = functions returning JSX
  • Composition = placing components inside others

Exercises + L1 BDD

  • Exercise: Wrap <Hello/> in a card.
  • L1 BDD: Assert “Hello React” in HTML.

ex3 — Props

Goal: Pass data from parent to child.

Setup (PowerShell)

PS C:\mycode\react\day1> robocopy ex2-hello-component ex3-hello-props /e
PS C:\mycode\react\day1\ex3-hello-props> npm install
PS C:\mycode\react\day1\ex3-hello-props> npm run dev

Concept & Flow

Props are inputs to a component. We pass name to <Hello/>.

Files (Full code — copy/paste)

src/Hello.tsx

type HelloProps = { name: string }

export default function Hello({ name }: HelloProps) {
  return <h2>Hello {name}</h2>
}

src/App.tsx

import Hello from "./Hello"

export default function App() {
  return (
    <div style={{ padding: 24 }}>
      <h1>ex3 — Props</h1>
      <Hello name="Ganesh" />
    </div>
  )
}

Key insights

  • Props make components reusable with different data
  • Type props with TS for safety

Exercises + L1 BDD

  • Exercise: Add a greeting prop with default.
  • L1 BDD: Table-driven names → greetings.

ex4 — State (useState)

Goal: Manage changing data in a component.

Setup (PowerShell)

PS C:\mycode\react\day1> robocopy ex3-hello-props ex4-counter-state /e
PS C:\mycode\react\day1\ex4-counter-state> npm install
PS C:\mycode\react\day1\ex4-counter-state> npm run dev

Concept & Flow

State is component memory. We build a counter with useState.

Files (Full code — copy/paste)

src/Counter.tsx

import { useState } from "react"

export default function Counter() {
  const [count, setCount] = useState(0)
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(c => c + 1)}>+1</button>
    </div>
  )
}

src/App.tsx

import Counter from "./Counter"

export default function App() {
  return (
    <div style={{ padding: 24 }}>
      <h1>ex4 — State</h1>
      <Counter />
    </div>
  )
}

Key insights

  • Event handlers update state → re-render
  • Functional update avoids stale state

Exercises + L1 BDD

  • Exercise: Add “-1” and “Reset”.
  • L1 BDD: Steps click and assert text.

ex5 — Compose Components

Goal: Use multiple components together.

Setup (PowerShell)

PS C:\mycode\react\day1> robocopy ex4-counter-state ex5-compose-components /e
PS C:\mycode\react\day1\ex5-compose-components> npm install
PS C:\mycode\react\day1\ex5-compose-components> npm run dev

Concept & Flow

Composition builds bigger UIs by combining smaller ones.

Files (Full code — copy/paste)

src/Hello.tsx

export default function Hello({ name = "React" }: { name?: string }) {
  return <h2>Hello {name}</h2>
}

src/App.tsx

import Hello from "./Hello"
import Counter from "./Counter"

export default function App() {
  return (
    <div style={{ padding: 24 }}>
      <h1>ex5 — Composition</h1>
      <Hello name="Ganesh" />
      <Counter />
    </div>
  )
}

Key insights

  • Compose to keep each piece focused
  • Props let repeated pieces vary

Exercises + L1 BDD

  • Exercise: Add a second Counter with its own label.
  • L1 BDD: Two counters update independently.

ex6 — Router Setup

Goal: Switch views by URL using React Router.

Setup (PowerShell)

PS C:\mycode\react\day1> robocopy ex5-compose-components ex6-router-setup /e
PS C:\mycode\react\day1\ex6-router-setup> npm install react-router-dom
PS C:\mycode\react\day1\ex6-router-setup> npm run dev

Concept & Flow

Router picks which component to show based on the URL.

Files (Full code — copy/paste)

src/App.tsx

import { BrowserRouter, Routes, Route } from "react-router-dom"

function Home() { return <h2>Home</h2> }
function About() { return <h2>About</h2> }

export default function App() {
  return (
    <BrowserRouter>
      <div style={{ padding: 24 }}>
        <h1>ex6 — Router</h1>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </div>
    </BrowserRouter>
  )
}

Key insights

  • <BrowserRouter> wraps once
  • Each Route maps path → component

Exercises + L1 BDD

  • Exercise: Add /counter route with <Counter/>.
  • L1 BDD: Navigate and assert headings.

ex7 — Navigation Links

Goal: Navigate declaratively with <Link>.

Setup (PowerShell)

PS C:\mycode\react\day1> robocopy ex6-router-setup ex7-router-links /e
PS C:\mycode\react\day1\ex7-router-links> npm install
PS C:\mycode\react\day1\ex7-router-links> npm run dev

Concept & Flow

<Link> changes URL without full page reload.

Files (Full code — copy/paste)

src/App.tsx

import { BrowserRouter, Routes, Route, Link } from "react-router-dom"

function Home() { return <h2>Home</h2> }
function About() { return <h2>About</h2> }

export default function App() {
  return (
    <BrowserRouter>
      <div style={{ padding: 24 }}>
        <h1>ex7 — Links</h1>
        <nav style={{ display:"flex", gap:12 }}>
          <Link to="/">Home</Link>
          <Link to="/about">About</Link>
        </nav>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </div>
    </BrowserRouter>
  )
}

Key insights

  • Declarative nav via <Link>
  • No full reload; state can persist

Exercises + L1 BDD

  • Exercise: Add active link style.
  • L1 BDD: Click Home→About and assert headings.

ex8 — MSW Setup (Mock API)

Goal: Intercept fetch and return fake data (no real server).

Setup (PowerShell)

PS C:\mycode\react\day1> robocopy ex7-router-links ex8-msw-setup /e
PS C:\mycode\react\day1\ex8-msw-setup> npm install msw --save-dev
PS C:\mycode\react\day1\ex8-msw-setup> npm run dev

Concept & Flow

MSW registers a service worker in dev; our handlers return JSON for paths like /api/users.

Files (Full code — copy/paste)

src/mocks/handlers.ts

import { http, HttpResponse } from "msw"

export const handlers = [
  http.get("/api/users", () => {
    return HttpResponse.json([
      { id: 1, name: "Ada" },
      { id: 2, name: "Linus" }
    ])
  }),
  http.post("/api/auth/login", async ({ request }) => {
    const body = await request.json()
    if (body.username && body.password) {
      return HttpResponse.json({ token: "fake-jwt", user: { name: body.username } })
    }
    return HttpResponse.json({ error: "invalid" }, { status: 400 })
  }),
]

src/mocks/browser.ts

import { setupWorker } from "msw/browser"
import { handlers } from "./handlers"

export const worker = setupWorker(...handlers)

src/main.tsx (start worker in dev)

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'

async function enableMocking() {
  if (import.meta.env.DEV) {
    const { worker } = await import('./mocks/browser')
    await worker.start()
  }
}
enableMocking()

createRoot(document.getElementById('root')!).render(
  <StrictMode><App /></StrictMode>
)

Key insights

  • Place handlers under src/mocks/
  • Call worker.start() before app renders (dev)

Exercises + L1 BDD

  • Exercise: Add GET /api/profile handler.
  • L1 BDD: Step hits mocked endpoint and asserts JSON shape.

ex9 — Fetch Users Component

Goal: Load users from /api/users (intercepted by MSW) and display.

Setup (PowerShell)

PS C:\mycode\react\day1> robocopy ex8-msw-setup ex9-users-fetch /e
PS C:\mycode\react\day1\ex9-users-fetch> npm install
PS C:\mycode\react\day1\ex9-users-fetch> npm run dev

Concept & Flow

useEffect triggers fetch on mount; state holds results; MSW fulfills the request.

Files (Full code — copy/paste)

src/Users.tsx

import { useEffect, useState } from "react"

type User = { id: number; name: string }

export default function Users() {
  const [users, setUsers] = useState<User[]>([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch("/api/users")
      .then(r => r.json())
      .then(data => setUsers(data))
      .finally(() => setLoading(false))
  }, [])

  if (loading) return <p>Loading...</p>
  return (
    <ul>
      {users.map(u => <li key={u.id}>{u.name}</li>)}
    </ul>
  )
}

src/App.tsx

import Users from "./Users"

export default function App() {
  return (
    <div style={{ padding: 24 }}>
      <h1>ex9 — Users</h1>
      <Users />
    </div>
  )
}

Key insights

  • useEffect(..., []) runs once on mount
  • MSW supplies the data → deterministic dev

Exercises + L1 BDD

  • Exercise: Add a skeleton for ~800ms.
  • L1 BDD: Names appear in order (Ada, Linus).

ex10 — Integrate Users with Router

Goal: Add /users route and wire menu → page → fetch (MSW).

Setup (PowerShell)

PS C:\mycode\react\day1> robocopy ex9-users-fetch ex10-users-route /e
PS C:\mycode\react\day1\ex10-users-route> npm install
PS C:\mycode\react\day1\ex10-users-route> npm run dev

Concept & Flow

Full mini-app: Home/About/Users; Users lists data from mocked API.

Files (Full code — copy/paste)

src/App.tsx

import { BrowserRouter, Routes, Route, Link } from "react-router-dom"
import Users from "./Users"

function Home() { return <h2>Home</h2> }
function About() { return <h2>About</h2> }

export default function App() {
  return (
    <BrowserRouter>
      <div style={{ padding: 24 }}>
        <h1>ex10 — Users Route</h1>
        <nav style={{ display:"flex", gap:12 }}>
          <Link to="/">Home</Link>
          <Link to="/about">About</Link>
          <Link to="/users">Users</Link>
        </nav>

        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
          <Route path="/users" element={<Users />} />
        </Routes>
      </div>
    </BrowserRouter>
  )
}

Key insights

  • Router ties pages together
  • MSW keeps dev productive and offline

Exercises + L1 BDD

  • Exercise: Add detail page /users/:id with handler GET /api/users/:id.
  • L1 BDD: Navigate list → detail and assert JSON fields.

Comments

Popular posts from this blog

Day 1: React Fundamentals — Build an Auth MFE

Building Scalable AWS VPC Infrastructure with Terraform Modules for SaaS Applications