433 lines
12 KiB
Markdown
433 lines
12 KiB
Markdown
# Development Notes
|
|
|
|
## Current Tech Stack (2025-11-26)
|
|
|
|
- **React 19.1.1** with TypeScript 5.9.3
|
|
- **shadcn/ui** component library (Radix UI + Tailwind)
|
|
- **Tailwind CSS 3.4.18** for styling
|
|
- **Recharts 3.3.0** for data visualization
|
|
- **Vite 5** as build tool
|
|
|
|
## Version Management
|
|
|
|
The project uses a **hybrid versioning approach**:
|
|
- **Semver** (e.g., `0.2.1`) in `package.json` for npm ecosystem compatibility
|
|
- **Git hash** (e.g., `+a3f2b9c`) automatically appended at build time
|
|
- **Displayed version** in UI footer: `0.2.1+a3f2b9c` (or `0.2.1+a3f2b9c-dirty` if uncommitted changes)
|
|
|
|
### Version Scripts
|
|
|
|
```sh
|
|
# Bump version manually (updates package.json)
|
|
npm run version:patch # 0.2.1 → 0.2.2 (bug fixes)
|
|
npm run version:minor # 0.2.1 → 0.3.0 (new features)
|
|
npm run version:major # 0.2.1 → 1.0.0 (breaking changes)
|
|
|
|
# Generate version.json with git info (runs automatically on build)
|
|
npm run prebuild
|
|
|
|
# Build for production (automatically generates version)
|
|
npm run build
|
|
```
|
|
|
|
### How It Works
|
|
|
|
1. **Manual semver bump**: Run `npm run version:patch|minor|major` when you want to increment the version
|
|
2. **Automatic git info**: On build, `scripts/generate-version.js` creates `src/version.json` with:
|
|
- `version`: Semver + git hash (e.g., `0.2.1+a3f2b9c`)
|
|
- `semver`: Just the semver (e.g., `0.2.1`)
|
|
- `commit`: Git commit hash (e.g., `a3f2b9c`)
|
|
- `branch`: Current git branch
|
|
- `buildDate`: ISO timestamp
|
|
- `gitDate`: Commit date
|
|
3. **Fallback handling**: If `version.json` is missing (fresh clone before first build), `src/constants/defaults.ts` generates a fallback version from `package.json`
|
|
|
|
### Version Display
|
|
|
|
The version is displayed in the UI footer (bottom right) next to the GitHub repository link. The format is:
|
|
- `0.2.1+a3f2b9c` (clean working directory)
|
|
- `0.2.1+a3f2b9c-dirty` (uncommitted changes present)
|
|
- `0.2.1-dev` (fallback when version.json is missing)
|
|
|
|
### Files
|
|
|
|
- `scripts/generate-version.js` - Generates version.json from git + package.json
|
|
- `scripts/bump-version.js` - Manually bumps semver in package.json
|
|
- `src/version.json` - Auto-generated, ignored by git
|
|
- `src/version.json.template` - Fallback template (committed to repo)
|
|
- `src/constants/defaults.ts` - Exports `APP_VERSION` and `BUILD_INFO`
|
|
|
|
## Initial Setup (Fresh Clone)
|
|
|
|
```sh
|
|
# Install all dependencies
|
|
npm install
|
|
|
|
# Run development server (Vite on port 3000)
|
|
npm start
|
|
|
|
# Build for production
|
|
npm run build
|
|
|
|
# Optionally preview the production build
|
|
npm run preview
|
|
```
|
|
|
|
### 2026-01-07 Build Tool Migration
|
|
|
|
We migrated from Create React App to Vite to resolve conflicting optional peer dependencies around `typescript` (CRA expected TS `^3.2 || ^4` while several libraries prefer TS `^5`). Vite supports modern TypeScript and avoids those conflicts, making new workspace setups straightforward. It is also much faster in dev mode.
|
|
|
|
## shadcn/ui Setup (Already Done)
|
|
|
|
The project was set up with shadcn/ui components. If you need to add more components:
|
|
|
|
```sh
|
|
# Add new shadcn/ui components
|
|
npx shadcn@latest add [component-name]
|
|
|
|
# Example:
|
|
npx shadcn@latest add dialog
|
|
```
|
|
|
|
## TypeScript Configuration
|
|
|
|
TypeScript is configured with:
|
|
- Strict mode enabled
|
|
- Path aliases: `@/*` → `./src/*`
|
|
- Target: ES5
|
|
- Module: ESNext
|
|
- JSX: react-jsx
|
|
|
|
## Tailwind CSS Configuration
|
|
|
|
Content paths in `tailwind.config.js`:
|
|
|
|
```javascript
|
|
module.exports = {
|
|
content: [
|
|
"./src/**/*.{js,jsx,ts,tsx}",
|
|
],
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
// HSL-based color system for shadcn/ui
|
|
},
|
|
},
|
|
},
|
|
plugins: [require("tailwindcss-animate")],
|
|
}
|
|
```
|
|
|
|
Global styles in `./src/styles/global.css`:
|
|
|
|
```css
|
|
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
@layer base {
|
|
:root {
|
|
--background: 0 0% 98%;
|
|
--foreground: 222 47% 11%;
|
|
/* ... more CSS variables for shadcn/ui theme */
|
|
}
|
|
}
|
|
```
|
|
|
|
## WSL Networking Issues
|
|
|
|
Please be aware that the issues and potential solutions in this section were relevant when using Create React App's webpack dev server. They may still apply to Vite in some cases, but Vite generally handles WSL2 networking better. The documentation was changed to reflect Vite usage (see earlier revisions), but never verified in all details.
|
|
|
|
If access to `http://localhost:3000` does not work from Windows host when running the Vite dev server in WSL, look at the following troubleshooting steps.
|
|
|
|
Note that not all steps may be necessary, depending on your specific WSL and Windows setup.
|
|
|
|
**For Vite:** The `HOST=0.0.0.0` binding is configured in `vite.config.ts` with `server.host: true`. The `start:wsl2` script also sets the environment variable as a fallback.
|
|
|
|
In my case the `npm start` terminal output shows:
|
|
|
|
```sh
|
|
Local: http://localhost:3000
|
|
On Your Network: http://172.20.39.187:3000
|
|
```
|
|
|
|
### WSL Networking Modes
|
|
|
|
Check and potentially change the network mode of WSL.
|
|
|
|
#### Option 1: NAT Networking Mode (Default)
|
|
|
|
This is the default mode used if Option 2 is not specifically set. Unless the settings described in Option 2 are applied, this mode is active.
|
|
|
|
#### Option 2: Mirrored Networking Mode (Windows 11 22H2+)
|
|
|
|
In `%USERPROFILE%\.wslconfig` add:
|
|
|
|
```ini
|
|
[wsl2]
|
|
networkingMode=mirrored
|
|
```
|
|
|
|
Then stop WSL and start it again so the changes take effect:
|
|
|
|
```batch
|
|
wsl --shutdown
|
|
wsl
|
|
```
|
|
|
|
### Dev Server Host Binding
|
|
|
|
**Vite** automatically binds to all interfaces when `server.host: true` is set in `vite.config.ts` (already configured).
|
|
|
|
For WSL2 environments, use the dedicated script:
|
|
|
|
```bash
|
|
npm run start:wsl2
|
|
```
|
|
|
|
This sets `HOST=0.0.0.0` explicitly as an environment variable for additional compatibility.
|
|
|
|
### Port Forwarding
|
|
|
|
If you want to access the Vite dev server via `http://localhost:3000` on Windows host, you need to set up port forwarding from Windows localhost to the WSL IP address.
|
|
|
|
First get the WSL IP address by running the following command in WSL:
|
|
|
|
```sh
|
|
hostname -I
|
|
|
|
# Or from Windows Command Prompt / PowerShell:
|
|
wsl hostname -I
|
|
```
|
|
|
|
Then use the WSL IP address (in my case `172.20.39.187`) in the following command to set up permanent port forwarding.
|
|
|
|
```batch
|
|
# Add port forwarding rule
|
|
netsh interface portproxy add v4tov4 listenport=3000 listenaddress=127.0.0.1 connectport=3000 connectaddress=172.20.39.187
|
|
|
|
# Just in case you need to delete the rule later, use:
|
|
#netsh interface portproxy delete v4tov4 listenport=3000 listenaddress=127.0.0.1
|
|
```
|
|
|
|
You should now be able to access the Vite dev server via `http://localhost:3000` on Windows host, instead of having to use the WSL IP address.
|
|
|
|
### Open Firewall Ports
|
|
|
|
In case you have trouble with your Windows Firewall blocking access to the forwarded port, or you want to allow access from other devices on your network, you may need to open the port in the firewall.
|
|
|
|
Run the following PowerShell commands to open the necessary port (just an example, ensure that the settings fit your security requirements):
|
|
|
|
```powershell
|
|
# Open port 3000 for inbound TCP traffic on WSL virtual network interface
|
|
New-NetFirewallRule -DisplayName "Allow WSL Inbound Port 3000" `
|
|
-Direction Inbound -Action Allow -Protocol TCP -LocalPort 3000 `
|
|
-InterfaceAlias "vEthernet (WSL (Hyper-V firewall))"
|
|
```
|
|
In case the above does not resolve your issues, just to rule out potential firewall issues, it is always an option to temporarily disable the firewall all together.
|
|
|
|
> WARNING: IF YOU DO THIS, DO NOT FORGET TO RE-ENABLE THE FIREWALL AFTER TESTING!
|
|
|
|
## VS Code Dev Container Port Forwarding
|
|
|
|
When running the Vite dev server in a VS Code dev container (WSL2 + Podman/Docker), VS Code automatically forwards ports from the container to the Windows host.
|
|
|
|
**Vite HMR (Hot Module Replacement) automatically detects the correct WebSocket port** from the page URL, so no special configuration is needed (unlike the old webpack dev server which required `WDS_SOCKET_PORT=0`).
|
|
|
|
You may encounter:
|
|
|
|
1. **Port remapping**: If port 3000 is busy on Windows, VS Code may forward to 3001 or another available port - this is normal and Vite will adapt automatically.
|
|
|
|
### Dev Container vs Direct WSL2 Configuration Differences
|
|
|
|
**In VS Code Dev Containers:**
|
|
- `HOST=0.0.0.0` is **not needed** - VS Code handles port forwarding from container's localhost
|
|
- File watching works reliably - Vite's HMR is fast and stable
|
|
|
|
**In Direct WSL2 (no container):**
|
|
- `HOST=0.0.0.0` is **recommended** - to bind to WSL2's network interface for host access
|
|
- Manual port forwarding with `netsh interface portproxy` may be needed
|
|
|
|
**Project Scripts:**
|
|
|
|
The project includes separate scripts for different environments:
|
|
|
|
```bash
|
|
# In VS Code Dev Container (default, optimized)
|
|
npm start
|
|
|
|
# In direct WSL2 (without container)
|
|
npm run start:wsl2
|
|
```
|
|
|
|
Configured in `package.json`:
|
|
```json
|
|
"scripts": {
|
|
"start": "vite",
|
|
"start:wsl2": "HOST=0.0.0.0 vite"
|
|
}
|
|
```
|
|
|
|
This way you don't need to modify scripts when switching between environments.
|
|
|
|
### Configure Port Forwarding Behavior
|
|
|
|
In `.devcontainer/devcontainer.json`, you can configure port forwarding:
|
|
|
|
```jsonc
|
|
{
|
|
"forwardPorts": [3000],
|
|
"portsAttributes": {
|
|
"3000": {
|
|
"label": "Vite Dev Server",
|
|
"onAutoForward": "notify"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Check Which Port is Actually Forwarded
|
|
|
|
In VS Code, check the **PORTS** tab (usually in the bottom panel) to see:
|
|
- Which container ports are forwarded
|
|
- Which Windows host ports they map to
|
|
- You can manually change the forwarded port by right-clicking the port entry
|
|
|
|
**Note:** If port 3000 is busy on Windows, VS Code may automatically forward to 3001 or another available port. This is normal - just use whatever port VS Code assigns in the PORTS tab.
|
|
|
|
### Kill Stuck Dev Server
|
|
|
|
If you need to free port 3000 (e.g., stuck dev server process):
|
|
|
|
```bash
|
|
npm run kill
|
|
```
|
|
|
|
This script uses `lsof` to find and terminate any process using port 3000. Note: `lsof` must be installed in the container (already configured in Dockerfile).
|
|
|
|
### Important: No Manual Port Proxy Needed
|
|
|
|
When using VS Code dev containers, you **do not need** `netsh interface portproxy` rules. VS Code handles all port forwarding automatically. Remove any existing rules:
|
|
|
|
```batch
|
|
netsh interface portproxy delete v4tov4 listenport=3000 listenaddress=127.0.0.1
|
|
```
|
|
|
|
## Development Server
|
|
|
|
### (Prevent) Auto Open in Browser
|
|
|
|
**Vite does not automatically open the browser** by default when the dev server starts. If you want to enable this behavior, add to `vite.config.ts`:
|
|
|
|
```typescript
|
|
export default defineConfig({
|
|
server: {
|
|
open: true // Opens browser automatically
|
|
}
|
|
});
|
|
```
|
|
|
|
### Hot Module Replacement (HMR)
|
|
|
|
Vite's HMR is significantly faster than webpack and works reliably in most environments including WSL2 and dev containers. File system watching is handled natively and typically doesn't require polling.
|
|
|
|
If you encounter issues with HMR not detecting changes (rare), you can configure polling in `vite.config.ts`:
|
|
|
|
```typescript
|
|
export default defineConfig({
|
|
server: {
|
|
watch: {
|
|
usePolling: true
|
|
}
|
|
}
|
|
});
|
|
```
|
|
|
|
Then the `start` script can remain as:
|
|
|
|
```sh
|
|
npm start
|
|
```
|
|
|
|
## Webhint
|
|
|
|
### Setup webhint in Project
|
|
|
|
Check local config:
|
|
|
|
```sh
|
|
# Install hint locally in the project
|
|
npm install hint --save-dev
|
|
|
|
# Optionally use the web-recommended config
|
|
#npm install @hint/configuration-web-recommended --save-dev
|
|
#npm create hintrc
|
|
|
|
# Or create .hintrc manually with a basic config
|
|
```sh
|
|
cat > .hintrc <<EOL
|
|
{
|
|
"extends": ["web-recommended"]
|
|
}
|
|
EOL
|
|
```
|
|
|
|
Add `webhint` script to `package.json`:
|
|
|
|
```json
|
|
"scripts": {
|
|
"webhint": "hint"
|
|
}
|
|
```
|
|
|
|
Optionally install puppeteer if you want to run webhint with headless Chrome:
|
|
|
|
```sh
|
|
npm install puppeteer --save-dev
|
|
```
|
|
|
|
### Run webhint
|
|
|
|
Ensure that the Vite development server is running when you run webhint against `http://localhost:3000`.
|
|
|
|
```sh
|
|
npm start
|
|
```
|
|
|
|
Run webhint:
|
|
|
|
```sh
|
|
npm run webhint -- http://localhost:3000
|
|
```
|
|
|
|
Open `./hint-report/http-localhost-3000.html` in a browser to see the report.
|
|
|
|
### VS Code: Problems with "Microsoft Edge Tools for VS Code" Extension
|
|
|
|
Error message:
|
|
|
|
> Unable to start webhint. Ensure you are using the latest version of the `hint` package.
|
|
|
|
Solution:
|
|
|
|
Install webhint locally in the project as shown above, or update to the latest version:
|
|
|
|
```sh
|
|
npm install hint@latest --save-dev
|
|
```
|
|
|
|
In doubt check the global installation and remove it if necessary:
|
|
|
|
```sh
|
|
# Global config
|
|
npm list -g hint
|
|
|
|
# Uninstall global version if necessary
|
|
npm uninstall -g hint
|
|
```
|
|
|
|
### External Resources
|
|
|
|
* [https://github.com/webhintio/hint](https://github.com/webhintio/hint)
|
|
* [https://webhint.io/docs/user-guide/configuring-webhint/summary/](https://webhint.io/docs/user-guide/configuring-webhint/summary/)
|