From dd990b7e5a715e4249c6da587223ae63049d564e Mon Sep 17 00:00:00 2001 From: kabeier Date: Thu, 26 Feb 2026 17:51:56 -0500 Subject: [PATCH 1/2] docs: align stack docs and docker setup with Next.js --- Dockerfile | 22 ++++++---- Makefile | 6 +-- README.md | 83 +++++++++++++++++-------------------- docker-compose.override.yml | 5 +-- docker-compose.yml | 2 +- 5 files changed, 56 insertions(+), 62 deletions(-) diff --git a/Dockerfile b/Dockerfile index 95c4b08..38857e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,3 @@ -# ----- build stage ----- FROM node:20-alpine AS build WORKDIR /app @@ -8,13 +7,18 @@ RUN npm ci COPY . . RUN npm run build -# ----- runtime stage ----- -FROM nginx:1.27-alpine -COPY --from=build /app/dist /usr/share/nginx/html +FROM node:20-alpine AS runtime +WORKDIR /app +ENV NODE_ENV=production + +COPY package*.json ./ +RUN npm ci --omit=dev -# SPA routing support -RUN rm /etc/nginx/conf.d/default.conf -COPY nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=build /app/.next ./.next +COPY --from=build /app/pages ./pages +COPY --from=build /app/src ./src +COPY --from=build /app/next-env.d.ts ./next-env.d.ts +COPY --from=build /app/tsconfig.json ./tsconfig.json -EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] +EXPOSE 4173 +CMD ["npm", "run", "start"] diff --git a/Makefile b/Makefile index 4b1ce4b..3462167 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,8 @@ dev: build: npm run build -preview: - npm run preview +start: + npm run start lint: npm run lint @@ -34,4 +34,4 @@ docker-down: docker compose down docker-e2e: - docker compose -f docker-compose.e2e.yml run --rm e2e \ No newline at end of file + docker compose -f docker-compose.e2e.yml run --rm e2e diff --git a/README.md b/README.md index bf4759f..e6ec945 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,23 @@ # ProjectSparks -TypeScript + React app built with Webpack. +TypeScript + React application built with **Next.js**. ## Tech Stack +- Next.js 15 - React 18 - TypeScript -- Webpack 5 -- Babel (TS/React presets) -- Docker + Docker Compose (dev + production-style builds) - ESLint + Prettier -- Vitest +- Vitest + Testing Library - Playwright + start-server-and-test -- Husky +- Docker + Docker Compose +- Husky + lint-staged ## Getting Started ### Requirements -- Node (see `.nvmrc`) +- Node.js 20+ - npm ### Install @@ -27,7 +26,7 @@ TypeScript + React app built with Webpack. npm ci ``` -### Run Dev Server +### Run the Development Server ```bash npm run dev @@ -35,7 +34,7 @@ npm run dev Open: -- [http://localhost:5173](http://localhost:5173) +- [http://localhost:3000](http://localhost:3000) ### Typecheck @@ -69,55 +68,50 @@ npm run e2e:ci npm run build ``` -Output is written to dist/ +Next.js build output is written to `.next/`. -### Preview Production Build Locally +### Run Production Server Locally ```bash -npm run preview +npm run start ``` Open: -- [http://localhost:5173](http://localhost:5173) - -## Analyze bundle -```bash -npm run analyze -``` +- [http://localhost:4173](http://localhost:4173) ## Docker -### Production (Docker Compose) +### Development (Docker Compose) -Run the production nginx container (no dev server): +Runs the Next.js development server in a container with your local source mounted for live edits. ```bash -docker compose -f docker-compose.yml up --build +docker compose up --build ``` Open: -- [http://localhost:5173](http://localhost:5173) - -### Dev (Docker Compose) +- [http://localhost:4173](http://localhost:4173) -This runs the webpack dev server inside a container and mounts your local source code into it. +Stop: ```bash -docker compose up --build +docker compose down ``` -Open: +### Production (Docker Compose) -- [http://localhost:5173](http://localhost:5173) - -Stop: +Runs a production Next.js build with `next start`. ```bash -docker compose down +docker compose -f docker-compose.yml up --build ``` +Open: + +- [http://localhost:4173](http://localhost:4173) + ### Production-style Container Build the image: @@ -129,12 +123,12 @@ docker build -t projectsparks-web . Run it: ```bash -docker run --rm -p 8080:80 projectsparks-web +docker run --rm -p 4173:4173 projectsparks-web ``` Open: -- [http://localhost:8080](http://localhost:8080) +- [http://localhost:4173](http://localhost:4173) ## Git Hooks (Husky) @@ -151,21 +145,19 @@ npm ci ## Project Layout -- `src/` — React + TypeScript application source -- `public/` — HTML template and static assets -- `dist/` — production build output (generated) +- `pages/` — Next.js Pages Router routes +- `src/` — shared React/TypeScript components, styles, and test setup +- `.next/` — Next.js build output (generated) - `e2e/` — Playwright end-to-end tests -- `webpack.config.cjs` — Webpack configuration (dev + prod) - `tsconfig.json` — TypeScript compiler settings - `vitest.config.ts` — Vitest configuration - `playwright.config.ts` — Playwright configuration -- `Dockerfile` — multi-stage build (Node build → Nginx runtime) -- `nginx.conf` — Nginx SPA routing config -- `docker-compose.yml` — production-style container (Nginx runtime) -- `docker-compose.override.yml` — dev overrides (bind mounts + dev server) -- `docker-compose.e2e.yml` - Playwright end-to-end tests inside docker container +- `Dockerfile` — production Next.js container build +- `docker-compose.yml` — production container config +- `docker-compose.override.yml` — development container overrides +- `docker-compose.e2e.yml` — Playwright tests inside Docker - `.github/` — CI workflow + Dependabot configuration - `commitlint.config.cjs` — commit message lint rules @@ -173,13 +165,12 @@ npm ci - `package.json` / `package-lock.json` — dependencies + scripts - `node_modules/` — installed dependencies (not committed) -- `Makefile` - convenience shortcuts for common tasks +- `Makefile` — convenience shortcuts for common tasks ### Notes -- `dist/` is generated output and should not be committed. +- `.next/` is generated output and should not be committed. - `package-lock.json` must be generated by npm commands (`npm install` / `npm ci`) and never hand-edited. -- CI validates lockfile reproducibility after install; any unintended lockfile changes should fail the build. +- CI validates lockfile reproducibility after install; unintended lockfile changes should fail the build. - CI runs `npm ci`, `npm run typecheck`, and `npm run build` on every PR/push. - Git hooks are managed by Husky and installed automatically on `npm ci`. - diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 39074e6..3ffff54 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -3,12 +3,11 @@ services: build: context: . target: build - command: npm run dev + command: npm run dev -- -p 4173 ports: - - "4173:8080" + - "4173:4173" volumes: - .:/app - /app/node_modules environment: - - WATCHPACK_POLLING=true - CHOKIDAR_USEPOLLING=true diff --git a/docker-compose.yml b/docker-compose.yml index 5c806fe..17ed7d1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,4 +3,4 @@ services: image: projectsparks-web build: . ports: - - "8080:80" + - "4173:4173" From 081f77c06c7b05933618501b2da7b33c4bb8cc80 Mon Sep 17 00:00:00 2001 From: kabeier Date: Thu, 26 Feb 2026 17:59:42 -0500 Subject: [PATCH 2/2] chore: migrate project toolchain docs to SWC --- .babelrc | 7 ------ .eslintrc.cjs | 2 +- .github/workflows/ci.yml | 4 ++-- Dockerfile | 3 +++ Makefile | 7 ++++++ README.md | 49 ++++++++++++++++------------------------ pages/about.tsx | 2 +- pages/projects.tsx | 2 +- 8 files changed, 35 insertions(+), 41 deletions(-) delete mode 100644 .babelrc diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 23629c0..0000000 --- a/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - ["@babel/preset-env"], - ["@babel/preset-react", { "runtime": "automatic" }], - ["@babel/preset-typescript"] - ] -} diff --git a/.eslintrc.cjs b/.eslintrc.cjs index e79a6bc..1350274 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,6 +1,6 @@ module.exports = { root: true, - ignorePatterns: ["dist/", "node_modules/", "*.config.js", "webpack.config.js"], + ignorePatterns: ["dist/", "node_modules/", "*.config.js"], env: { browser: true, diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e8071c..6d2fa29 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,10 +22,10 @@ jobs: - name: Install dependencies run: npm ci --include=dev - - name: Verify core framework dependencies + - name: Verify Next.js + SWC setup run: | node -e "const pkgs=['next','react','react-dom']; for (const pkg of pkgs){const path=require.resolve(pkg + '/package.json'); const version=require(path).version; console.log(pkg + '@' + version)}" - test -f node_modules/next/dist/bin/next + test ! -f .babelrc - name: Lockfile reproducibility check run: git diff --exit-code package-lock.json diff --git a/Dockerfile b/Dockerfile index 38857e8..dfc2687 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,18 @@ FROM node:20-alpine AS build WORKDIR /app +ENV NEXT_TELEMETRY_DISABLED=1 COPY package*.json ./ RUN npm ci COPY . . +# Next.js compiles with SWC by default when no Babel config is present RUN npm run build FROM node:20-alpine AS runtime WORKDIR /app ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 COPY package*.json ./ RUN npm ci --omit=dev diff --git a/Makefile b/Makefile index 3462167..807ffd6 100644 --- a/Makefile +++ b/Makefile @@ -35,3 +35,10 @@ docker-down: docker-e2e: docker compose -f docker-compose.e2e.yml run --rm e2e + +ci: + npm ci + npm run typecheck + npm run lint + npm run test:run + npm run build diff --git a/README.md b/README.md index e6ec945..7beba09 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,19 @@ # ProjectSparks -TypeScript + React application built with **Next.js**. +TypeScript + React application built with **Next.js (SWC compiler)**. ## Tech Stack -- Next.js 15 +- Next.js 15 (Pages Router) - React 18 - TypeScript +- SWC (Next.js built-in compiler/minifier; no Babel pipeline) - ESLint + Prettier - Vitest + Testing Library - Playwright + start-server-and-test - Docker + Docker Compose - Husky + lint-staged +- GitHub Actions CI ## Getting Started @@ -84,7 +86,7 @@ Open: ### Development (Docker Compose) -Runs the Next.js development server in a container with your local source mounted for live edits. +Runs `next dev` in a container with your local source mounted for live edits. ```bash docker compose up --build @@ -94,15 +96,9 @@ Open: - [http://localhost:4173](http://localhost:4173) -Stop: - -```bash -docker compose down -``` - ### Production (Docker Compose) -Runs a production Next.js build with `next start`. +Builds and runs `next start` on port `4173`. ```bash docker compose -f docker-compose.yml up --build @@ -130,18 +126,18 @@ Open: - [http://localhost:4173](http://localhost:4173) -## Git Hooks (Husky) +## CI -This repo uses Husky + lint-staged to enforce formatting and linting on commit. +GitHub Actions runs: -- Prettier runs on staged files -- ESLint runs on staged JS/TS files +- `npm ci` +- `npm run typecheck` +- `npm run lint` +- `npm run test:run` +- `npm run build` +- `npm run e2e:ci` -If hooks don’t run after cloning, make sure you’ve installed dependencies: - -```bash -npm ci -``` +CI also verifies there is no project Babel configuration so Next.js compiles with SWC. ## Project Layout @@ -150,27 +146,22 @@ npm ci - `.next/` — Next.js build output (generated) - `e2e/` — Playwright end-to-end tests -- `tsconfig.json` — TypeScript compiler settings -- `vitest.config.ts` — Vitest configuration -- `playwright.config.ts` — Playwright configuration - +- `.github/workflows/ci.yml` — CI pipeline - `Dockerfile` — production Next.js container build - `docker-compose.yml` — production container config - `docker-compose.override.yml` — development container overrides - `docker-compose.e2e.yml` — Playwright tests inside Docker -- `.github/` — CI workflow + Dependabot configuration +- `tsconfig.json` — TypeScript compiler settings +- `vitest.config.ts` — Vitest configuration +- `playwright.config.ts` — Playwright configuration - `commitlint.config.cjs` — commit message lint rules - `CHANGELOG.md` — release notes / project history - - `package.json` / `package-lock.json` — dependencies + scripts -- `node_modules/` — installed dependencies (not committed) - `Makefile` — convenience shortcuts for common tasks ### Notes - `.next/` is generated output and should not be committed. +- This repo intentionally does **not** include a Babel config file, so Next.js uses SWC end-to-end. - `package-lock.json` must be generated by npm commands (`npm install` / `npm ci`) and never hand-edited. -- CI validates lockfile reproducibility after install; unintended lockfile changes should fail the build. -- CI runs `npm ci`, `npm run typecheck`, and `npm run build` on every PR/push. -- Git hooks are managed by Husky and installed automatically on `npm ci`. diff --git a/pages/about.tsx b/pages/about.tsx index feface5..1a9afe0 100644 --- a/pages/about.tsx +++ b/pages/about.tsx @@ -2,7 +2,7 @@ export default function AboutPage() { return (

About

-

This repo is intentionally “from scratch” (Webpack, Docker, CI) to show the full pipeline.

+

This repo is intentionally “from scratch” (Next.js + SWC, Docker, CI) to show the full pipeline.

); } diff --git a/pages/projects.tsx b/pages/projects.tsx index 2015c39..f304d38 100644 --- a/pages/projects.tsx +++ b/pages/projects.tsx @@ -9,7 +9,7 @@ const PROJECTS: Project[] = [ { id: "starter", title: "Starter Template", - description: "This repo itself: Webpack + TS + Docker + CI + tests.", + description: "This repo itself: Next.js + SWC + TS + Docker + CI + tests.", }, ];