Skip to content
Topic 13 of 13
Theory

A real project: Vite, modules and the final shop

From the site to your own computer

Until now React ran right on the course page: the library was connected, and JSX was turned into JavaScript behind the scenes. Real applications are made differently: a project is a folder of files on your computer, where each component lives in its own file, and a special tool — a bundler — assembles them into a finished site. This topic is about how that works and how to start your own project.

Node.js and npm

The bundler and other developer tools are written in JavaScript and run in Node.js — JavaScript outside the browser. Together with Node.js you get npm — a package manager: it downloads libraries (React, React Router and thousands of others) from the shared catalog npmjs.com.

Install Node.js from nodejs.org (the LTS version) and check in the terminal:

node --version
npm --version

Creating a Vite project

Vite is a fast and the most popular bundler for React projects. Create a project with one command:

npm create vite@latest my-shop -- --template react
cd my-shop
npm install
npm run dev
  • npm create vite@latest my-shop — create the my-shop folder with a project template;
  • npm install — download all the libraries the project needs;
  • npm run dev — start the development server. It prints an address, for example http://localhost:5173 — open it in the browser.

The development server watches the files: you save a change — the page updates itself in a fraction of a second, and the components' state is kept when possible.

What's inside the project

my-shop/
├── index.html          ← the only HTML page, with <div id="root">
├── package.json        ← the project description: dependencies and commands
├── package-lock.json   ← the exact versions of all installed packages
├── vite.config.js      ← bundler settings
├── node_modules/       ← downloaded libraries (not edited and not stored in git)
├── public/             ← files "as is": the icon, images
└── src/
    ├── main.jsx        ← the entry point: createRoot(...).render(<App />)
    ├── App.jsx         ← the root component
    ├── App.css
    └── index.css

package.json is the project's passport:

{
  "name": "my-shop",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  }
}

A new library is added with npm install name — it's downloaded into node_modules and recorded in dependencies. For example, npm install react-router-dom.

Modules: import and export

On the site all the code was in one file. In a project each file is a separate module with its own scope: one file's variables aren't visible in another until they're explicitly exported and imported.

A named export — a module gives away several things by name:

// src/utils/money.js
export function formatPrice(price) {
  return price.toFixed(2) + " somoni";
}

export const CURRENCY = "TJS";
// src/components/ProductCard.jsx
import { formatPrice, CURRENCY } from "../utils/money.js";

A default export — the one main thing of a module. Components are usually exported this way:

// src/components/ProductCard.jsx
import { formatPrice } from "../utils/money.js";

export default function ProductCard({ product }) {
  return (
    <div className="card">
      <h3>{product.title}</h3>
      <p>{formatPrice(product.price)}</p>
    </div>
  );
}
// src/App.jsx
import ProductCard from "./components/ProductCard.jsx";   // you choose the name when importing
What Export Import
Named export function f() {} / export const x = 1 import { f, x } from "./file.js"
Default export default function App() {} import App from "./App.jsx"
Rename — import { f as format } from "./file.js"
From a library — import { useState } from "react"
Styles — import "./App.css"

Paths: ./ — the same folder, ../ — one level up. If a path starts without a dot ("react", "react-router-dom"), it's a package from node_modules.

Now it's clear where the line const { useState } = React; in all the course examples comes from: in a project it's replaced by import { useState } from "react";.

How to split a project into files

There's no single right structure, but this one is enough to start:

src/
├── main.jsx
├── App.jsx                 ← routes
├── api/products.js         ← server request functions
├── context/CartContext.jsx ← CartProvider and the useCart hook
├── hooks/useFetch.js       ← custom hooks
├── components/             ← reusable parts: Header, ProductCard, Button
└── pages/                  ← pages: HomePage, ProductPage, CartPage

The rule: a component longer than ~100 lines or used in several places is a reason to move it into its own file.

Styles

In Vite you simply import a CSS file into a component — and the styles get onto the page:

import "./ProductCard.css";

So that different components' classes don't conflict, CSS modules are used: a file ProductCard.module.css and import styles from "./ProductCard.module.css" → className={styles.card}. Tailwind CSS is also popular — small ready-made classes right in the markup.

Building and publishing

npm run dev is for development. To put the site online, you build it:

npm run build

Vite turns JSX into JavaScript, glues all the modules into a few files, compresses them and puts the result into the dist/ folder. These are ordinary static files — HTML, CSS and JS. They can be put on any hosting, and many are free: Netlify, Vercel, Cloudflare Pages, GitHub Pages. Usually it's enough to connect a GitHub repository — the hosting runs npm run build itself after every change.

Don't forget the React Router setting from the previous topic: the hosting must serve index.html for any address.

Useful tools

  • React Developer Tools — a browser extension: the component tree, their props and state, the Profiler.
  • ESLint (already set up in the Vite template) — finds mistakes, including violations of the rules of hooks and forgotten effect dependencies.
  • Git — the history of the project's changes; node_modules and dist aren't added to it (the .gitignore file).
  • TypeScript — the --template react-ts template: types for props and state catch errors before you even run the code.
  • Next.js — a framework on top of React: file-based routes, loading data on the server, SEO. This site is built with it.

The final project

The last task of the topic is a mini shop that uses almost everything from the course: components and props, lists and key, state and immutable updates, an effect that loads data, routes with parameters, calculations during rendering. Solve it, and then try to repeat it on your own computer in a Vite project, split into files: pages/, components/, context/CartContext.jsx. That will be your first real React project for your portfolio.

Summary

  • Node.js + npm — the environment and the package manager; npm create vite@latest, npm install, npm run dev.
  • package.json — dependencies and commands; libraries — npm install name.
  • Each file is a module: export / export default and import.
  • Packages are imported by name ("react"), your own files by path ("./App.jsx").
  • npm run build → the dist/ folder → free hosting.

Catalog with filters

Easy+10 XP

Write a component Catalog with a prop products (an array of { id, title, category, price }). It shows:

  • a <select> of categories: the first option is all, then all the categories from the products without repeats, in order of first appearance;
  • an <input> for searching by title (case-insensitive);
  • a <ul> with an <li> for each matching product, the text is <title> — <price>.

Compute the filtered list and the list of categories while rendering — keep only the selected category and the search text in state.

category fruit              → Apple — 10, Banana — 5
search "an" (all categories) → Banana — 5, Mango juice — 20

Connect the connector to solve tasks

Task code runs on your own computer — faster and more reliable than in the browser. This needs the free CodeWithMe connector app. You only connect it once.

Looking for the connector on this computer…

  1. 1
    Download the connector for your system (Windows, macOS or Linux).Download the connectorOn the download page pick the file with your system in its name, e.g. windows-amd64.
  2. 2Run it and choose a folder for your solutions. It will install Python and Node.js there by itself when needed.
  3. 3
    Enter below the 6-digit code shown in the connector window (“Code for CodeWithMe”). If the browser asks about local network access — allow it.

The connector is open source (on GitHub), works only on your computer and runs code only after you enter the pairing code.