Categories
Development

React Projekt aufsetzen

Ausgangslage

Ubuntu 22.04.5 LTS mit node v20.17.0 und npm 10.8.2

React-Projekt einrichten

  1. Terminal öffnen und in das Verzeichnis navigieren, in dem das Verzeichnis für das Projekt erstellt werden soll.
  2. Erstelle ein neues Vite-Projekt mit React (Vite ist ein moderner Build-Tool, der schneller als Create React App ist):
npm create vite@latest my-react-app -- --template react
  1. Wechsle in das neue Projektverzeichnis und installiere die Abhängigkeiten:
cd my-react-app && npm install

4: Starte den Entwicklungsserver:

npm run dev

Jetzt kanns im Browser unter http://localhost:5173 die React-Anwendung aufgerufen werden.

Projektstruktur

my-react-app/
├── node_modules/
├── public/
├── src/
│   ├── assets/
│   ├── App.jsx
│   ├── App.css
│   ├── index.css
│   └── main.jsx
├── .gitignore
├── index.html
├── package.json
├── package-lock.json
└── vite.config.js

Wichtige Dateien:

  • src/App.jsx: Deine Hauptkomponente
  • src/main.jsx: Der Einstiegspunkt deiner Anwendung
  • index.html: Die HTML-Vorlage
  • package.json: Projektkonfiguration und Abhängigkeiten

Nützliche npm Befehle:

  • npm run dev: Startet den Entwicklungsserver
  • npm run build: Erstellt eine optimierte Produktionsversion
  • npm run preview: Zeigt die Produktionsversion lokal an

Wichtige Tools

Tailwind CSS

Tailwind CSS ist ein Utility-First-CSS-Framework, das eine Sammlung von vordefinierten CSS-Klassen bereitstellt, die man direkt in deinem HTML (oder JSX) verwenden kannst. Anstatt vordefinierte Komponenten (wie Buttons oder Karten) anzubieten, bietet Tailwind kleine, atomare Utility-Klassen, die man kombinieren kann, um benutzerdefinierte Designs zu erstellen.

Utility-First-Ansatz

Der Utility-First-Ansatz bedeutet, dass man Stile durch das Kombinieren von kleinen, spezifischen Klassen anwendest. Jede Klasse entspricht einer CSS-Eigenschaft.

Beispiel:

<button class="bg-blue-500 text-white font-bold py-2 px-4 rounded">
  Klick mich
</button>
  • bg-blue-500: Hintergrundfarbe (blau, 500er Stufe).
  • text-white: Textfarbe (weiß).
  • font-bold:Schriftstärke (fett).
  • py-2: Padding oben und unten (2 Einheiten).
  • px-4: Padding links und rechts (4 Einheiten).
  • rounded: Abgerundete Ecken.

Warum werden PostCSS und Autoprefixer mit Tailwind CSS verwendet?

Tailwind CSS ist ein Utility-First-Framework, das stark auf PostCSS angewiesen ist, um:

  • Utility-Klassen zu generieren: Tailwind verwendet PostCSS, um die Utility-Klassen (z. B. mt-4, text-center) in normales CSS umzuwandeln.
  • CSS zu optimieren: PostCSS entfernt ungenutzte CSS-Klassen (mit dem purge-Feature), um die Bundle-Größe zu reduzieren.
  • Browser-Präfixe hinzuzufügen: Autoprefixer stellt sicher, dass das generierte CSS in allen Browsern funktioniert.

PostCSS

PostCSS ist ein Tool zur Transformation von CSS mit JavaScript. Es fungiert als eine Art "CSS-Compiler" und ermöglicht es, CSS durch Plugins zu erweitern und zu optimieren.

Wofür braucht man PostCSS?

  • Tailwind CSS: Tailwind verwendet PostCSS, um seine Utility-Klassen in normales CSS umzuwandeln.
  • CSS-Modernisierung: PostCSS kann modernes CSS (z. B. CSS-Variablen, verschachtelte Regeln) in browserkompatibles CSS umwandeln.
  • Plugin-Ökosystem: Es gibt zahlreiche PostCSS-Plugins, die zusätzliche Funktionen bieten, z. B.:
    • Autoprefixer (für Browser-Präfixe)
    • CSS-Nano (für CSS-Minifizierung)
    • CSS-Modules (für lokale Scope-CSS)

Autoprefixer

Autoprefixer ist ein PostCSS-Plugin, das automatisch Browser-Präfixe (Vendor-Prefixes) zu deinem CSS hinzufügt. Dies stellt sicher, dass dein CSS in allen Browsern korrekt funktioniert.

Wofür braucht man Autoprefixer?

  • Browser-Kompatibilität: Einige CSS-Eigenschaften (z. B. flexbox, grid, transform) benötigen browser-spezifische Präfixe wie -webkit-, -moz-, -ms- usw.
  • Automatisierung: Autoprefixer fügt diese Präfixe automatisch hinzu, basierend auf den Browsern, die du unterstützen möchtest. Du musst dich nicht mehr manuell um Präfixe kümmern.
  • Zukunftssicherheit: Autoprefixer entfernt auch veraltete Präfixe, die nicht mehr benötigt werden.

Lucide

Lucide ist eine Sammlung von einfachen, eleganten und konsistenten Icons, die als Open Source verfügbar sind. Es ist der Nachfolger von Feather Icons und bietet eine große Auswahl an Icons für Web- und Mobile-Anwendungen. lucide-react ist das offizielle React-Paket, das die Lucide-Icons für die Verwendung in React-Projekten bereitstellt.

  • Icon-Sammlung: Lucide bietet über 1.000 Icons in einem einheitlichen Designstil.
  • Open Source: Die Icons sind kostenlos und unter der MIT-Lizenz verfügbar.
  • Einfach und minimalistisch: Die Icons sind schlicht und eignen sich gut für moderne Benutzeroberflächen.
  • Skalierbar: Die Icons sind als SVG verfügbar und können in jeder Größe verwendet werden.

Installation und Einrichtung

Installation und Einrichtung:

# Installation
npm install -D tailwindcss postcss autoprefixer lucide-react

# Tailwind und PostCSS Config erstellen
npx tailwindcss init -p

Die erzeugte tailwind.config.jsanpassen:

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Tailwind in das Projekt einbinden: In der Datei src/App.css folgenden Inhalt hinzufügen:

@tailwind base;
@tailwind components;
@tailwind utilities;

Den Entwicklungsserver starten:

npm run dev
Categories
Development

WebSockets with Node.js

WebSockets are a protocol that provides full-duplex communication channels over a single, long-lived connection. They are designed for real-time, event-driven web applications and allow for low-latency communication between a client (typically a web browser) and a server. Here are some key points about WebSockets:

  1. Full-Duplex Communication: Unlike HTTP, which is request-response based, WebSockets allow for two-way communication where both client and server can send and receive messages independently of each other.
  2. Persistent Connection: WebSocket connections are persistent, meaning they remain open as long as both the client and server agree to keep the connection alive. This reduces the overhead associated with establishing new connections.
  3. Low Latency: WebSockets are ideal for scenarios requiring real-time updates because they reduce the latency associated with polling or long-polling techniques.
  4. Protocol: WebSockets are established by upgrading an HTTP/HTTPS connection using a WebSocket handshake, switching the protocol from HTTP to WebSocket.
  5. Use Cases: Common use cases include live chat applications, real-time notifications, collaborative editing, online gaming, and any application requiring real-time data updates.

Node.js in Codespace

I want to test WebSockets with Node.js in GitHub Codespace.

Node Version Manager (nvm)

# test installation
command -v nvm
nvm

# check version
nvm ls
       v18.20.1
       v20.12.1
->       system
default -> 20 (-> v20.12.1)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v20.12.1) (default)
stable -> 20.12 (-> v20.12.1) (default)
lts/* -> lts/iron (-> v20.12.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12 (-> N/A)
lts/fermium -> v14.21.3 (-> N/A)
lts/gallium -> v16.20.2 (-> N/A)
lts/hydrogen -> v18.20.1
lts/iron -> v20.12.1

# check node version
node --version
v20.12.1

Node.js

# install LTS
nvm install --lts
Installing latest LTS version.
Now using node v20.14.0 (npm v10.7.0)

# check version
nvm ls

# check node version
node --version
v20.14.0

Some npm commands

# Show installed Nodes
nvm ls
# Show available versions
nvm ls-remote
# Install latest version
nvm install node
# Install LTS version
nvm install --lts
# Install a specific version (list available -> example 16.20.2)
nvm install 16.20.2
# Use a specific version
nvm use 16.20.2
# Show npm version
npm --version

Simple Website with Node.js

To serve an HTML page using Node.js, we can use the built-in http module.

Create an HTML file




    
    
    Node.js HTML Server


    

Hello, World!

This is a simple HTML page served by Node.js.

Create a Node.js script to serve the HTML file

const http = require('http');
const fs = require('fs');
const path = require('path');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
    if (req.method === 'GET' && req.url === '/') {
        const filePath = path.join(__dirname, 'index.html');
        fs.readFile(filePath, (err, data) => {
            if (err) {
                res.statusCode = 500;
                res.setHeader('Content-Type', 'text/plain');
                res.end('Internal Server Error');
            } else {
                res.statusCode = 200;
                res.setHeader('Content-Type', 'text/html');
                res.end(data);
            }
        });
    } else {
        res.statusCode = 404;
        res.setHeader('Content-Type', 'text/plain');
        res.end('Not Found');
    }
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

Run the Node.js server

node server.js

Test Node.js server in terminal

curl localhost:3000
http localhost:3000

Test Node.js server in browser

WebSocket in Codespace

To create a Node.js server that provides both an HTTP server for serving an HTML page and a WebSocket server for real-time communication, we can use the ws library for WebSockets.

Install the ws library

npm install ws

Create the HTML file




    
    
    WebSocket Example


    

WebSocket Example

Connecting...

Create the Node.js server

const http = require('http');
const fs = require('fs');
const path = require('path');
const WebSocket = require('ws');

const hostname = '127.0.0.1';
const port = 3000;

// Create HTTP server
const server = http.createServer((req, res) => {
    if (req.method === 'GET' && req.url === '/') {
        const filePath = path.join(__dirname, 'index.html');
        fs.readFile(filePath, (err, data) => {
            if (err) {
                res.statusCode = 500;
                res.setHeader('Content-Type', 'text/plain');
                res.end('Internal Server Error');
            } else {
                res.statusCode = 200;
                res.setHeader('Content-Type', 'text/html');
                res.end(data);
            }
        });
    } else {
        res.statusCode = 404;
        res.setHeader('Content-Type', 'text/plain');
        res.end('Not Found');
    }
});

// Create WebSocket server
const wss = new WebSocket.Server({ server });

wss.on('connection', ws => {
    console.log('Client connected');

    ws.on('message', message => {
        console.log(`Received: ${message}`);
        ws.send('Hello Client');
    });

    ws.on('close', () => {
        console.log('Client disconnected');
    });
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

Run the Node.js server

node server.js

Test Node.js server in terminal

curl localhost:3000
http localhost:3000

Test Node.js server in browser

Brower Fix

We need to adjust the address of the WebSocket.

When setting up a WebSocket connection from the client-side script within the HTML file, the WebSocket URL must match the address and port where the WebSocket server is running. This URL should include the WebSocket protocol (ws:// or wss:// for secure connections)

Adjustment:

const socket = new WebSocket('wss://symmetrical-disco-g454xqrq9pqvfw6pr-3000.app.github.dev/:3000');

OK, this works, so make it a little more dynamic:

const socket = new WebSocket('wss://' + location.host + '/:3000');

Test WebSocket from terminal

Unfortunately, curl and httpie do not natively support WebSocket protocols. To test WebSocket connections using command-line we can use wscat, which is specifically designed for WebSocket communication.

npm install -g wscat

Using wscat to Test WebSocket Connections:

wscat -c ws://localhost:3000

Connected (press CTRL+C to quit)
> hello
< Hello Client

Build a Chat App

Let's build a "Chat App"

Server

We enhance the server to dynamically answer to a message:

[...]
     ws.on('message', message => {
        console.log(`Received: ${message}`);
        ws.send('Hello ' + message);
    });
[...]

Amazing!

Client




    
    
    WebSocket Chat Example
    


    

WebSocket Chat Example

Connecting...



Awesome!

Also 'Chatbot' is working from terminal:

Categories
Development

Node.js WSL

Install Node.js on WSL

Install Node.js on Windows Subsystem for Linux (WSL2)

I am following this instructions: https://learn.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-wsl

Install Node Version Manager (nvm)

sudo apt-get install curl
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash

## Open NEW TERMINAL windows

# test installation
command -v nvm
nvm

# check version
nvm ls

->       system
iojs -> N/A (default)
node -> stable (-> N/A) (default)
unstable -> N/A (default)

# check node version
node --version
v10.19.0

Install Node.js

# install LTS
nvm install --lts

# check version
nvm ls
->     v16.18.0
         system
default -> lts/* (-> v16.18.0)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v16.18.0) (default)
stable -> 16.18 (-> v16.18.0) (default)
lts/* -> lts/gallium (-> v16.18.0)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12 (-> N/A)
lts/fermium -> v14.20.1 (-> N/A)
lts/gallium -> v16.18.0

# check node version
node --version
v16.18.0

# check npm version
npm --version
8.19.2

Some npm commands

# Show installed Nodes
nvm ls
# Show available versions
nvm ls-remote
# Install latest version
nvm install node
# Install LTS version
nvm install --lts
# Install a specific version (list available -> example 16.18.0)
nvm install 16.18.0
# Use a specific version
nvm use 16.18.0
# Show npm version
npm --version

Categories
AWS

Example React application on AWS Amplify

I followed the steps through this tutorial: https://aws.amazon.com/de/getting-started/hands-on/build-react-app-amplify-graphql/

I is mostly well documented. But I had some obstacles:

Build specification

I had to add the backend part to the build specification:

version: 1
backend:
  phases:
    build:
      commands:
        - '# Execute Amplify CLI with the helper script'
        - amplifyPush --simple
frontend:
  phases:
    preBuild:
      commands:
        - npm ci
    build:
      commands:
         - npm run build
  artifacts:
    baseDirectory: build
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

Service role

I had to create and add a service role.

First create a service role in IAM console, named it "AmplifyConsoleServiceRole-AmplifyRole":

Then add this role in the general settings of the Amplify application:

Amplify CLI to latest version

I had to set the Live package updates for the Amplify CLI to the latest version in build image settings:

To be continued...

Unfortunately this took too much time, so I have to do the last steps (4: API and database; 5: storage) another time. Maybe there will be some other challanges I can write down here.

Categories
Development

Node.js

Install Node.js on Windows

I am following this instructions: https://docs.microsoft.com/de-de/windows/nodejs/setup-on-windows

Download Node Version Manager (nvm) for Windows: https://github.com/coreybutler/nvm-windows#node-version-manager-nvm-for-windows
Current version: 1.1.7; nvm-setup.zip

Open cmd or GitBash and run 'nvm ls' to see installed Node versions.

Some npm commands:

# Show installed Nodes
nvm ls
# Show available versions
nvm list available
# Install latest version
nvm install latest
# Install latest LTS version (list available -> currently 12.19.0)
nvm install 12.19.0
# Use latest LTS version
nvm use 12.19.0
# Show npm version
npm --version