| کانال توسعهدهندگان وب |
前往频道在 Telegram
⭕️ کانال توسعهدهندگان وب دولوپیکس 💠 دولوپیکس | جامعه توسعهدهندگان ایرانی 💎 @Developix 🚀 Developix.ir 📌 پشتیبانی و تبلیغات: @DevelopixSupport
显示更多3 020
订阅者
-424 小时
-177 天
-1830 天
帖子存档
\n\n\n\n\n\n\nبرخلاف async، ترتیب اجرای اسکریپتها با defer حفظ میشود، که برای بیشتر پروژههای Web امنتر و قابلپیشبینیتر است. 🌱\n\nمرجع بیشتر: MDN – 











🔥 پروژه: ریمیکس؛ فریمورک فولاستک وب
برای ساخت اپلیکیشن وب، ریمیکس رویکرد فولاستک را با تکیه بر استانداردهای خود وب دنبال میکند؛ گزینهای برای وقتی که رابط کاربری و منطق سرور باید کنار هم طراحی شوند.
تمرکز روی درخواست و پاسخ HTTP، فرمها و کار با داده در سمت سرور، آن را برای توسعهدهندههایی جذاب میکند که میخواهند بهجای چسباندن چند ابزار جدا، مسیر یکپارچهتری داشته باشند.
برای آشنایی با مسیر فعلی توسعه و نمونههای پروژه، مخزن ریمیکس را ببین؛ ارزش بررسی دارد.
⭐️ 33,405 ستاره
🔖 #Web #وب #Frontend #Backend #Remix
💎 @DevelopixWeb
پیکربندی وبسرور آپاچی و مدیریت فایل htaccess.
در این مطلب به نحوه پیکربندی وبسرور Apache، مدیریت خطاهای HTTP، ماژول mod_rewrite و کاربردهای عملی بازنویسی آدرسها (URL Rewriting) پرداخته شده است.
برای مطالعه کامل این مطلب میتوانید به لینک زیر مراجعه کنید:
https://gnutec.net/apache-http-web-server-htaccess/
🔖 #Web #وب #Frontend #Backend
👤 ابوالفضل
💎 Channel: @DevelopixWeb
+1
چرا قبل از تموم شدن ذخیرهها، پیام موفقیت میبینی؟
توی کد اول، گذاشتن
async داخل forEach باعث نمیشه حلقه منتظر ذخیرهها بمونه. خودِ forEach هم Promise برنمیگردونه؛ پس اون await بیرونی عملاً منتظر عملیات ذخیرهسازی نمیمونه!
روش دوم رو برای ذخیرههای مستقل امتحان کن: با map، Promiseها رو جمع میکنیم و با Promise.all منتظر موفقیت همهشون میمونیم. اگه یکی رد بشه، تابع هم خطا میده و پیام موفقیت اجرا نمیشه؛ البته عملیات دیگه خودکار لغو نمیشن.
اگه ترتیب ذخیرهها مهمه، بهجای اجرای همزمان از حلقهٔ for...of و await استفاده کن.
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWebبرای پروژههایی که Redux برایشان زیادی سنگین است، کتابخانهٔ Zustand گزینهٔ خیلی تمیزی برای مدیریت state در React است ⚡️
ایدهاش ساده است: یک global store سبک، بدون Providerهای تو در تو، با API خیلی سرراست.
چند مزیت مهم:
✅ بدون boilerplate؛ فقط یک تابع برای ساختن store
✅ پشتیبانی عالی از TypeScript
✅ بدون re-render اضافی؛ فقط کامپوننتهای وابسته رندر میشوند
✅ سازگار با Server Components در پروژههای مدرن React / Next.js
نمونه استفاده ساده:
npm install zustand
import create from 'zustand'
const useStore = create((set) => ({
count: 0,
inc: () => set((s) => ({ count: s.count + 1 }))
}))
function Counter() {
const { count, inc } = useStore()
return <button onClick={inc}>Count: {count}</button>
}
برای پروژههایی که فقط یک state مدیریتپذیر، تمیز و قابل تست میخواهند، Zustand معمولا اندازهاش دقیقا همان چیزی است که نیاز میشود 🙂
لینکها:
GitHub
Docs
🔖 #Web #وب #Frontend #Backend #Zustand #React #State_Management #JavaScript #TypeScript #Frontend
👤 Developix
💎 Channel: @DevelopixWeb🍋 چرا برای پیامک سایتت هزینه اضافه بدی؟!
با لیمو اس ام اس شروع کار کاملاً رایگانه 👇
✅ ثبتنام رایگان و بدون پرداخت هزینه
🎁 شارژ اولیه رایگان بعد از ثبتنام
💚 پنل پیامکی رایگان
🔥 تعرفه پیامک از فقط ۱۰۶ تومان
🧩 افزونههای وردپرس کاملاً رایگان برای:
• دیجیتس
• پیامک ووکامرس
• پیامک دکان
• پیامک بوکلی
• پیامک گرویتی فرم
یعنی میتونی بدون پرداخت هزینه برای پنل و افزونه، پیامکهای سایتت رو راهاندازی کنی و فقط هزینه پیامک مصرفی رو پرداخت کنی.
🚀 مناسب برنامهنویسها، سایتهای وردپرسی و کسبوکارهای آنلاین
👉 همین الان رایگان ثبتنام کن:
https://panel.limosms.com
📞 اطلاعات بیشتر:
09108303821 | 09001200800
https://limosms.com
کتابخانه Zod برای TypeScript/JavaScript کمک میکند اسکیماهای داده را یکبار تعریف کنی و همزمان هم type بگیری، هم validation در زمان اجرا ✨
مشکل کلاسیک فرمها و APIها این است که typeها فقط در زمان کامپایل چک میشوند، ولی دیتای واقعی کاربر یا کلاینت ناشناخته است. Zod این فاصله بین TypeScript و دنیای واقعی را پر میکند.
چند نکته مهم:
• تعریف اسکیما و type از یک منبع واحد ➜ بدون دوبارهکاری 🧠
• مناسب برای APIها، فرمهای React، و Validation سمت سرور در Node.js
• ادغام عالی با کتابخانههایی مثل React Hook Form و tRPC
نمونه استفاده ساده:
npm install zod
import { z } from "zod";
const userSchema = z.object({
name: z.string().min(3),
age: z.number().int().nonnegative(),
});
const result = userSchema.safeParse({
name: "Ali",
age: 28,
});
if (!result.success) {
console.log(result.error.format());
}
مستندات رسمی:
GitHub
Docs
برای هر پروژه وب که ورودی کاربر یا JSON از بیرون میگیرد، امتحان Zod کلی خطای Runtime را کم میکند و کد را تمیزتر نگه میدارد 🚀
🔖 #Web #وب #Frontend #Backend #Zod #TypeScript #Validation #Web #Node_js
👤 Developix
💎 Channel: @DevelopixWeb🔥 پروژه: Angular برای وب اپهای مقیاسپذیر
فریمورک Angular برای تیمهایی که روی وباپهای بزرگ و جدی کار میکنند هنوز یکی از امنترین انتخابهاست 🚀
ساختار opinionated، TypeScript پیشفرض، DI قوی، routing و فرمها، تستنویسی و ابزارهای CLI یکپارچه باعث میشود از روز اول روی معماری و DX تمرکز کنی، نه سیمکشی دستی.
با قابلیتهایی مثل standalone components و SSR، هم performance و هم SEO پوشش داده میشود. اگر پروژه بعدیتان جدی است، حتما سری به ریپو Angular بزنید.
⭐️ 101,003 ستاره
🔖 #Web #وب #Frontend #Backend #Angular
💎 @DevelopixWeb
در اپهای وب مدرن، مخصوصاً فرمهای سرچ زنده، گاهی چندین درخواست fetch پشتسرهم ارسال میشود و پاسخهای قدیمیتر، نتیجه جدید را خراب میکند. راهحل تمیز و امروزی: استفاده از AbortController ✨
با این کار میتوان درخواست قبلی را قبل از کامل شدن، لغو کرد تا هم UI تمیز بماند، هم پهنایباند و منابع سرور هدر نرود.
const controller = new AbortController();
const { signal } = controller;
fetch("/api/search?q=test", { signal })
.then(res => res.json())
.then(data => {
console.log("result", data);
})
.catch(err => {
if (err.name === "AbortError") {
console.log("request cancelled");
} else {
console.error(err);
}
});
// هر وقت لازم بود:
controller.abort();
برای سرچهای لحظهای، میتوان در هر ورودی جدید، controller.abort() قبلی را صدا زد و بعد یک AbortController جدید ساخت.
این تکنیک کمک میکند Race Condition در پاسخها کمتر شود و تجربه کاربری سریعتر و قابلاعتمادتر به نظر برسد 🚀
مرجع: MDN - AbortController
🔖 #Web #وب #Frontend #Backend #AbortController #fetch #JavaScript #Web_API #frontend
👤 Developix
💎 Channel: @DevelopixWeb🎨 تم روشن/تاریک فقط با CSS Variables
خیلی وقتها برای پیادهسازی dark mode سریع میشه از CSS Custom Properties (همون CSS variables) استفاده کرد و بدون دست زدن به کلی selector، رنگ کل UI رو عوض کرد. ✨
ایده اینه که همه رنگها رو روی
:root تعریف بشه و بعد با اضافه کردن یک class به <html> یا <body>، تم عوض بشه. فقط یکبار style مینویسی و هرجا لازم بود از var(--color-name) استفاده میکنی. 🔁
:root {
--bg: #ffffff;
--text: #111111;
}
html.dark {
--bg: #111827;
--text: #f9fafb;
}
body {
background-color: var(--bg);
color: var(--text);
}
// JavaScript
const html = document.documentElement;
const toggleTheme = () => {
html.classList.toggle('dark');
};
با این روش، اضافهکردن stateهای جدید (مثل high-contrast) هم فقط یعنی تعریف چند متغیر جدید، نه refactor بزرگ روی کل CSS. 🔧
مرجع بیشتر در MDN 👇
Using CSS custom properties - MDN
🔖 #Web #وب #Frontend #Backend #CSS #dark_mode #CSS_variables #frontend #web
👤 Developix
💎 Channel: @DevelopixWebبا Migration Boost هاستایران، برای مهاجرت به سرور ابری دوباره هزینه ترافیک نده! 🚀
با خرید اولین سرور ابری غیرساعتی از **هاستایران**، بسته ترافیک هدیه مهاجرت بهصورت خودکار برای سرویس شما فعال میشود:
✅ حداقل ۱۰۰ گیگابایت ترافیک هدیه مهاجرت
✅ افزایش حجم هدیه متناسب با ظرفیت دیسک اولیه
✅ ترافیک آپلود رایگان
✅ بدون محدودیت زمانی
سرور ابری هاستایران را راهاندازی کنید و بکاپها، فایلها و پایگاه داده خود را بدون دغدغه هزینههای پنهان ترافیک منتقل کنید.
👇 مشاهده پلنهای سرور ابری هاستایران
hostiran.club/Migration
hostiran.club/Migration
+1
در نمونهکد بالا در روش اشتباه، در هر بار اجرا شدن
getServerSideProps یک کانکشن جدید به دیتابیس ساخته میشود و هرگز بسته یا دوباره استفاده نمیشود؛ این کار روی سرور واقعی (مثلاً در Next.js زیر بار ترافیک بالا) باعث Connection Exhaustion، افت شدید کارایی و حتی کرش شدن سرویس میشود.
در روش صحیح با استفاده از یک متغیر سراسری و کشکردن MongoClient (یا هر Driver دیگری)، در محیط development جلوی ساخت کانکشنهای تکراری بعد از هر Hot-Reload گرفته شده و در محیط production هم تنها یک بار به دیتابیس متصل میشویم و همه درخواستها از همان کانکشن/Pool استفاده میکنند.
به این ترتیب، هم مصرف منابع بهشدت کاهش پیدا میکند، هم زمان پاسخگویی API و صفحات server-side بهتر میشود و در عین حال ریسک Memory Leak و اشباع شدن کانکشنهای دیتابیس پایین میآید.
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb💠 نسخه جدید محیط توسعه Webstorm منتشر شده است
🔸 ارتقا از نسخه 2026.1.4 به 2026.2
🔖 #webstorm, #web, #react, #vue, #js, #release
💎 @DevelopixWeb
+1
در نمونهکد بالا هندل کردن خطا در Express بهصورت اشتباه انجام شده است؛ Middleware مربوط به خطا باید در انتهای زنجیره Routeها و سایر Middlewareها قرار بگیرد و امضای تابع آن هم باید چهار آرگومان
err، req، res و next را داشته باشد. با رعایت این الگو، خطاهای Async (مثلاً خطاهای Promise در درخواستهای پایگاهداده) بهدرستی لاگ و مدیریت شده و از ارسال پاسخهای ناقص یا Crash شدن ناگهانی سرور در محیط Production جلوگیری میشود.
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb🏆آفرهای جام جهانی ۲۰۲۶ هاستایران فعال شد!
با کمپین «ترکیب برنده سایتت»، زیرساخت سایتت رو برای روزهای پرترافیک آماده کن:
🔥 ۲۵٪ تخفیف روی پلنهای ۳ ماهه هاست اشتراکی ایران
⚡ ۵۰٪ تخفیف روی پلنهای یکماهه سرویس ابری در دیتاسنترهای تهران، مشهد و اهواز
🧠 مشاوره رایگان زیرساخت توسط کارشناسان هاستایران
فرصت استفاده از تخفیفها و ثبت فرم مشاوره محدود است.
📌 برای کپی کدهای تخفیف و ثبتنام در فرم مشاوره، روی لینک زیر کلیک کنید:
📌صفحه فرم مشاوره
📌تلگرام هاستایران
📌بله هاستایران
#هاست_ایران #سرور_ابری_هاست_ایران #هاست_اشتراکی #دیتاسنتر #مشاوره_زیرساخت #جام_جهانی2026
اسکرول صفحات روی موبایل اگه کلی event listener مثل
touchstart و wheel داشته باشه، راحت لگ میزنه. یه ترفند ساده توی جاوااسکریپت کمک میکنه این مشکل خیلی کمتر بشه: استفاده از passive event listener ✅
به طور پیشفرض، مرورگر مجبور میشه صبر کنه ببینه توی handler از event.preventDefault() استفاده میکنی یا نه؛ همین مکث، اسکرول رو کند میکنه. اگه به مرورگر بگی این listener «passive» هست، دیگه صبر نمیکنه و اسکرول رو روان انجام میده. 🚀
// همیشه قبل از استفاده، پشتیبانی رو چک کن
const passiveIfSupported = (() => {
let passive = false;
try {
const opts = Object.defineProperty({}, 'passive', {
get() {
passive = { passive: true };
}
});
window.addEventListener('test', null, opts);
} catch (e) {}
return passive;
})();
window.addEventListener('scroll', handleScroll, passiveIfSupported);
function handleScroll(e) {
// اینجا از e.preventDefault() استفاده نشه
}
هر جا فقط میخوای event رو بخونی و قصد preventDefault() نداری (مثل analytics روی اسکرول یا لمس)، استفاده از گزینه { passive: true } هم UX رو بهتر میکنه هم performance رو. ✨
مرجع: MDN - Passive event listeners
🔖 #Web #وب #Frontend #Backend #JavaScript #Performance #Frontend #Scroll #Event_Listener
👤 Developix
💎 Channel: @DevelopixWebدر کد زیر سعی شده در یک route مربوط به Express دادهها از یک API خارجی گرفته شده و به صورت JSON برگردانده شود، اما یک اشتباه/Anti Pattern جدی در استفاده از async/await و مدیریت error وجود دارد که میتواند باعث رفتارهای غیرقابل پیشبینی روی سرور شود.
با دقت به این کد نگاه کنید:
app.get('/posts', async (req, res) => {
try {
const response = fetch('https://example.com/api/posts');
response
.then(r => r.json())
.then(data => {
res.json({
success: true,
posts: data
});
})
.catch(err => {
console.error('Fetch error:', err);
res.status(500).json({ message: 'Internal error' });
});
} catch (err) {
console.error('Route error:', err);
res.status(500).json({ message: 'Route failed' });
}
});
چه چیزی باید در این کد اصلاح شود تا استفاده از async/await و مدیریت خطا به شکل درست و قابل پیشبینی انجام شود؟
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWebتمیز کردن Controller با تکنیک Extract Function 🧹
یکی از سادهترین و تاثیرگذارترین تکنیکهای refactor در وب، مخصوصاً توی backend، Extract Function هست: جدا کردن بخشهای منطقیِ یک تابع بزرگ به چند تابع کوچک، واضح و قابل تست. 👌
وقتی یک controller یا handler همهچیز را خودش انجام میدهد (validation، لاگ، query، mapping، ارسال response)، سریع تبدیل به کد شلوغ و سختقابلتغییر میشود؛ همون چیزی که تو Clean Code بهش میگن God Function یا Long Method.
بیایید یک مثال Node.js & Express ببینیم.
قبل از Extract Function (کد شلوغ)
app.post('/api/users', async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ message: 'Invalid data' });
}
console.log('Creating user', email);
const exists = await User.findOne({ email });
if (exists) {
return res.status(409).json({ message: 'User exists' });
}
const hash = await bcrypt.hash(password, 10);
const user = await User.create({ email, password: hash });
return res.status(201).json({
id: user.id,
email: user.email,
});
});
این تابع "کار میکند"، اما:
• چندین سطح responsibility قاطی شده 🔥
• تست کردنش سختتر است
• توسعه بعدی (مثل اضافهکردن audit log یا event) ریسک bug دارد
بعد از Extract Function (کد تمیزتر)
function validateCreateUser(body) {
const { email, password } = body;
if (!email || !password) {
throw new Error('INVALID_DATA');
}
}
async function ensureUserNotExists(email) {
const exists = await User.findOne({ email });
if (exists) {
throw new Error('USER_EXISTS');
}
}
async function createUser(email, password) {
const hash = await bcrypt.hash(password, 10);
return User.create({ email, password: hash });
}
app.post('/api/users', async (req, res) => {
try {
validateCreateUser(req.body);
const { email, password } = req.body;
await ensureUserNotExists(email);
const user = await createUser(email, password);
return res.status(201).json({
id: user.id,
email: user.email,
});
} catch (err) {
if (err.message === 'INVALID_DATA') {
return res.status(400).json({ message: 'Invalid data' });
}
if (err.message === 'USER_EXISTS') {
return res.status(409).json({ message: 'User exists' });
}
return res.status(500).json({ message: 'Server error' });
}
});
الان هر تابع یک کار مشخص انجام میدهد:
• validateCreateUser → فقط validation
• ensureUserNotExists → فقط چک کردن business rule
• createUser → فقط ساختن user
چند مزیت مهم:
• تست واحد برای validation و منطقِ وجود کاربر مستقل از Express ✅
• خوانایی خیلی بهتر؛ controller مثل یک سناریو step-by-step شده 📖
• آماده برای reuse در endpoint یا سرویسهای دیگر ♻️
برای مطالعه بیشتر درباره Extract Function و refactoring:
refactoring.guru/extract-method
این نوع refactorهای کوچک، در طول زمان معماری backend و حتی frontend (مثلاً در handlerهای React/Next.js) را بسیار تمیزتر و قابلنگهداریتر میکند. امروز روی یک متد شلوغ امتحانش کنید و تفاوت را در خوانایی حس کنید. 🚀
🔖 #Web #وب #Frontend #Backend #refactoring #clean_code #nodejs #express #backend #extract_function #controller
👤 Developix
💎 Channel: @DevelopixWeb🚀 ترفند کوچک برای لود سریعتر JS با
defer
خیلی وقتها اسکریپتهای سنگین باعث میشوند لود اولیه صفحه کند شود و First Paint دیر اتفاق بیفته. یک راه ساده و امن برای بهتر شدن تجربه کاربر، استفاده از attribute بهدردبخور defer در اسکریپتهای خارجی است. 😎
وقتی روی <script> از defer استفاده میشود:
- HTML بدون توقف پارس میشود ✅
- فایل JS در پسزمینه دانلود میشود ✅
- اجرای JS بعد از کامل شدن HTML و قبل از DOMContentLoaded انجام میشود ✅
<!-- خوب برای اسکریپتهای غیرضروری در لحظه اول -->
<script src="/static/js/app.js" defer></script>
<!-- اگر به ترتیب اجرا نیاز داری، همین ترتیب tagها رعایت میشود -->
<script src="/static/js/vendor.js" defer></script>
<script src="/static/js/main.js" defer></script>
برخلاف async، ترتیب اجرای اسکریپتها با defer حفظ میشود، که برای بیشتر پروژههای Web امنتر و قابلپیشبینیتر است. 🌱
مرجع بیشتر: MDN – <script> element
یک بار روی اسکریپتهای عمومی و analytics امتحان شود، تاثیرش روی سرعت حس میشود. ⚡️
🔖 #Web #وب #Frontend #Backend #HTML #script #defer #Performance #Frontend #Web
👤 Developix
💎 Channel: @DevelopixWeb+1
در نمونهکد بالا، در نسخهٔ اشتباه همهٔ event listenerها روی window ثبت میشوند اما هرگز در زمان نیاز حذف نمیشوند و همین موضوع میتواند در یک Single Page Application بزرگ باعث Memory Leak و افت کارایی در طول زمان شود. در نسخهٔ اصلاحشده با نگه داشتن reference توابع هندلر و حذف آنها در زمان مناسب، ضمن رعایت best practice در مدیریت lifecycle، از رشد بیرویهٔ مصرف مموری و کند شدن رندر جلوگیری میشود. در پروژههای جدی وب، مخصوصاً وقتی کامپوننتها بهطور پویا mount/unmount میشوند، مدیریت صحیح event listenerها مثل این نمونه بسیار حیاتی است.
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
✨ NextAuth.js؛ احراز هویت مدرن برای Next.js
اگه با Next.js کار میکنی و احراز هویت همیشه برات دردسر بوده، NextAuth.js دقیقا برای همینه 👇
🔐 چیه و چی حل میکنه؟
یک کتابخونهٔ آماده برای اضافهکردن login/signup، session management و OAuth (مثل Google, GitHub, Twitter) بدون اینکه خودت از صفر Token و Cookie و Security رو هندل کنی.
🚀 ویژگیهای مهم
• پشتیبانی از OAuth, Email/Password, Credentials
• Session سمت سرور، سازگار با SSR و Route Handlerهای Next.js
• تنظیمات قابلانعطاف و TypeScript‑friendly
• کار با DBهای مختلف (PostgreSQL, MySQL, MongoDB, Prisma و ...)
🛠️ نصب سریع
npm install next-auth
مثال ساده Route Handler در Next.js 13+
import NextAuth from "next-auth";
import GitHubProvider from "next-auth/providers/github";
export const authOptions = {
providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
],
};
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
برای پروژههای SaaS، پنلهای ادمین یا هر اپ multi-user، استفاده از NextAuth.js هم سریعتره هم امنتر از نوشتن auth از صفر ✅
Docs رسمی:
https://next-auth.js.org
GitHub:
https://github.com/nextauthjs/next-auth
امتحانش کن و روی auth وقت کمتری بذار تا روی featureهای اصلی اپ 😉
🔖 #Web #وب #Frontend #Backend #NextAuth #Next_js #Authentication #OAuth #Web_Dev #JavaScript #TypeScript
👤 Developix
💎 Channel: @DevelopixWeb