frontend-hamroun 1.2.53 → 1.2.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -603
- package/package.json +1 -1
package/README.md
CHANGED
@@ -1,69 +1,33 @@
|
|
1
|
-
|
1
|
+
# Frontend Hamroun
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
<img src="https://raw.githubusercontent.com/hamroun/frontend-hamroun/main/assets/logo.png" alt="Frontend Hamroun Logo" width="300" style="border-radius: 10px; margin: 20px 0;"/>
|
3
|
+

|
6
4
|
|
7
5
|
A lightweight full-stack JavaScript framework with Virtual DOM and hooks implementation
|
8
6
|
|
9
|
-
[
|
23
|
-
- [Quick Start](#-quick-start)
|
24
|
-
- [Features](#-features)
|
25
|
-
- [Client-side Features](#-client-side-features)
|
26
|
-
- [Server-side Features](#-server-side-features)
|
27
|
-
- [Server-Side Rendering](#-server-side-rendering)
|
28
|
-
- [Performance Optimization](#-performance-optimization)
|
29
|
-
- [CLI Tools](#-cli-tools)
|
30
|
-
- [TypeScript Support](#-typescript-support)
|
31
|
-
- [Browser Compatibility](#-browser-compatibility)
|
32
|
-
- [Contributing](#-contributing)
|
33
|
-
- [Documentation](#-documentation)
|
7
|
+
[](https://www.npmjs.com/package/frontend-hamroun)
|
8
|
+
[](https://bundlephobia.com/result?p=frontend-hamroun)
|
9
|
+
[](https://www.npmjs.com/package/frontend-hamroun)
|
10
|
+
[](LICENSE)
|
34
11
|
|
35
|
-
|
36
|
-
|
37
|
-
## 🔌 Installation
|
12
|
+
## Installation
|
38
13
|
|
39
14
|
```bash
|
40
15
|
npm install frontend-hamroun
|
41
16
|
```
|
42
17
|
|
43
|
-
|
44
|
-
|
45
|
-
### ✨ Quick Links
|
46
|
-
|
47
|
-
[](https://github.com/hamroun/frontend-hamroun)
|
48
|
-
[](https://github.com/hamroun/frontend-hamroun/examples)
|
49
|
-
[](https://github.com/hamroun/frontend-hamroun/docs/API.md)
|
50
|
-
[](https://discord.gg/frontendhamroun)
|
51
|
-
|
52
|
-
</div>
|
53
|
-
|
54
|
-
## 🚀 Quick Start
|
18
|
+
## Quick Start
|
55
19
|
|
56
|
-
Create a new project
|
20
|
+
Create a new project using:
|
57
21
|
|
58
22
|
```bash
|
59
|
-
# Using create-frontend-app
|
23
|
+
# Using the create-frontend-app command
|
60
24
|
npx create-frontend-app my-app
|
61
25
|
|
62
26
|
# Or using the frontend-hamroun CLI
|
63
27
|
npx frontend-hamroun create my-app
|
64
28
|
```
|
65
29
|
|
66
|
-
Then
|
30
|
+
Then:
|
67
31
|
|
68
32
|
```bash
|
69
33
|
cd my-app
|
@@ -71,92 +35,17 @@ npm install
|
|
71
35
|
npm run dev
|
72
36
|
```
|
73
37
|
|
74
|
-
|
75
|
-
|
76
|
-
### 🎮 Interactive Demo
|
77
|
-
|
78
|
-
[](https://codesandbox.io)
|
79
|
-
[](https://stackblitz.com)
|
80
|
-
|
81
|
-
</div>
|
82
|
-
|
83
|
-
## 🎯 Features
|
84
|
-
|
85
|
-
<div class="features-grid" style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px;">
|
86
|
-
|
87
|
-
<div class="feature-card" style="background: #f8f9fa; border-radius: 8px; padding: 20px;">
|
88
|
-
<h3>🔍 Lightweight Core</h3>
|
89
|
-
<p><strong><5KB</strong> gzipped for essential runtime</p>
|
90
|
-
</div>
|
91
|
-
|
92
|
-
<div class="feature-card" style="background: #f8f9fa; border-radius: 8px; padding: 20px;">
|
93
|
-
<h3>⚡ Full-Stack Solution</h3>
|
94
|
-
<p>Client and server capabilities in one package</p>
|
95
|
-
</div>
|
96
|
-
|
97
|
-
<div class="feature-card" style="background: #f8f9fa; border-radius: 8px; padding: 20px;">
|
98
|
-
<h3>🔄 Virtual DOM</h3>
|
99
|
-
<p>Efficient rendering and diffing algorithm</p>
|
100
|
-
</div>
|
101
|
-
|
102
|
-
<div class="feature-card" style="background: #f8f9fa; border-radius: 8px; padding: 20px;">
|
103
|
-
<h3>🪝 Hooks API</h3>
|
104
|
-
<p>Complete hooks system for state management</p>
|
105
|
-
</div>
|
106
|
-
|
107
|
-
<div class="feature-card" style="background: #f8f9fa; border-radius: 8px; padding: 20px;">
|
108
|
-
<h3>🌐 Server-Side Rendering</h3>
|
109
|
-
<p>Optimized SSR with hydration</p>
|
110
|
-
</div>
|
111
|
-
|
112
|
-
<div class="feature-card" style="background: #f8f9fa; border-radius: 8px; padding: 20px;">
|
113
|
-
<h3>🔐 Authentication</h3>
|
114
|
-
<p>Built-in JWT authentication system</p>
|
115
|
-
</div>
|
116
|
-
|
117
|
-
<div class="feature-card" style="background: #f8f9fa; border-radius: 8px; padding: 20px;">
|
118
|
-
<h3>💾 Database Integration</h3>
|
119
|
-
<p>Support for MongoDB, MySQL, PostgreSQL</p>
|
120
|
-
</div>
|
121
|
-
|
122
|
-
<div class="feature-card" style="background: #f8f9fa; border-radius: 8px; padding: 20px;">
|
123
|
-
<h3>🧩 TypeScript Support</h3>
|
124
|
-
<p>Full type definitions included</p>
|
125
|
-
</div>
|
126
|
-
|
127
|
-
</div>
|
128
|
-
|
129
|
-
<br>
|
130
|
-
|
131
|
-
## 📊 Framework Comparison
|
132
|
-
|
133
|
-
| Feature | Frontend Hamroun | React | Vue | Angular |
|
134
|
-
|---------|------------------|-------|-----|---------|
|
135
|
-
| Bundle Size | < 5KB | 42KB | 33KB | 65KB |
|
136
|
-
| Virtual DOM | ✅ | ✅ | ✅ | ❌ |
|
137
|
-
| Hooks API | ✅ | ✅ | ⚠️ | ❌ |
|
138
|
-
| Built-in SSR | ✅ | ❌ | ⚠️ | ✅ |
|
139
|
-
| Built-in API Server | ✅ | ❌ | ❌ | ❌ |
|
140
|
-
| DB Integration | ✅ | ❌ | ❌ | ❌ |
|
141
|
-
| Learning Curve | Low | Medium | Low | High |
|
142
|
-
|
143
|
-
<br>
|
144
|
-
|
145
|
-
## 💻 Basic Usage
|
38
|
+
## Basic Usage
|
146
39
|
|
147
40
|
```jsx
|
148
41
|
import { render, useState } from 'frontend-hamroun';
|
149
42
|
|
150
43
|
function App() {
|
151
44
|
const [count, setCount] = useState(0);
|
152
|
-
|
153
45
|
return (
|
154
|
-
<div
|
155
|
-
<h1>
|
156
|
-
<
|
157
|
-
<button onClick={() => setCount(count + 1)}>
|
158
|
-
Increment
|
159
|
-
</button>
|
46
|
+
<div>
|
47
|
+
<h1>Count: {count}</h1>
|
48
|
+
<button onClick={() => setCount(count + 1)}>Increment</button>
|
160
49
|
</div>
|
161
50
|
);
|
162
51
|
}
|
@@ -164,15 +53,23 @@ function App() {
|
|
164
53
|
render(<App />, document.getElementById('root'));
|
165
54
|
```
|
166
55
|
|
167
|
-
|
168
|
-
<img src="https://via.placeholder.com/600x300?text=Application+Screenshot" alt="Application Screenshot" width="600" style="border-radius: 8px;"/>
|
169
|
-
</div>
|
56
|
+
## Features
|
170
57
|
|
171
|
-
|
58
|
+
- **Lightweight Core**: <5KB gzipped for essential runtime
|
59
|
+
- **Full-Stack Solution**: Client and server capabilities in one package
|
60
|
+
- **Virtual DOM**: Efficient rendering and diffing algorithm
|
61
|
+
- **Hooks API**: Complete hooks system (useState, useEffect, useMemo, useRef)
|
62
|
+
- **Context API**: Simple state management across components
|
63
|
+
- **Server-Side Rendering**: Optimized SSR with hydration
|
64
|
+
- **Database Integration**: Support for MongoDB, MySQL, and PostgreSQL
|
65
|
+
- **Authentication**: Built-in JWT authentication system
|
66
|
+
- **API Routing**: Express-based file system routing
|
67
|
+
- **TypeScript Support**: Full type definitions included
|
68
|
+
- **Interactive CLI**: Powerful tools for project scaffolding and component creation
|
172
69
|
|
173
|
-
|
70
|
+
## Client-side Features
|
174
71
|
|
175
|
-
|
72
|
+
### Component Development
|
176
73
|
|
177
74
|
```jsx
|
178
75
|
import { useState, useEffect } from 'frontend-hamroun';
|
@@ -188,81 +85,22 @@ function Counter() {
|
|
188
85
|
return (
|
189
86
|
<div className="counter">
|
190
87
|
<h2>Counter: {count}</h2>
|
191
|
-
<
|
192
|
-
|
193
|
-
<button onClick={() => setCount(count - 1)}>-</button>
|
194
|
-
</div>
|
88
|
+
<button onClick={() => setCount(count + 1)}>+</button>
|
89
|
+
<button onClick={() => setCount(count - 1)}>-</button>
|
195
90
|
</div>
|
196
91
|
);
|
197
92
|
}
|
198
93
|
```
|
199
94
|
|
200
|
-
|
201
|
-
<summary><b>🔍 View Hooks API Reference</b></summary>
|
95
|
+
### Hooks API
|
202
96
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
setCount(count + 1); // Direct update
|
209
|
-
setCount(prev => prev + 1); // Functional update
|
210
|
-
```
|
97
|
+
- **useState**: Manage component state
|
98
|
+
- **useEffect**: Handle side effects
|
99
|
+
- **useMemo**: Memoize expensive calculations
|
100
|
+
- **useRef**: Reference DOM elements and persist values
|
101
|
+
- **useErrorBoundary**: Create error boundaries
|
211
102
|
|
212
|
-
|
213
|
-
```jsx
|
214
|
-
useEffect(() => {
|
215
|
-
// Effect logic
|
216
|
-
const subscription = api.subscribe();
|
217
|
-
|
218
|
-
return () => {
|
219
|
-
// Cleanup logic
|
220
|
-
subscription.unsubscribe();
|
221
|
-
};
|
222
|
-
}, [dependency]); // Dependency array
|
223
|
-
```
|
224
|
-
|
225
|
-
#### 🔄 useMemo
|
226
|
-
```jsx
|
227
|
-
const expensiveValue = useMemo(() => {
|
228
|
-
return computeExpensiveValue(a, b);
|
229
|
-
}, [a, b]); // Recomputes only when a or b changes
|
230
|
-
```
|
231
|
-
|
232
|
-
#### 🔄 useRef
|
233
|
-
```jsx
|
234
|
-
const inputRef = useRef(null);
|
235
|
-
|
236
|
-
// Access the DOM element directly
|
237
|
-
useEffect(() => {
|
238
|
-
inputRef.current.focus();
|
239
|
-
}, []);
|
240
|
-
|
241
|
-
return <input ref={inputRef} />;
|
242
|
-
```
|
243
|
-
|
244
|
-
#### 🔄 useErrorBoundary
|
245
|
-
```jsx
|
246
|
-
const [error, resetError] = useErrorBoundary();
|
247
|
-
|
248
|
-
if (error) {
|
249
|
-
return (
|
250
|
-
<div className="error-boundary">
|
251
|
-
<h2>Something went wrong</h2>
|
252
|
-
<p>{error.message}</p>
|
253
|
-
<button onClick={resetError}>Try again</button>
|
254
|
-
</div>
|
255
|
-
);
|
256
|
-
}
|
257
|
-
```
|
258
|
-
|
259
|
-
</details>
|
260
|
-
|
261
|
-
### 🔄 Context API
|
262
|
-
|
263
|
-
Share state across your component tree:
|
264
|
-
|
265
|
-
<div class="code-with-diagram" style="display: flex; align-items: flex-start; gap: 20px;">
|
103
|
+
### Context API
|
266
104
|
|
267
105
|
```jsx
|
268
106
|
// Create context
|
@@ -276,9 +114,7 @@ function App() {
|
|
276
114
|
<ThemeContext.Provider value={theme}>
|
277
115
|
<Header />
|
278
116
|
<Main />
|
279
|
-
<button onClick={() => setTheme(
|
280
|
-
theme === 'light' ? 'dark' : 'light'
|
281
|
-
)}>
|
117
|
+
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
|
282
118
|
Toggle theme
|
283
119
|
</button>
|
284
120
|
</ThemeContext.Provider>
|
@@ -288,35 +124,11 @@ function App() {
|
|
288
124
|
// Consumer
|
289
125
|
function Header() {
|
290
126
|
const theme = useContext(ThemeContext);
|
291
|
-
return
|
292
|
-
<header className={theme}>
|
293
|
-
<h1>My App</h1>
|
294
|
-
</header>
|
295
|
-
);
|
127
|
+
return <header className={theme}><h1>My App</h1></header>;
|
296
128
|
}
|
297
129
|
```
|
298
130
|
|
299
|
-
|
300
|
-
<strong>Context Flow Diagram</strong><br>
|
301
|
-
<pre style="background: #f0f0f0; padding: 10px; margin-top: 10px; border-radius: 5px;">
|
302
|
-
App (Provider)
|
303
|
-
│
|
304
|
-
├─► Header (Consumer)
|
305
|
-
│ Uses theme value
|
306
|
-
│
|
307
|
-
├─► Main
|
308
|
-
│ │
|
309
|
-
│ └─► Article (Consumer)
|
310
|
-
│ Uses theme value
|
311
|
-
│
|
312
|
-
└─► Footer (Consumer)
|
313
|
-
Uses theme value
|
314
|
-
</pre>
|
315
|
-
</div>
|
316
|
-
|
317
|
-
</div>
|
318
|
-
|
319
|
-
## 🖥️ Server-Side Features
|
131
|
+
## Server-Side Features
|
320
132
|
|
321
133
|
### Express Server Integration
|
322
134
|
|
@@ -342,18 +154,8 @@ await app.start();
|
|
342
154
|
console.log('Server running at http://localhost:3000');
|
343
155
|
```
|
344
156
|
|
345
|
-
<div align="center">
|
346
|
-
<img src="https://via.placeholder.com/600x300?text=Server+Architecture+Diagram" alt="Server Architecture" width="600" style="border-radius: 8px;"/>
|
347
|
-
</div>
|
348
|
-
|
349
157
|
### API Routes
|
350
158
|
|
351
|
-
Create API endpoints easily with file-based routing:
|
352
|
-
|
353
|
-
<div class="file-structure" style="display: flex; gap: 20px;">
|
354
|
-
|
355
|
-
<div class="code-example" style="flex: 1;">
|
356
|
-
|
357
159
|
```js
|
358
160
|
// api/users.js - Automatically mapped to /api/users
|
359
161
|
export async function get(req, res) {
|
@@ -365,179 +167,18 @@ export async function post(req, res) {
|
|
365
167
|
const { name, email } = req.body;
|
366
168
|
|
367
169
|
if (!name || !email) {
|
368
|
-
return res.status(400).json({
|
369
|
-
error: 'Name and email are required'
|
370
|
-
});
|
170
|
+
return res.status(400).json({ error: 'Name and email are required' });
|
371
171
|
}
|
372
172
|
|
373
|
-
const result = await req.db.collection('users').insertOne({
|
374
|
-
name,
|
375
|
-
email
|
376
|
-
});
|
377
|
-
|
173
|
+
const result = await req.db.collection('users').insertOne({ name, email });
|
378
174
|
res.status(201).json(result);
|
379
175
|
}
|
380
176
|
```
|
381
177
|
|
382
|
-
|
383
|
-
|
384
|
-
<div class="file-structure-diagram" style="background: #f8f9fa; border-radius: 8px; padding: 15px; min-width: 250px;">
|
385
|
-
<strong>File-based Routing</strong><br>
|
386
|
-
<pre style="background: #f0f0f0; padding: 10px; margin-top: 10px; border-radius: 5px;">
|
387
|
-
api/
|
388
|
-
├── users.js
|
389
|
-
│ ├── get() → GET /api/users
|
390
|
-
│ └── post() → POST /api/users
|
391
|
-
├── posts/
|
392
|
-
│ ├── index.js
|
393
|
-
│ │ └── get() → GET /api/posts
|
394
|
-
│ └── [id].js
|
395
|
-
│ └── get() → GET /api/posts/:id
|
396
|
-
└── auth/
|
397
|
-
├── login.js
|
398
|
-
│ └── post() → POST /api/auth/login
|
399
|
-
└── register.js
|
400
|
-
└── post() → POST /api/auth/register
|
401
|
-
</pre>
|
402
|
-
</div>
|
403
|
-
|
404
|
-
</div>
|
405
|
-
|
406
|
-
<details>
|
407
|
-
<summary><b>🔍 View Database Integration Examples</b></summary>
|
408
|
-
|
409
|
-
### 💾 Database Integration
|
410
|
-
|
411
|
-
Access your database directly in API routes:
|
412
|
-
|
413
|
-
<div class="tabs">
|
414
|
-
<div class="tab" id="mongodb">
|
415
|
-
|
416
|
-
#### MongoDB Example
|
417
|
-
|
418
|
-
```js
|
419
|
-
// MongoDB example
|
420
|
-
export async function get(req, res) {
|
421
|
-
const { id } = req.params;
|
422
|
-
const user = await req.db.collection('users').findOne({
|
423
|
-
_id: new ObjectId(id)
|
424
|
-
});
|
425
|
-
|
426
|
-
if (!user) {
|
427
|
-
return res.status(404).json({ error: 'User not found' });
|
428
|
-
}
|
429
|
-
|
430
|
-
res.json(user);
|
431
|
-
}
|
432
|
-
```
|
433
|
-
|
434
|
-
</div>
|
435
|
-
<div class="tab" id="mysql">
|
436
|
-
|
437
|
-
#### MySQL Example
|
438
|
-
|
439
|
-
```js
|
440
|
-
// MySQL example
|
441
|
-
export async function get(req, res) {
|
442
|
-
const [users] = await req.db.execute(
|
443
|
-
'SELECT * FROM users WHERE active = ?',
|
444
|
-
[true]
|
445
|
-
);
|
446
|
-
res.json(users);
|
447
|
-
}
|
448
|
-
```
|
449
|
-
|
450
|
-
</div>
|
451
|
-
<div class="tab" id="postgres">
|
452
|
-
|
453
|
-
#### PostgreSQL Example
|
454
|
-
|
455
|
-
```js
|
456
|
-
// PostgreSQL example
|
457
|
-
export async function get(req, res) {
|
458
|
-
const result = await req.db.query(
|
459
|
-
'SELECT * FROM users WHERE role = $1',
|
460
|
-
['admin']
|
461
|
-
);
|
462
|
-
res.json(result.rows);
|
463
|
-
}
|
464
|
-
```
|
465
|
-
|
466
|
-
</div>
|
467
|
-
</div>
|
468
|
-
|
469
|
-
</details>
|
470
|
-
|
471
|
-
<details>
|
472
|
-
<summary><b>🔍 View Authentication Example</b></summary>
|
473
|
-
|
474
|
-
### 🔐 Authentication
|
475
|
-
|
476
|
-
Built-in JWT authentication:
|
477
|
-
|
478
|
-
```js
|
479
|
-
// api/auth/login.js
|
480
|
-
export async function post(req, res) {
|
481
|
-
const { username, password } = req.body;
|
482
|
-
const user = await req.db.collection('users').findOne({ username });
|
483
|
-
|
484
|
-
if (!user || !await req.auth.comparePasswords(password, user.password)) {
|
485
|
-
return res.status(401).json({ error: 'Invalid credentials' });
|
486
|
-
}
|
487
|
-
|
488
|
-
const token = req.auth.generateToken(user);
|
489
|
-
res.json({
|
490
|
-
token,
|
491
|
-
user: { id: user._id, username: user.username }
|
492
|
-
});
|
493
|
-
}
|
494
|
-
|
495
|
-
// Protected route
|
496
|
-
// api/profile.js
|
497
|
-
export async function get(req, res) {
|
498
|
-
// req.auth.requireAuth middleware automatically added
|
499
|
-
// req.user contains the authenticated user
|
500
|
-
res.json(req.user);
|
501
|
-
}
|
502
|
-
```
|
503
|
-
|
504
|
-
</details>
|
505
|
-
|
506
|
-
<details>
|
507
|
-
<summary><b>🔍 View Middleware Example</b></summary>
|
508
|
-
|
509
|
-
### Middleware Support
|
510
|
-
|
511
|
-
Add custom middleware to your routes:
|
512
|
-
|
513
|
-
```js
|
514
|
-
// middleware/logger.js
|
515
|
-
export default function logger(req, res, next) {
|
516
|
-
console.log(`${req.method} ${req.path}`);
|
517
|
-
next();
|
518
|
-
}
|
519
|
-
|
520
|
-
// server.js
|
521
|
-
import logger from './middleware/logger';
|
522
|
-
|
523
|
-
const app = await server.createServer({
|
524
|
-
// ...other options
|
525
|
-
middleware: [logger]
|
526
|
-
});
|
527
|
-
```
|
528
|
-
|
529
|
-
</details>
|
530
|
-
|
531
|
-
## 🌐 Server-Side Rendering
|
532
|
-
|
533
|
-
Frontend Hamroun provides seamless SSR with hydration:
|
534
|
-
|
535
|
-
<div class="ssr-diagram-container" style="display: flex; gap: 20px; margin-bottom: 20px;">
|
536
|
-
|
537
|
-
<div class="code-example" style="flex: 1;">
|
178
|
+
## Server-Side Rendering
|
538
179
|
|
539
180
|
```jsx
|
540
|
-
//
|
181
|
+
// Server-side
|
541
182
|
import { renderToString } from 'frontend-hamroun/ssr';
|
542
183
|
import App from './App';
|
543
184
|
|
@@ -559,47 +200,17 @@ app.get('*', async (req, res) => {
|
|
559
200
|
`);
|
560
201
|
});
|
561
202
|
|
562
|
-
//
|
203
|
+
// Client-side
|
563
204
|
import { hydrate } from 'frontend-hamroun';
|
564
205
|
import App from './App';
|
565
206
|
|
566
|
-
hydrate(<App url={window.location.pathname} />,
|
567
|
-
document.getElementById('root'));
|
207
|
+
hydrate(<App url={window.location.pathname} />, document.getElementById('root'));
|
568
208
|
```
|
569
209
|
|
570
|
-
|
571
|
-
|
572
|
-
<div class="ssr-flow-diagram" style="background: #f8f9fa; border-radius: 8px; padding: 15px; min-width: 250px;">
|
573
|
-
<strong>SSR Flow</strong><br>
|
574
|
-
<pre style="background: #f0f0f0; padding: 10px; margin-top: 10px; border-radius: 5px;">
|
575
|
-
1. HTTP Request
|
576
|
-
↓
|
577
|
-
2. Server renders React to HTML
|
578
|
-
↓
|
579
|
-
3. HTML sent to browser
|
580
|
-
↓
|
581
|
-
4. Browser displays HTML
|
582
|
-
↓
|
583
|
-
5. JavaScript loads
|
584
|
-
↓
|
585
|
-
6. Hydration attaches event
|
586
|
-
handlers to existing DOM
|
587
|
-
↓
|
588
|
-
7. App becomes interactive
|
589
|
-
</pre>
|
590
|
-
</div>
|
591
|
-
|
592
|
-
</div>
|
593
|
-
|
594
|
-
<div align="center">
|
595
|
-
<img src="https://via.placeholder.com/700x200?text=SSR+vs+CSR+Performance+Comparison" alt="SSR Performance" width="700" style="border-radius: 8px;"/>
|
596
|
-
</div>
|
597
|
-
|
598
|
-
## ⚡ Performance Optimization
|
210
|
+
## Performance Features
|
599
211
|
|
600
212
|
### Batch Updates
|
601
|
-
|
602
|
-
Group state updates for better performance:
|
213
|
+
Group multiple state updates together to prevent unnecessary re-renders:
|
603
214
|
|
604
215
|
```jsx
|
605
216
|
import { batchUpdates } from 'frontend-hamroun';
|
@@ -614,121 +225,33 @@ function handleSubmit() {
|
|
614
225
|
}
|
615
226
|
```
|
616
227
|
|
617
|
-
|
618
|
-
|
619
|
-
The framework uses an efficient diffing algorithm to minimize DOM operations:
|
620
|
-
|
621
|
-
<div class="diffing-container" style="display: flex; gap: 20px; margin-bottom: 20px;">
|
622
|
-
|
623
|
-
<div class="code-example" style="flex: 1;">
|
624
|
-
|
625
|
-
```jsx
|
626
|
-
// This only updates the changed parts of the DOM
|
627
|
-
function Counter() {
|
628
|
-
const [count, setCount] = useState(0);
|
629
|
-
return (
|
630
|
-
<div>
|
631
|
-
<h1>Counter</h1>
|
632
|
-
<p>Count: {count}</p> {/* Only this text node updates */}
|
633
|
-
<button onClick={() => setCount(count + 1)}>
|
634
|
-
Increment
|
635
|
-
</button>
|
636
|
-
</div>
|
637
|
-
);
|
638
|
-
}
|
639
|
-
```
|
640
|
-
|
641
|
-
</div>
|
642
|
-
|
643
|
-
<div class="diffing-diagram" style="background: #f8f9fa; border-radius: 8px; padding: 15px; min-width: 250px;">
|
644
|
-
<strong>Diffing Process</strong><br>
|
645
|
-
<pre style="background: #f0f0f0; padding: 10px; margin-top: 10px; border-radius: 5px;">
|
646
|
-
Old Virtual DOM
|
647
|
-
↓
|
648
|
-
New Virtual DOM
|
649
|
-
↓
|
650
|
-
Compare Trees
|
651
|
-
↓
|
652
|
-
Identify Differences
|
653
|
-
↓
|
654
|
-
Update Only Changed
|
655
|
-
DOM Elements
|
656
|
-
</pre>
|
657
|
-
</div>
|
658
|
-
|
659
|
-
</div>
|
660
|
-
|
661
|
-
<div align="center">
|
662
|
-
<img src="https://via.placeholder.com/700x200?text=Performance+Benchmark+Graph" alt="Performance Benchmark" width="700" style="border-radius: 8px;"/>
|
663
|
-
</div>
|
664
|
-
|
665
|
-
## 🛠️ CLI Tools
|
228
|
+
## CLI Tools
|
666
229
|
|
667
230
|
Frontend Hamroun includes powerful CLI tools for development:
|
668
231
|
|
669
|
-
<div class="cli-examples" style="background: #f8f9fa; border-radius: 8px; padding: 20px; margin-bottom: 20px;">
|
670
|
-
|
671
232
|
```bash
|
672
|
-
# Create a new project
|
233
|
+
# Create a new project
|
673
234
|
npx frontend-hamroun create my-app
|
674
235
|
|
675
|
-
# Generate a new component
|
236
|
+
# Generate a new component
|
676
237
|
npx frontend-hamroun add:component Button
|
677
238
|
|
678
|
-
# Create a new page
|
239
|
+
# Create a new page
|
679
240
|
npx frontend-hamroun add:page Home
|
680
241
|
|
681
242
|
# Generate an API route
|
682
243
|
npx frontend-hamroun add:api users --methods=get,post,put,delete
|
683
|
-
|
684
|
-
# View development tools and tips
|
685
|
-
npx frontend-hamroun dev:tools
|
686
244
|
```
|
687
245
|
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
<ul>
|
698
|
-
<li>Quick setup</li>
|
699
|
-
<li>No build step in development</li>
|
700
|
-
<li>Focused on simplicity</li>
|
701
|
-
<li>Perfect for learning</li>
|
702
|
-
</ul>
|
703
|
-
</div>
|
704
|
-
|
705
|
-
<div class="template-card" style="background: #f0fff4; border-radius: 8px; padding: 15px; min-width: 250px; border-left: 5px solid #34a853;">
|
706
|
-
<h3>🌐 SSR Template</h3>
|
707
|
-
<p>Server-side rendering with hydration</p>
|
708
|
-
<ul>
|
709
|
-
<li>SEO-friendly</li>
|
710
|
-
<li>Fast initial load</li>
|
711
|
-
<li>Express server included</li>
|
712
|
-
<li>Optimized for content sites</li>
|
713
|
-
</ul>
|
714
|
-
</div>
|
715
|
-
|
716
|
-
<div class="template-card" style="background: #fff8e1; border-radius: 8px; padding: 15px; min-width: 250px; border-left: 5px solid #fbbc04;">
|
717
|
-
<h3>⚡ Fullstack App</h3>
|
718
|
-
<p>Complete solution with API, authentication, and database</p>
|
719
|
-
<ul>
|
720
|
-
<li>API routes included</li>
|
721
|
-
<li>Database integration</li>
|
722
|
-
<li>Authentication ready</li>
|
723
|
-
<li>Production-ready setup</li>
|
724
|
-
</ul>
|
725
|
-
</div>
|
726
|
-
|
727
|
-
</div>
|
728
|
-
|
729
|
-
## 📘 TypeScript Support
|
730
|
-
|
731
|
-
Frontend Hamroun is built with TypeScript and includes full type definitions:
|
246
|
+
## Project Templates
|
247
|
+
|
248
|
+
Choose from multiple project templates:
|
249
|
+
|
250
|
+
1. **Basic App**: Client-side SPA with essential features
|
251
|
+
2. **SSR Template**: Server-side rendering with hydration
|
252
|
+
3. **Fullstack App**: Complete solution with API, authentication, and database
|
253
|
+
|
254
|
+
## TypeScript Support
|
732
255
|
|
733
256
|
```tsx
|
734
257
|
import { useState } from 'frontend-hamroun';
|
@@ -754,67 +277,14 @@ function UserProfile({ id, name, email }: UserProps) {
|
|
754
277
|
}
|
755
278
|
```
|
756
279
|
|
757
|
-
##
|
758
|
-
|
759
|
-
Frontend Hamroun works in all modern browsers
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
<div>Firefox</div>
|
769
|
-
<div>Latest 2 versions</div>
|
770
|
-
</div>
|
771
|
-
<div style="text-align: center; padding: 10px;">
|
772
|
-
<div style="font-size: 2em;">🧭</div>
|
773
|
-
<div>Safari</div>
|
774
|
-
<div>Latest 2 versions</div>
|
775
|
-
</div>
|
776
|
-
<div style="text-align: center; padding: 10px;">
|
777
|
-
<div style="font-size: 2em;">🌐</div>
|
778
|
-
<div>Edge</div>
|
779
|
-
<div>Latest 2 versions</div>
|
780
|
-
</div>
|
781
|
-
<div style="text-align: center; padding: 10px;">
|
782
|
-
<div style="font-size: 2em;">🏛️</div>
|
783
|
-
<div>IE11</div>
|
784
|
-
<div>With polyfills</div>
|
785
|
-
</div>
|
786
|
-
</div>
|
787
|
-
|
788
|
-
## 👥 Contributing
|
789
|
-
|
790
|
-
Contributions are welcome! See [CONTRIBUTING.md](./docs/CONTRIBUTING.md) for details.
|
791
|
-
|
792
|
-
<div class="contribution-workflow" style="background: #f8f9fa; border-radius: 8px; padding: 20px; margin: 20px 0;">
|
793
|
-
<h3>Contribution Workflow</h3>
|
794
|
-
<ol>
|
795
|
-
<li>Fork the repository</li>
|
796
|
-
<li>Create your feature branch: <code>git checkout -b feature/amazing-feature</code></li>
|
797
|
-
<li>Commit your changes: <code>git commit -m 'Add amazing feature'</code></li>
|
798
|
-
<li>Push to the branch: <code>git push origin feature/amazing-feature</code></li>
|
799
|
-
<li>Open a Pull Request</li>
|
800
|
-
</ol>
|
801
|
-
</div>
|
802
|
-
|
803
|
-
## 📚 Documentation
|
804
|
-
|
805
|
-
For complete documentation, visit [our documentation site](https://github.com/hamroun/frontend-hamroun).
|
806
|
-
|
807
|
-
<div align="center">
|
808
|
-
|
809
|
-
<div style="margin-top: 40px;">
|
810
|
-
<h3>💖 Support the Project</h3>
|
811
|
-
|
812
|
-
[](https://github.com/sponsors/hamroun)
|
813
|
-
[](https://github.com/hamroun/frontend-hamroun)
|
814
|
-
</div>
|
815
|
-
|
816
|
-
<div style="margin-top: 30px;">
|
817
|
-
<p>MIT © Hamroun</p>
|
818
|
-
</div>
|
819
|
-
|
820
|
-
</div>
|
280
|
+
## Browser Compatibility
|
281
|
+
|
282
|
+
Frontend Hamroun works in all modern browsers (Chrome, Firefox, Safari, Edge) and in IE11 with appropriate polyfills.
|
283
|
+
|
284
|
+
## Documentation
|
285
|
+
|
286
|
+
For complete documentation, visit our [GitHub repository](https://github.com/hamroun/frontend-hamroun).
|
287
|
+
|
288
|
+
## License
|
289
|
+
|
290
|
+
MIT © Hamroun
|