"Proof of craft" project for testing React 19 and various FE
concepts in a sterile context.
- Live Demo
- Local
- All
package.jsoncommands - Technical Features
- Deployment
- Component strategy
- Components
- Components/Core
- Powered by
https://newmediapilot.github.io/react-19-bike-shop
npm run dev
npm run db // Separate window
yarn run <command>
| Script | Command | Description |
|---|---|---|
dev |
vite |
Local development |
build |
vite build |
Production build |
db |
npx json-server public/db.json |
Local mock database |
lint |
eslint my-app |
Linter |
preview |
vite preview |
Preview production build |
deploy |
bash script/deploy-preview.sh |
Deploy to preview |
gw |
node util/watch.js |
Watch git for changes |
gp |
node util/push.js |
Flatten branch && push -f |
Each loader definition is processed by loaderHandler.tsx
It manages how states are hydrated (fetch or cached)
This is the general flow of data in loaderHandler:
- IF
reduxdefined returnreduxdata - IF
reduxundefined usefetch - IF
fetch200 setlocal&& dispatchredux - IF
fetcherrors stubfixture&& continue... - IF
localdefined overwrite stub - dispatch
redux
If the last step fails we fallback to
fixture.
This is just so thatgh-pagescan function.
Since we aren't using
NextJSwe have to write a pre-fetch solution
Prefetch is handled by pf.ts
pfuses its own syntax to distribute a pre-fetch strategypf.loader("@api/list")prepares and returns a loader to invoke laterpf.prefetch("@api/list")downloads the datapf.loader("id@api/list")prepares a loader and prepares loaders for sub-items- The produced list would hydrate
id@api/listrecursively as@api/list/[id] - We can then pre-fetch specific members as
pf.prefetch("@api/list/[0-9]") pf.events("id@api/list")is anonMouseOvermixin runningpf.prefetch
// Preloads list items `onMouseOver`
<>
list.map((data, key)=> {
<NavLink key={key} {...pf.events(`@api/list/${key}`)}>View Item</NavLink>
}
</>Vite uses VITE_{VARIABLE} to define its environment by default.
.env() consumes and scans the files on compile.
-
[.env]
VITE_DBinformsloaderHandlerhow to join paths when usingfetch()
Stubbed with
http://localhost:3000fornpm run db
This will become your API root
npm run deploy
- Resets node modules via
npm run reset - Prompts to flatten the current branch to the newest tag
- Prompts to make a deployment
- Bumps version and amends commit with build message
- Adds git tag
- Pushes to
gh-pages
- Layouts are used as a general wrapper and declared in router.tsx
- Also in
router.tsxPage declarations andprefetch("@route")declarations are set - Page templates (eg. PListings.tsx) assemble from (eg. PListings/)
- Components are general purpose components such as navbar/footer
- Core Components atomic and frequently used
Each type of component adheres to state management differently
- Defines a
gridstrategy for its members - DRY composition layer for Flex, Grid, etc.
- No selectors, injections or emits
- Only hydrate via
selector - Should be simple to move around the page
- Must use
useSelector, cannot useprops - Must fill their container
w&h-[100%]
- Only hydrate via
props - Can exist anywhere, lightweight API
- Must fill their container
w&h-[100%] - Doesn't need to be visual eg.
Suspense
- Yarn
- Vite
- React 19
- React Router
- React Redux
- React Hook Form
- Workbox CLI
- Tailwind CSS
- Skeleton UI
- Hero Icons
- React Spring
- LoDash
- JSON Server
| Tool | URL | Description | Notes |
|---|---|---|---|
| Jotai | https://github.com/pmndrs/jotai | A great alternative to Redux or Zustand. | Powerful and clean implementation (pre-fetch capable) |
| Daisy UI | https://daisyui.com/ | A UI component library based on Tailwind | Similar to Radix & Skeleton |
AI was used to generate
db.json