תחביר וצורת כתיבה
הגדרת הפרויקט: ES Modules
הקורס כותב import ו-export (ES Modules), התקן המודרני של JavaScript. כדי ש-Node.js יקרא כך את הקבצים, מוסיפים שורה אחת ל-package.json:
{
"name": "my-server",
"type": "module",
"dependencies": {
"express": "^5.1.0"
}
}
בקוד ישן תפגשו את הסגנון הקודם, CommonJS: const express = require('express') ו-module.exports. הוא עדיין עובד, אבל בפרויקט חדש כדאי ES Modules. שני הבדלים שכדאי לזכור:
- בייבוא קובץ מקומי כותבים את הסיומת:
import router from './routes/users.js'. - אין
__dirname. במקומו ישimport.meta.dirname(Node.js 20.11 ומעלה).
מבנה בסיסי של אפליקציית Express
כל אפליקציית Express מתחילה באותו מבנה:
// First
// ==============================================
// 1. ייבוא התלויות (Imports)
// ==============================================
import express from 'express';
// ==============================================
// 2. יצירת האפליקציה
// ==============================================
const app = express();
// ==============================================
// 3. הגדרות (Configuration)
// ==============================================
const PORT = 3000;
// ==============================================
// 4. Middleware גלובלי
// ==============================================
app.use(express.json());
// ==============================================
// 5. הגדרת Routes
// ==============================================
app.get('/', (req, res) => {
res.send('שלום עולם!');
});
// ==============================================
// 6. הפעלת השרת
// ==============================================
app.listen(PORT, () => {
console.log(`השרת רץ בפורט ${PORT}`);
});
תבניות כתיבה נפוצות
1. הגדרת Route בסיסי
// Template: app.METHOD(PATH, HANDLER)
// הצורה הכי נפוצה - Arrow Function
app.get('/users', (req, res) => {
res.json({ users: [] });
});
// אפשר גם עם function רגיל
app.get('/users', function(req, res) {
res.json({ users: [] });
});
2. Route עם פרמטרים
// One פרמטר
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.send(`משתמש: ${userId}`);
});
// מספר פרמטרים
app.get('/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = req.params;
res.json({ userId, postId });
});
// פרמטר אופציונלי: בסוגריים מסולסלים (Express 5)
// ב-Express 4 כתבו '/users/:id?' - התחביר הזה כבר לא עובד
app.get('/users{/:id}', (req, res) => {
if (req.params.id) {
res.send(`משתמש ספציפי: ${req.params.id}`);
} else {
res.send('כל המשתמשים');
}
});
3. שימוש ב-Query String
// URL: /search?q=express&page=1
app.get('/search', (req, res) => {
const { q, page } = req.query;
res.json({
searchTerm: q, // 'express'
currentPage: page // '1'
});
});
4. קבלת נתונים מ-Body
// Must use middleware לפרסור JSON
app.use(express.json());
app.post('/users', (req, res) => {
const { name, email } = req.body;
// יצירת משתמש חדש
const newUser = {
id: Date.now(),
name,
email
};
res.status(201).json(newUser);
});
סגנונות כתיבה
סגנון 1: Inline Handlers (מתאים לפרויקטים קטנים)
// כל הלוגיקה ישירות ב-route
app.get('/users', (req, res) => {
const users = [
{ id: 1, name: 'יוסי' },
{ id: 2, name: 'דני' }
];
res.json(users);
});
סגנון 2: פונקציות נפרדות (Controllers)
// הפרדה של הלוגיקה לפונקציות
const getUsers = (req, res) => {
res.json({ users: [] });
};
const getUserById = (req, res) => {
res.json({ user: { id: req.params.id } });
};
const createUser = (req, res) => {
res.status(201).json({ user: req.body });
};
// רישום ה-routes
app.get('/users', getUsers);
app.get('/users/:id', getUserById);
app.post('/users', createUser);
סגנון 3: Route Chaining
// שרשור routes לאותו נתיב
app.route('/users')
.get((req, res) => {
res.json({ action: 'Get all users' });
})
.post((req, res) => {
res.json({ action: 'Create user' });
});
app.route('/users/:id')
.get((req, res) => {
res.json({ action: 'Get user by ID' });
})
.put((req, res) => {
res.json({ action: 'Update user' });
})
.delete((req, res) => {
res.json({ action: 'Delete user' });
});
שליחת סוגי תשובות שונים
טקסט רגיל
app.get('/text', (req, res) => {
res.send('זהו טקסט רגיל');
});
JSON
app.get('/json', (req, res) => {
res.json({
message: 'הצלחה',
data: { id: 1, name: 'Test' }
});
});
HTML
app.get('/html', (req, res) => {
res.send('<h1>כותרת HTML</h1><p>פסקה</p>');
});
קובץ
app.get('/file', (req, res) => {
res.sendFile('/path/to/file.pdf');
});
הורדת קובץ
app.get('/download', (req, res) => {
res.download('/path/to/file.pdf', 'document.pdf');
});
הפניה (Redirect)
app.get('/old-page', (req, res) => {
res.redirect('/new-page');
});
// עם קוד סטטוס ספציפי
app.get('/moved', (req, res) => {
res.redirect(301, '/new-location');
});
קודי סטטוס HTTP
הגדרת קוד סטטוס לפני התשובה:
// הצלחה
res.status(200).json({ message: 'OK' });
// נוצר בהצלחה
res.status(201).json({ message: 'Created' });
// אין תוכן להחזיר
res.status(204).send();
// בקשה שגויה
res.status(400).json({ error: 'Bad Request' });
// לא מורשה
res.status(401).json({ error: 'Unauthorized' });
// אסור
res.status(403).json({ error: 'Forbidden' });
// לא נמצא
res.status(404).json({ error: 'Not Found' });
// שגיאת שרת
res.status(500).json({ error: 'Internal Server Error' });
קודים נפוצים:
| קוד | משמעות | שימוש |
|---|---|---|
| 200 | OK | בקשה הצליחה |
| 201 | Created | משאב נוצר |
| 204 | No Content | הצלחה ללא תוכן |
| 400 | Bad Request | נתונים שגויים |
| 401 | Unauthorized | נדרשת הזדהות |
| 403 | Forbidden | אין הרשאה |
| 404 | Not Found | לא נמצא |
| 500 | Server Error | שגיאת שרת |
הגדרות (app.set)
// Set view engine
app.set('view engine', 'ejs');
// Set views directory
app.set('views', './views');
// הגדרת פורט
app.set('port', process.env.PORT || 3000);
// קריאת הגדרה
const port = app.get('port');
מבנה תיקיות מומלץ
פרויקט קטן:
project/
├── server.js # קובץ ראשי
├── package.json
└── public/ # קבצים סטטיים
├── css/
├── js/
└── images/
פרויקט בינוני-גדול:
project/
├── src/
│ ├── app.js # הגדרת האפליקציה
│ ├── server.js # הפעלת השרת
│ ├── routes/ # הגדרת routes
│ │ ├── index.js
│ │ ├── users.js
│ │ └── products.js
│ ├── controllers/ # לוגיקה עסקית
│ │ ├── userController.js
│ │ └── productController.js
│ ├── middleware/ # middleware מותאם
│ │ ├── auth.js
│ │ └── validation.js
│ └── config/ # קבצי הגדרות
│ └── database.js
├── public/ # קבצים סטטיים
├── views/ # תבניות HTML
├── package.json
└── .env # משתני סביבה
Best Practices (שיטות עבודה מומלצות)
1. השתמשו ב-ES Modules וב-const
// ✅ מודרני: import, ו-const לכל מה שלא משתנה
import express from 'express';
const app = express();
// ❌ סגנון ישן: CommonJS ו-var
var express = require('express');
2. טפלו בשגיאות
ב-Express 5, שגיאה בתוך פונקציה אסינכרונית (או Promise שנדחה) מגיעה לבד ל-Middleware של השגיאות. עדיין כדאי לתפוס שגיאות צפויות במקום, כדי להחזיר תשובה ברורה:
// ✅ טוב
app.get('/users/:id', async (req, res) => {
try {
const user = await findUser(req.params.id);
res.json(user);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
3. השתמשו ב-async/await
// ✅ Modern and clean
app.get('/data', async (req, res) => {
const data = await fetchData();
res.json(data);
});
// ❌ פחות קריא
app.get('/data', (req, res) => {
fetchData()
.then(data => res.json(data))
.catch(err => res.status(500).json(err));
});
4. הפרד לוגיקה לקבצים
// routes/users.js
import express from 'express';
const router = express.Router();
router.get('/', getUsers);
router.post('/', createUser);
export default router;
// app.js
import userRoutes from './routes/users.js';
app.use('/users', userRoutes);
5. השתמשו במשתני סביבה
// ✅ Good
const PORT = process.env.PORT || 3000;
// ❌ Bad
const PORT = 3000; // קשיח
סיכום - תבנית מלאה
// ===== server.js =====
import express from 'express';
const app = express();
// === Middleware ===
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));
// === Routes ===
app.get('/', (req, res) => {
res.json({ message: 'ברוכים הבאים!' });
});
app.get('/api/users', (req, res) => {
res.json({ users: [] });
});
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
res.status(201).json({ id: 1, name, email });
});
// === Error Handler ===
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'שגיאה בשרת' });
});
// === Start Server ===
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`🚀 השרת רץ: http://localhost:${PORT}`);
});
← חזרה ליסודות | המשך לניתוב →
בדקו את עצמכם
נסו לענות לבד לפני שאתם פותחים את התשובה.
-
מה צריך להוסיף ל-package.json כדי לכתוב
import express from 'express'?הצגת התשובה
תשובה א. כך Node.js מבין את הקבצים כ-ES Modules.
-
למה לקחת את הפורט מ-
process.env.PORT?הצגת התשובה
תשובה א. פורט קבוע בקוד לא יעבוד בפרודקשן.