چگونه وبلاگم را شروع کردم • جاش دبلیو کومو

در چند ماه گذشته من روی نسخه جدید این وبلاگ کار می کردم. چند هفته پیش سوئیچ را زدم! در اینجا یک موازی سریع وجود دارد:
صفحه اصلی وبلاگ (قدیمی)

صفحه اصلی وبلاگ (جدید)


از نظر طراحی، خیلی تغییر نکرده است. من دوست دارم فکر کنم کمی ظریف تر است، اما ایده کلی همان است. بسیاری از جالب تغییرات در زیر کاپوت یا پنهان در جزئیات است. در این پست وبلاگ می خواهم به اشتراک بگذارم که پشته جدید چگونه است و به برخی از آن جزئیات بپردازم!
در طول سال ها، وبلاگ من به یک برنامه کاربردی پیچیده تبدیل شده است. تمام شد 100000 خط کد، بدون احتساب محتوا. مهاجرت به همه چیز پروژه بزرگی بود، اما فوق العاده آموزشی. من افکار صادقانه خود را در مورد تمام فناوری های جدیدی که برای این وبلاگ استفاده کرده ام به اشتراک خواهم گذاشت.
اگر میخواهید خودتان وبلاگی راهاندازی کنید یا از برخی از فناوریهایی که من استفاده میکنم استفاده میکنید، امیدواریم این پست بسیار مفید باشد!
بیایید با لیست کوتاهی از فناوری های اصلی استفاده شده توسط وبلاگ من شروع کنیم:
این فهرست احتمالاً برای یک وبلاگ بیش از حد به نظر می رسد، و چندین نفر از من پرسیده اند که چرا جایگزین “سبک تر” را انتخاب نکرده ام. چند دلیل وجود دارد:
-
همه پست های وبلاگ من با استفاده از MDX نوشته شده اند، بنابراین من به پشتیبانی MDX ممتاز نیاز داشتم.
-
پروژه اصلی دیگر من، پلتفرم دوره من، از Next.js استفاده می کند. من میخواستم تا آنجا که ممکن است اصطکاک تغییر متن کمتر باشد.
-
من میخواستم با جدیدترین ویژگیهای React، چیزهایی مانند مؤلفههای سرور و اقدامات، کمی تجربه بیشتر کسب کنم.
اگر به دلایل 2 و 3 نبود، احتمالاً داشتم Astro(در برگه جدید باز می شود) شلیک کرد. من هم کنجکاو بودم ریمیکس(در برگه جدید باز می شود) برای مدت طولانی! من فکر می کنم هر دو احتمالا گزینه های فوق العاده ای هستند.
من پست های وبلاگ را با استفاده از MDX می نویسم. این احتمالاً مهمترین بخش بسته فناوری برای من است.
اگر با MDX آشنایی ندارید، اساساً ترکیبی از Markdown و JSX است. میتوانید آن را بهعنوان یک ابرمجموعه از Markdown در نظر بگیرید که یک ابرقدرت اضافی را ارائه میکند: توانایی گنجاندن عناصر سفارشی React در محتوا.
با MDX، من می توانم ویجت های تعاملی ایجاد کنم و آنها را درست در وسط یک پست وبلاگ رها کنم، مانند این:
برگرفته از پست وبلاگ من، راهنمای تعاملی Flexbox.
این توانایی برای انواع محتوایی که من ایجاد می کنم بسیار مهم است. من نمیخواستم با مجموعه استاندارد عناصر Markdown (پیوندها، جداول، فهرستها…) محدود شوم. با MDX می توانم من آیتم های خودم را ایجاد می کنم! این بسیار قدرتمندتر از Markdown سنتی یا محتوای متن غنی ذخیره شده در یک CMS است.
ممکن است از خود بپرسید: چرا به “full React” بروید و بخش Markdown را به طور کامل نادیده بگیرید؟ وقتی اولین نسخه این وبلاگ را در سال 2017 ایجاد کردم، این کار را انجام دادم. هر پست وبلاگ یک جزء React بود. این دو مشکل داشت:
-
نوشته وحشتناکی بود شما باید هر پاراگراف را در یک بپیچید
, for example, gets old really fast. -
There was no way to access the content as data. I couldn’t, for example, get a list of the 10 most recently updated blog posts, since each blog post was a chunk of code, not a database record or JSON object.
MDX solves both of these problems, and without really sacrificing anything. I still have the full power of React when I'm writing blog posts!
In terms of workflow, I edit my MDX files directly in VS Code and commit them as code. Article metadata (eg. title, publish date) is set in frontmatter at the top of the file. There are some drawbacks to this method (eg. I have to re-deploy the whole app to fix a typo), but I’ve found it’s the simplest option for me.
There are several ways to use MDX with Next.js. I'm using next-mdx-remote(opens in new tab), mostly because it’s what I use on my course platform and I want the two projects to be as similar as possible. If you’re building a brand-new blog using Next.js, it’s probably worth giving the built-in MDX support(opens in new tab) a shot; it seems a lot more straightforward.
The old version of my blog used styled-components, a CSS-in-JS library. As I’ve written about previously, styled-components isn’t fully compatible with React Server Components. So, for this new blog, I've switched to Linaria(opens in new tab), via the next-with-linaria integration(opens in new tab).
Here’s what it looks like:
import { styled } from '@linaria/react';
const Wrapper = styled.div`
background: red;
`;
Linaria یک ابزار عالی است. آشنایی را پیشنهاد می کند styled API، اما به جای اینکه جادوی خود را در زمان اجرا انجام دهد، به جای آن در ماژول های CSS کامپایل می شود. این بدان معنی است که هیچ زمان اجرای JS در کار نیست و در نتیجه کاملاً با React Server Components سازگار است!
حالا کار کردن Linaria با Next یک نبرد سخت بود. من با چند مشکل عجیب برخورد کردم. به عنوان مثال، زمانی که من React را در یک فایل بدون در واقع وارد می کنم استفاده کنید این، من این خطای گیج کننده را دریافت می کنم:
EvalError: TextEncoder تعریف نشده است
/node_modules/.pnpm/@wyw-in-js+transform@0.4.1_typescript@5.4.5/node_modules/@wyw-in-js/transform/lib/module.js:223
پرتاب جدید EvalError(e.message, this.callstack.join('\n| '));
پیامهای خطا/ردیابی پشته واقعاً کمکی نکردند، بنابراین بیشتر مشکلات را با بازگشت به تغییرات خود و/یا حذف موارد تصادفی تا زمانی که خطا برطرف شد، حل کردم. خوشبختانه، تمام مشکلاتی که پیدا کردم ثابت و قابل پیش بینی بود. این یکی از آن چیزهایی نیست که در آن اشتباه اتفاق می افتد گاهی اوقات، یا فقط در حال تولید است.
هنگامی که تمام ویژگی های خاص او را یاد گرفتم، همه چیز کاملاً روان بود، اگرچه یک مشکل اصلی باقی مانده است. و این به هیچ وجه به Linaria مربوط نمی شود، بلکه به نحوه مدیریت ماژول های CSS توسط Next.js مربوط می شود.
این یک حرکت بسیار بزرگ است که در این پست به درستی پوشش داده نمی شود، اما به طور خلاصه می توان گفت: Next.js "خوشبینانه" دسته ای از CSS را از مسیرهای نامرتبط ادغام می کند تا سرعت ناوبری بعدی را بهبود بخشد و ترتیب صحیح CSS را تضمین کند. برای مثال، این پست وبلاگ 245 کیلوبایت CSS را بارگیری می کند اما فقط از 47 کیلوبایت استفاده می کند.هر دو عدد مقادیر کامل فشرده نشده هستند. مقدار واقعی داده ارسال شده از طریق کابل کمتر است. یک بحث فعال در مورد وجود دارد Github(در برگه جدید باز می شود) در مورد این و به نظر می رسد برخی از گزینه های پیکربندی آینده ممکن است وضعیت را بهبود بخشد.
تمام آنچه گفته شد، من نمی توانم Linaria را توصیه کنم. این ابزار فوقالعادهای است، اما آنقدر آزمایش نشده است که بتواند راهحلی معقول برای اکثر افراد/تیمها باشد.
من در حال حاضر بیشتر در مورد پیگمنت هیجان زده هستم CSS(در برگه جدید باز می شود)، یک ابزار CSS-in-JS با زمان صفر که توسط تیم سازنده Material UI توسعه یافته است. در آینده، این کتابخانه CSS خواهد بود که توسط کتابخانه مؤلفه MUI محبوب آنها استفاده می شود، به این معنی که به سرعت به یکی از آزمایش شده ترین کتابخانه های CSS تبدیل خواهد شد.
هنوز روزهای اولیه است، اما زمانی که آنها نسخه 1.0 را منتشر کردند، قصد دارم سعی کنم تغییر دهم. امیدواریم تا آن زمان، Next.js مشکل گروه بندی را با ماژول های CSS برطرف کرده باشد. 🤞
به لطف یک تم دستوری سفارشی، قطعات کد در وبلاگ جدید بسیار متفاوت به نظر می رسند! در اینجا قبل / بعد:
قطعه کد (قدیمی)
قطعه کد (جدید)
اگر می خواهید از این تم در IDE خود استفاده کنید، می توانید فایل های JSON (تاریک، روشن) را دانلود کنید. من آن را تست نکرده ام، اما از همان دستور زبان VSCode و سایر ویرایشگرها استفاده می کند. باید کار کردن
پیوند به این عنوانجادوی استاتیک
من استفاده می کنم شیکی(در برگه جدید باز می شود) برای کنترل برجسته سازی نحو. اگرچه به طور خاص برای React ساخته نشده است، اما Shiki برای اجرا در زمان کامپایل طراحی شده است، و آن را برای اجزای سرور React مناسب می کند. به طرز شگفت انگیزی هیجان انگیز است.
در وبلاگ قدیمی خود، من از Prism، یک کتابخانه برجسته نحوی معمولی در سمت مشتری استفاده کردم. از آنجایی که تمام کدها در بسته جاوا اسکریپت گنجانده شده است، باید چند فداکاری انجام داد:
-
ما باید در مورد تعداد زبان هایی که پشتیبانی می کنیم بسیار محافظه کار باشیم، زیرا هر زبان اضافی کیلوبایت به بسته ما اضافه می کند.
-
منطق برجستهسازی نحو آسانتر است، بسیار سادهتر از برجستهسازی نحو در یک IDE مانند VS Code. این به سازندگان تم کنترل کمتری بر نتیجه نهایی می دهد و به این معنی است که نمی توانیم تم ها را بین IDE و Prism به اشتراک بگذاریم.
با حداقل مجموعه زبانهای داخلی، Prism با ۲۶ کیلوبایت کوچکسازی میشود و gzipped(در برگه جدید باز می شود)، که برای یک برچسب نحوی فوق العاده کوچک است، اما همچنان یک افزودنی ضروری به بسته است.
با Shiki، 0 کیلوبایت به بسته جاوا اسکریپت اضافه می کند، از گرامر استاندارد TextMate مانند VS Code استفاده می کند و می تواند ده ها زبان را بدون هزینه اضافی پشتیبانی کند.
این به این معنی است که وقتی میخواهم یک قطعه Haskell را اضافه کنم، همانطور که در یک پست تصادفی وبلاگی که سالها پیش نوشتم، آن را به طور کامل در نحو خطدار میشود:
pe58 = n
where
a p q = scanl (+) p $ iterate (+ 8) q
b = [[x,y,z] | (x,(y,z)) zip (a 3 10) $ zip (a 5 12) (a 7 14)]
c = zip (scanl1 (+) . map (length . filter isPrime) $ b) (iterate (+ 4) 5)
[(n,_)] = take 1 $ dropWhile (\(_,(a,b)) -> 10*a > b) $ zip [3,5..] c
کار با Shiki به عنوان یک توسعه دهنده لذت بخش است. این فوق العاده انعطاف پذیر و قابل گسترش است. به عنوان مثال، من منطق "حاشیه" خود را ایجاد کردم تا بتوانم خطوط خاصی از کد را برجسته کنم:
function someRandomFunction() {
// These two lines are highlighted! You can tell by the
// background color, and the little bump on the left.
return 42;
}
در وبلاگ قدیمی من، برجسته سازی نحو برای CSS-in-JS به درستی کار نمی کرد. رشته های قالب من به عنوان یک رشته استاندارد در نظر گرفته می شوند، نه کمی CSS تزریق شده در JS:
با Shiki، من میتوانم از منطق برجستهسازی نحوی که VSCode روی کامپوننتهای استایلگذاری شده استفاده میکنم. پسوند(در برگه جدید باز می شود) فراهم می کند. بنابراین، اجزای استایل من به درستی علامت گذاری شده اند:
const FunkyButton = styled.button`
position: absolute;
background: linear-gradient(
to bottom,
red,
gold
);
@media (min-width: 24rem) {
&:focus {
background: gold;
}
}
`;
export default FunkyButton;
به همان اندازه که من شیکی را دوست دارم، برخی معاوضه ها وجود دارد.
از آنجایی که از مکانیزم برجستهسازی نحو قدرتمندتری استفاده میکند، به سرعت گزینههای دیگر نیست. من در ابتدا این پستهای وبلاگ را «در صورت تقاضا» با استفاده از رندر سمت سرور استاندارد بهجای تولید HTML استاتیک در زمان کامپایل ارائه کردم، اما متوجه شدم که Shiki سرعت کار را بسیار کند کرده است، مخصوصاً در صفحاتی که قطعات زیادی دارند. این مشکل را می توان با تغییر به تولید استاتیک یا با استفاده از حافظه پنهان HTTP حل کرد.
شیکی نیز حافظه گرسنه است. من با تمام شدن Node به مشکل برخوردم حافظه(در برگه جدید باز می شود)، و من مجبور شدم برای اینکه مطمئن شوم چندین نمونه از شیکی ایجاد نمی کنم، اصلاح کنم.
با این حال، بزرگترین مشکل این است که گاهی اوقات من نیاز به برجسته سازی نحوی دارم مشتری به عنوان مثال، در تولید کننده پالت سایه من، قطعه بر اساس نحوه ویرایش سایه ها توسط کاربر تغییر می کند:
هیچ راهی برای تولید این در زمان کامپایل وجود ندارد زیرا کد پویا است!
برای این موارد من یک دوما هایلایتر شیک. این یکی سبک تر است و تنها تعداد کمی از زبان ها را پشتیبانی می کند. و در بسته های پیش فرض من گنجانده نشده است، من آن را با تنبلی بارگذاری می کنم بعدی/پویا(در برگه جدید باز می شود). از آنجایی که خود برجسته سازی نحو کندتر است، من از useDeferredValue استفاده می کنم تا بقیه برنامه را سریع نگه دارم.
سخت ترین قسمت این بود که به آن نیاز داشتم هر دو یک جزء سرور استاتیک و همچنین یک مؤلفه مشتری پویا برای SSR که به درستی کار کند. پس از بارگیری همه چیز، مخفیانه بین آنها روی مشتری سوئیچ می کنم.
علاوه بر تکههای کد، زمین بازی کد، ویرایشگرهای کوچک به سبک Codepen نیز دارم:
کد زمین بازی
import React from 'react'; import range from 'lodash.range'; import styles from './PrideFlag.module.css'; import { COLORS } from './constants'; function PrideFlag({ variant = 'rainbow', width = 200, numOfColumns = 10, staggeredDelay = 100, billow = 2, }) { const colors = COLORS[variant]; const friendlyWidth = Math.round(width / numOfColumns) * numOfColumns; const firstColumnDelay = numOfColumns * staggeredDelay * -1; return ( div className={styles.flag} style={{ width: friendlyWidth }}> {range(numOfColumns).map((index) => ( div key={index} className={styles.column} style={{ '--billow': index * billow + 'px', background: generateGradientString(colors), animationDelay: firstColumnDelay + index * staggeredDelay + 'ms', }} /> ))} div> ); } function generateGradientString(colors) { const numOfColors = colors.length; const segmentHeight = 100 / numOfColors; const gradientStops = colors.map((color, index) => { const from = index * segmentHeight; const to = (index + 1) * segmentHeight; return `${color} ${from}% ${to}%`; }); return `linear-gradient(to bottom, ${gradientStops.join(', ')})`; } export default PrideFlag;
برگرفته از پست وبلاگ من، متحرک پرچم های غرور.
من برای زمین های بازی React استفاده می کنم بسته بندی شن و ماسه(در برگه جدید باز می شود)، یک ویرایشگر فوق العاده که توسط افراد CodeSandbox ایجاد شده است. من قبلاً در مورد نحوه استفاده از Sandpack نوشته ام و همه این موارد هنوز اعمال می شود.
برای HTML/CSS استاتیک از فورک خودم از agnym استفاده می کنم زمین بازی کودکان(در برگه جدید باز می شود). بسته بندی شن و ماسه انجام می دهد از قالبهای استاتیک پشتیبانی میکنند، اما آنها به Service Workers متکی هستند، که گاهی اوقات توسط تنظیمات حریم خصوصی مرورگر مسدود میشوند و در نتیجه یک تجربه کاربری خراب میشوند.
بسیاری از مردم از من پرسیده اند که چگونه می توانم دموهای تعاملی را در پست هایم مانند این ایجاد کنم:
مطمئنی
این عمل قابل لغو نیست.
برگرفته از پست وبلاگ من، طراحی سایه های زیبا در CSS.
من هرگز نمی دانم چگونه به این سوال پاسخ دهم 😅 من از کتابخانه ها یا بسته های خاصی برای این کار استفاده نمی کنم، همه چیز برای توسعه وب استاندارد است. من قابل استفاده مجدد خودم را ایجاد کردم مؤلفهای که پوشش و مجموعهای از کنترلها را فراهم میکند، و من آن را برای هر ویجت جداگانه مینویسم.
با این حال، چند ابزار کلی وجود دارد که کمک می کند. من از React استفاده می کنم بهار(در برگه جدید باز می شود) برای درونیابی هموار بین مقادیر به روشی سیال و ارگانیک. من هم از Framer استفاده میکنم حرکت(در برگه جدید باز می شود) برای انیمیشن های چیدمان
داشتن دو کتابخانه انیمیشن مجزا بسیار لذت بخش است، به خصوص که هیچکدام کوچک نیستند ( 19.4 کیلوبایت(در برگه جدید باز می شود) و 44.6 کیلوبایت(در برگه جدید باز می شود)به ترتیب). من React Spring را بهعنوان کتابخانه پایه اضافه میکنم و در صورت نیاز، Framer Motion را به صورت پویا وارد میکنم.
با این حال، راستش را بخواهید، Framer Motion باید بتواند هر کاری که React Spring میتواند انجام دهد را انجام دهد، بنابراین اگر مجبور باشم یک کتابخانه انیمیشن «جزیره صحرایی» انتخاب کنم، احتمالاً Framer Motion خواهد بود.
اگر در حال خواندن این مطلب در رایانه رومیزی هستید، ممکن است این پسر کوچک را در کنار خود دیده باشید:
این یک است مانند دکمه که به نوعی احمقانه است... شبکه های اجتماعی از دکمه هایی مانند این استفاده می کنند تا الگوریتم خود را در مورد اینکه کدام قسمت از محتوا ظاهر شود، استفاده می کنند. این وبلاگ هیچ الگوریتم اکتشافی ندارد، بنابراین هدفی جز زیبا بودن ندارد.
هر بازدید کننده می تواند تا 16 بار روی دکمه کلیک کند و داده ها در MongoDB ذخیره می شوند. ورودی پایگاه داده به شکل زیر است:
{
"slug": "promises",
"categorySlug": "javascript",
"hits": 123456,
"likesByUser": {
"abc123": 16,
"def456": 4,
"ghi789": 16,
// ...
}
}
شناسه ها بر اساس آدرس IP کاربر هش شده با استفاده از نمک مخفی برای حفظ ناشناس بودن تولید می شوند. این وبلاگ در Vercel مستقر شده است و Vercel IP را از طریق یک هدر در اختیار کاربر قرار می دهد.
در ابتدا از شناسههایی استفاده میکردم که روی کلاینت تولید شده و در محلی ذخیره میشدند، اما کاراگاه افسانهای جین منچون وانگ با ارسال هرزنامه به نقطه پایانی API و ایجاد دهها هزار لایک به من نشان داد که چرا این ایده بدی است. 😅
یکی از چیزهای مورد علاقه من در مورد Next.js این است که شما به Node.js باطن جداگانه نیاز ندارید. منطق لایک کردن پست ها در Route انجام می شود دستکاری کننده(در برگه جدید باز می شود)، که تقریباً دقیقاً مانند یک نقطه پایانی Express عمل می کند.
پیوند به این عنوانانسجام عنصر
من زمان غیر منطقی را صرف کردم متنی سبک، مطمئن شوید که اجزای مشترک "آجرهای LEGO" من به خوبی با هم ترکیب شده اند.
مثلا من دارم
جزء (پیش از این بحث شد). ببینید وقتی a قرار می دهیم چه اتفاقی می افتد داخل an
:
آن را با یک قطعه کد مقایسه کنید نه داخل یک یادداشت جانبی:
function findLargestNum(nums: Arraynumber>) {
if (nums.length === 1) {
return nums[0];
}
return Math.max(...nums);
}
به جای داشتن پسزمینه شفاف و طرح کلی خاکستری، CodeSnippet داخل از Aside پس زمینه قهوه ای می شود. سایر جزئیات، مانند حاشیه نویسی و دکمه کپی در کلیپ بورد نیز دارای رنگ های سفارشی هستند.
به جای داشتن پسزمینه آبی روشن، CodeSnippet داخل از Aside پس زمینه طلایی می شود سایر جزئیات، مانند حاشیه نویسی و دکمه کپی در کلیپ بورد نیز دارای رنگ های سفارشی هستند.
من برای هر چهار رنگ سفارشی ایجاد کردم Aside انواع (اطلاعات، موفقیت، هشدار، خطا)، برای هر تم رنگی (روشن، تاریک). تکههای کد نیز هنگام قرار گرفتن در کنار، حاشیه/بالشتک متفاوتی دریافت میکنند، و این بر اساس اندازه درگاه دید و اینکه آیا آنها آخرین فرزند در ظرف هستند یا نه، تغییر میکند. با توجه به تمام ترکیبات ممکن، بسیار پیچیده می شود!
این نیز تنها یک نمونه است. بسیاری از مؤلفههای دیگر دارای سبکهای «واکنشی» هستند که بسته به زمینهشان تغییر میکنند تا اطمینان حاصل شود که همه چیز منسجم است. کار زیادی بود اما نتیجه را راضی کننده می دانم.😄
پیوند به این عنوانرنگین کمان
در صفحه اصلی دسکتاپ، ممکن است متوجه شده باشید که یک رنگین کمان بزرگ جدید وجود دارد:

این قوس به مکاننمای شما پاسخ میدهد، بخشهایی مانند برادههای آهن که به آهنربا پاسخ میدهند به سمت آن خم میشوند.
همچنین یک تخم مرغ کوچک اضافی وجود دارد: اگر برای چند ثانیه روی رنگین کمان بمانید، یک دکمه کوچک "ویرایش" ظاهر می شود. با کلیک بر روی آن 🌈 باز می شود پیکربندی رنگین کمان.

پیچش اینجاست: شما فقط قوس دستگاه خود را تغییر نمی دهید، شما آن را برای همه تغییر دهید هر تغییری فوراً در سراسر جهان پخش می شود، رنگین کمان ها از طریق کابل های شبکه و سیگنال های وای فای عکس می گیرند تا همه ما بتوانیم از رنگین کمانی که شما طراحی کرده اید لذت ببریم.💖
این امر توسط PartyKit(در برگه جدید باز می شود)یک ابزار مدرن عالی که توسط Sunil Pai معروف ایجاد شده است. از WebSockets استفاده می کند بنابراین تغییرات سریع هستند. من نمی توانم به اندازه کافی چیزهای خوب در مورد PartyKit بگویم. تجربه توسعه دهندگان در سطح جهانی است.
یکی از مواردی که من نتوانستم در نظر بگیرم این است که چقدر آشفته خواهد بود با صدها نفر که سعی می کنند همزمان رنگین کمان را ویرایش کنند. وقتی برای اولین بار وبلاگ جدید را راهاندازی کردم، چند گزارش اشکال از افرادی دریافت کردم که فکر میکردند رنگین کمان در حال محو شدن است، بدون اینکه نمیدانستند افراد دیگر بر سر کنترلها با هم دعوا میکنند. اکنون همه چیز آرام شده است، اما من هنوز باید راهی برای روشن تر کردن این موضوع پیدا کنم.
پیوند به این عنوانمروری بر انتقال ها
هنگام پیمایش بین صفحات، باید یک انیمیشن متقاطع محو ظریف وجود داشته باشد. اگر هدر در یک مکان جدید است، باید در جای خود بلغزد:
این باعث می شود از View Transitions بسیار قدرتمند استفاده شود API(در برگه جدید باز می شود). هنوز در همه مرورگرها پشتیبانی نمیشود، اما فکر میکنم یک بهبود تدریجی خوب است.
این API با گرفتن اسکرین شات مجازی از رابط کاربری درست قبل از انتقال و دستکاری آن اسکرین شات و رابط کاربری واقعی، کشیدن و محو کردن چیزها برای ایجاد این توهم کار می کند که دو عنصر مجزا در دو صفحه جداگانه یکسان هستند.
صادقانه بگویم، کار کردن با آن بسیار دشوار است. من فکر می کنم طراحی API عالی است، اما فضای مشکل اساسی آنقدر پیچیده است که راهی برای جلوگیری از پیچیدگی وجود ندارد. انتظار داشته باشید که با موارد عجیب و غریب مواجه شوید، مانند مواردی که نسبت تصویر خود را حفظ نمی کنند یا متن ناهموار است.
دریافتم که محتوای جیک آرچیبالد در جمع بندی افکارم پیرامون انتقال مرور بسیار مفید بود. به عنوان مثال، مقاله او در مورد رسیدگی به نسبت تغییر می کند(در برگه جدید باز می شود).
کار کردن آن در مسیریاب برنامه Next.js کمی چالش برانگیز بود. من استفاده کردم استفاده - مشاهده - انتقال(در برگه جدید باز می شود) بسته و سطح پایینی ایجاد کرد Link جزء که می پیچد next/link. شما می توانید آن را بررسی کنید در منابع اگر کنجکاو هستید پنجره!
پیوند به این عنوانجستجو کنید
بلاخره وبلاگ من یک تابع جستجو دارد! با کلیک بر روی ذره بین در هدر می توانید به آن دسترسی پیدا کنید.
من استفاده می کنم الگوليا(در برگه جدید باز می شود) برای انجام تمام کارهای سخت مانند تطبیق فازی. در برخی مواقع ممکن است تمام داده های پست وبلاگم را به یک عامل هوش مصنوعی برسانم و یک ربات چت بسازم، اما در حال حاضر به نظر می رسد جستجوی اولیه کار می کند.
یک جزئیات کوچک زیبا: کلیک کردن روی نماد "سطل زباله" عبارت جستجو را پاک می کند، اما من آن را تنظیم کرده ام تا آنی نباشد. می خواستم به نظر برسد که سطل زباله هر شخصیت را می بلعد. 😄
پیوند به این عنواننمادهای طرح کلی مدرن
در نگاه اول آیکون های این سایت به نظر می رسد کاملا شبیه به آیکون های قدیمی، اما بهبود یافته است. بسیاری از آنها ریز تعاملات جدیدی دارند!
روند من برای این شامل شروع با نمادهای Feather است نمادها(در برگه جدید باز می شود)، زیرا آنها به خوبی با زیبایی شناسی من مطابقت دارند. سپس SVG آنها را تقسیم یا بازسازی می کنم تا بتوانم قسمت های مستقل را متحرک کنم.
به عنوان مثال، من یک گلوله فلش دارم که در حالت انتظار کشیده می شود:
من با دریافت کد SVG برای نمادهای پر شروع کردم ArrowRightو تبدیل آن به JSX. کد نهایی به شکل زیر است:
import { useSpring, animated } from 'react-spring';
const SPRING_CONFIG = {
tension: 300,
friction: 16,
};
function IconArrowBullet({
size = 20,
isBooped = false,
}: Props) {
const shaftProps = useSpring({
x2: isBooped ? 23 : 18,
config: SPRING_CONFIG,
});
const tipProps = useSpring({
points: isBooped
? '17 6 24 12 17 18'
: '12 5 19 12 12 19',
config: SPRING_CONFIG,
});
return (
svg
fill="none"
width={size / 16 + 'rem'}
height={size / 16 + 'rem'}
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
xmlns="http://www.w3.org/2000/svg"
>
animated.line
x1="5"
y1="12"
y2="12"
{...shaftProps}
/>
animated.polyline {...tipProps} />
svg>
);
}
export default IconArrowBullet;
مانند یک فلش واقعی، این نماد از یک شفت و نوک ساخته شده با SVG تشکیل شده است line و polyline. با استفاده از React Spring، مقادیر x/y را برای برخی از نقاط زمانی که bup است تغییر میدهم. این یک فرآیند آزمون و خطا بود، حرکت دادن نقاط فردی تا زمانی که احساس درستی پیدا کرد.
بسیاری از نمادهای موجود در این سایت دارای ریز تعاملات مشابهی هستند. من حتی یک تخم مرغ ویژه دیگر برای عید پاک برای یکی از نمادها برنامه ریزی کرده ام، چیزی که به موقع برای عرضه به پایان نرسیدم. 😮
پیوند به این عنوانقابلیت دسترسی
در حقیقت شگفتانگیز درباره پیکسلها و قابلیت دسترسی، نحوه استفاده را نشان میدهم rem ماژول پرسش رسانه در دسترس تر است. اگر کاربر اندازه فونت پیشفرض مرورگر خود را افزایش دهد، تضمین میکند که طرحبندی ما به خوبی تطبیق مییابد.
هر از گاهی یک خواننده متوجه این موضوع می شود وبلاگ واقعی من استفاده می شود پیکسلپرس و جوهای رسانه ای مبتنی بر من حتی به آنچه که موعظه می کردم عمل نکردم! چه ریاکاری!
وقتی برای اولین بار نسخه قبلی وبلاگم را ایجاد کردم، نمی دانستم که پرسش های رسانه ای مبتنی بر rem در دسترس تر هستند. من آن را هنگام ساختن پلتفرم دوره خود کشف کردم. ابزار مجدد وبلاگم برای استفاده از پرسشهای رسانهای مبتنی بر rem کار بزرگی بود، و من نمیخواستم منتظر بمانم تا این کار انجام شود تا آنچه را یاد گرفتم به اشتراک بگذارم!
بنابراین، هر بار که کسی در مورد آن به من ایمیل میفرستاد، آن دلیل را به اشتراک میگذاشتم، اما هنوز هم نسبت به آن احساس ناراحتی میکردم. 😅
نیازی به گفتن نیست که این وبلاگ جدید از پرسشهای رسانهای مبتنی بر rem در سراسر جهان استفاده میکند. من در طول سالها چیزهای زیادی در مورد دسترسی (از جمله از طریق ناتوانی کوتاهمدت خودم) یاد گرفتهام و همه چیزهایی را که یاد گرفتهام در این وبلاگ جدید به کار بردهام.
البته، من همیشه به یادگیری ادامه می دهم، بنابراین اگر چیزی را در این وبلاگ گم کردید، لطفاً به من اطلاع دهید!
همانطور که قبلاً اشاره کردم، یکی از بزرگترین تغییرات با وبلاگ جدید حرکت از این وبلاگ بود روتر صفحات به برنامه روتر. من می دانم که بسیاری از افراد در نظر دارند همان سوئیچ را ایجاد کنند، بنابراین می خواستم تجربه خود را برای کمک به شما در تصمیم گیری به اشتراک بگذارم.
راستش تجربه من کمی مختلط بود😅. بیایید با چیزهای خوب شروع کنیم.
الگوی فکر فوق العاده است. پارادایم "مولفه های سرور" بسیار طبیعی تر از آن به نظر می رسد getServerSideProps. قطعاً یک منحنی یادگیری وجود دارد، اما من خیلی سریع از آن استفاده کردم. علاوه بر ارگونومی بهبود یافته، سیستم جدید قدرتمندتر نیز می باشد. به عنوان مثال: در مسیریاب Pages، تنها جزء مسیر سطح بالا می تواند کار پشتیبان را انجام دهد، در حالی که اکنون هر مؤلفه سرور می تواند.
مزیت دیگر اجزای سرور این است که دیگر نیازی به گنجاندن هر مؤلفه React در بسته های مشتری خود نداریم. این بدان معنی است که اجزای "استاتیک" به طور کامل از بسته ها حذف می شوند. همچنین به این معنی است که ما میتوانیم از کتابخانههای قدرتمند انحصاری سرور مانند Shiki استفاده کنیم، زیرا بدانیم که نیازی نیست نگران نفخ باشیم.
در تئوری این باید منجر به افزایش عملکرد بسیار قابل توجهی می شود، اما این تجربه من نیست. در واقع معرفی وبلاگ جدید من است کمی بدتر از وبلاگ قدیمی من:
گزارش فانوس دریایی (قدیمی)
گزارش فانوس دریایی (جدید)
وجود دارد لحن هر چند از اخطارها در این مورد:
-
این واقعاً یک مقایسه سیب با سیب نیست زیرا من مجموعه ای از ویژگی ها و جزئیات جدید را به وبلاگ جدید اضافه کرده ام. این یک مهاجرت مستقیم 1:1 نبود.
-
یکی از عوامل مهم، بستهبندی CSS است یک سوال(در برگه جدید باز می شود) قبلا اشاره کردم. اگر از ماژول های CSS (یا ابزاری که در ماژول های CSS کامپایل می شود) استفاده نمی کنید، با این مشکل مواجه نخواهید شد.
-
از آنجایی که من تعاملات زیادی را با استفاده از React Spring انجام می دهم، a زیاد در غیر این صورت اجزای ثابتی که باید به اجزای مشتری تبدیل شوند. من واقعاً آنقدر اجزای سرور ندارم.
-
این امکان وجود دارد که من فرصت هایی را برای بهبود عملکرد از دست داده باشم یا در اجرای خود اشتباه کرده باشم.
با نگاه کردن به اعداد به راحتی دلسرد میشویم، اما وقتی CPU/شبکهام را کنترل میکنم و مقایسههای جانبی انجام میدهم، نمیتوانم تفاوت را تشخیص دهم. من کمی نگران تأثیر سئو امتیاز پایین تر Lighthouse هستم، اما فکر می کنم اگر تیم Next با مشکل گروه بندی CSS مقابله کند، باید تقریباً معادل باشد.
در حالی که ما در مورد عملکرد کند هستیم، سرور توسعه با App Router بسیار کندتر است. با بزرگ شدن وبلاگم این وضعیت بدتر و بدتر می شود. در اینجا آمار فعلی است:
-
با روتر Pages، بسته به وضعیت کش، سرور توسعه دهنده من 7 تا 12 ثانیه طول می کشد تا شروع شود. با App Router، این اعداد به 30-60+ ثانیه افزایش یافت.
-
بارگذاری مجدد داغ در مسیریاب صفحات آنی احساس می شود. با تغییر از ویرایشگر به مرورگر، تغییر من آنجا بود. با App Router، این کار 1 تا 5 ثانیه طول می کشد.
-
گاهی اوقات یک صفحه به طور تصادفی برای همیشه طول می کشد تا بارگذاری شود، مانند این:

خیلی دردناکه😬. وقتی برای کار روی پلتفرم دوره خود (که هنوز از مسیریاب صفحات استفاده میکند) دنده را تغییر میدهم، احساس یک نفس تازه میکنم.
باید توجه داشته باشم: از آنجایی که من از Linaria استفاده می کنم، مجبور شدم Turbopack، جایگزین مدرن مبتنی بر Rust برای Webpack را کنار بگذارم. ممکن است با فعال بودن Turbopack، عملکرد برنامهنویس مشکلی نداشته باشد. اما من گمان می کنم که بسیاری از ما در شرایط مشابهی قرار خواهیم گرفت که برای برخی از بسته ها یا بسته های دیگر به Webpack نیاز داریم و شما مجبور نیستید خیلی کند باش روتر Pages از Webpack استفاده می کرد و سریع بود!
خبر خوب این است که تیم Next.js از این نوع مسائل آگاه است و بهره وری توسعه دهندگان را در اولویت قرار داده است. App Router هنوز در مراحل ابتدایی خود است و مطمئناً مشکلاتی در حال رشد خواهد داشت. من اطمینان زیادی دارم که تیم Next.js این موارد را برطرف خواهد کرد (تیم عالی است و قبلاً به بسیاری از مسائلی که من مطرح کردم پرداخته است!). روتر برنامه ممکن است به عنوان "پایدار" علامت گذاری شود، اما صادقانه بگویم که هنوز برای من بسیار نوپا است.
چشم انداز پشت React Server Components و App Router الهام بخش است. با وجود تمام شوخیهایی که در مورد «اختراع مجدد» PHP توسط انجمن React وجود دارد، من واقعاً فکر میکنم Meta/Vercel کار واقعاً قابل توجهی انجام دادهاند، و هنگامی که همه پیچیدگیها را برطرف کنند، قطعاً بهترین راه برای ساخت برنامههای React خواهد بود. اما امروز به نظر می رسد که ما کاملاً در قلمرو "پذیرش زودهنگام" هستیم.
خوشحالم که وبلاگم را به App Router منتقل کردم (و وقتی مشکلات CSS حل شد احساس بهتری خواهم داشت) اما همچنین عجله ای برای انتقال پلت فرم دوره خود ندارم.
من حدود 7 سال است که React را تدریس می کنم. من شروع به تدریس در یک بوت کمپ کد نویسی محلی کردم، برنامه درسی React آنها را توسعه دادم و با دانش آموزان تک به تک کار کردم. من 22 مقاله در مورد React از طریق این وبلاگ منتشر کرده ام. و من شادی را آفریدم واکنش نشان دهید(در برگه جدید باز می شود)، یک دوره آنلاین جامع که به نحوه عملکرد React و نحوه استفاده موثر از آن می پردازد.
این دوره بر روی مکانیک اصلی React متمرکز است، اما آخرین ماژول تماماً در مورد مولفه های Next.js App Router و React Server است. در واقع، پروژه نهایی شما را مجبور می کند یک وبلاگ تعاملی بر اساس MDX بسازید. 😄
به نظر می رسد این است:


این پیچیده ترین چیزی نیست که در این دوره به آن می پردازیم، اما یکی از کاربردی ترین آنهاست. و بهترین بخش این است که می توانید از آن استفاده کنید به عنوان پایه ای برای وبلاگ واقعی شما! این فقط یک پروژه درسی تخیلی نیست، بلکه میتواند پایگاه دنیای واقعی شما در اینترنت باشد. 😄
در اینجا می توانید اطلاعات بیشتری کسب کنید:
آخرین به روز رسانی از
20 اکتبر 2026


