چگونه یک وب IDE مانند codesandbox بسازیم؟

معرفی
من برای اولین بار در طول روزهای دانشگاهم از طریق پلتفرم های برنامه نویسی رقابتی آنلاین مانند leetcode و hackerrank با Web IDE آشنا شدم و از آن زمان مفهوم IDE یا ویرایشگرهای مبتنی بر وب همیشه در من نفوذ کرده است و این موضوع نسبتاً بسیار مهم است، من نتوانستم منابع زیادی در مورد آن پیدا کنم. کار می کند. با این حال، در پایان سال آخرم، یک نمونه اولیه وب IDE پیدا کردم که به شما امکان میدهد برنامههای React را در مرورگر بسازید، نمونه اولیه یک کاوشگر فایل، ترمینال کار، ویرایشگر کد و یک پنجره پیشنمایش زنده داشت. در آن زمان من آنقدر از کیفیت کد و معماری خود خجالت میکشیدم که پروژه را پست یا منبع باز نکردم. به سرعت به امروز، دوباره پروژه را مرور کردم، به اشتباهاتم خندیدم و در نهایت IDE را با بهترین دانشم بهبود دادم و اکنون تصمیم گرفتم آن را منبع باز کنم.
امکانات:
ویرایشگر کد (موناکو)
جستجوگر فایل
ترمینال Xterm.js
پشتیبانی از LSP (پروتکل سرور زبان).
پشته فنی:
Node.js
داکر
واکنش نشان دهید
پیاده سازی های موجود
قبل از توضیح اجرای ویرایشگر کد آنلاین، میخواهم به چند روش/وبسایت موجود دیگر مانند:
- VS Code.dev: Core VS Code منبع باز است (به غیر از بازار برنامه های افزودنی) و از آنجایی که با فناوری های وب مانند HTML، CSS و JS از طریق چارچوب الکترونی ساخته شده است، اکثر قسمت های جلویی ویرایشگر برای اجرا در یک مرورگر وب سازگار هستند، اما برای باطن ویرایشگر از سرورهای راه دور یا کانتینرهای docker استفاده می کند.
- StackBlitz: از WASM و WebContainers برای نیرو دادن به زمین های بازی کد خود استفاده می کند که کاملاً در یک مرورگر وب اجرا می شوند.
ساخت من:
از آنجایی که من میخواستم ویرایشگر خود را بسازم (یا حداقل مونتاژ کنم) VS Code رویکردی که به آن علاقه داشتم نبود. StackBlitz پیشرفتهتر و یک فناوری عالی است، اما محدودیتهایی برای انجام کارهایی وجود دارد که میتوان انجام داد. از طریق WASM
بنابراین رویکرد من این بود که تمام ابزارهای منبع باز موجود را انتخاب کنم و آنها را به هم بچسبانم تا به عنوان یک ویرایشگر وب اجرا شوند.
FrontEnd: من به ترتیب از monaco و xterm.js به عنوان ویرایشگر و ترمینال خود استفاده کردم (VS Code نیز از اینها استفاده می کند). من یک جزء کاوشگر فایل بازگشتی کوچک برای مشاهده، ایجاد و حذف فایل ها/پوشه ها نوشتم. کل ویرایشگر به لطف split.js پاسخگو است.
فرانت اند با react ساخته شده و به عنوان یک سایت ثابت در داخل سطل S3 من مستقر شده است.
پیوند به مخزن ظاهری
Backend: Backend در node.js نوشته شده است و در داخل یک داکر کانتینر اجرا می شود. Backend مسئول ارائه فایل های پروژه و نوشتن محتوا در فایل ها و همچنین ایجاد یک نمونه ترمینال برای کاربر (با امتیازات غیر ریشه) است.
پیوند به مخزن پشتیبان
کافی است کد به من نشان بده…!
برای ویرایشگر، بستهبندیهای react monaco زیادی وجود دارد، اما پس از آزمایش تعدادی از آنها، بهترین موردی که من پیدا کردم، از typefox به نام کلاینت موناکو زبان است. نکته مهم در مورد این این است که به طور یکپارچه با تقریباً تمام پسوندهای برجسته سازی نحوی در مقابل کد ادغام می شود و همچنین راهی برای ادغام سرورهای زبان بر روی سوکت های وب ارائه می دهد (این جالب ترین بخش است که در بخش بعدی در مورد آن توضیح خواهیم داد).
جالبترین بخش این مخزن این است که از پسوندهای کد VS موجود برای ارائه برجستهسازی نحو خاص زبان استفاده میکند (خط شماره 1 را بررسی کنید). اگر میخواهید برجستهسازی نحوی را خودتان بسازید، Monarch را بررسی کنید.
همچنین در اینجا می توانید پیکربندی golang lsp را ببینید، اما آنچه که هست LSP ?
LSP مخفف پروتکل سرور زبان. این اساساً یک زبان خاص است که به ویرایشگرهای کد و محیط های توسعه (مانند Visual Studio Code) اجازه می دهد تا با سرورهای زبان صحبت کنند.
این سرورهای زبان مانند برنامه های کوچکی هستند که زیر و بم یک زبان برنامه نویسی خاص را درک می کنند. ویرایشگر میتواند درباره کد شما سؤالاتی از سرور بپرسد و سرور میتواند ویژگیهای جالبی مانند تکمیل خودکار، یافتن خطاها، وارد کردن خودکار بستهها یا پرش به جایی که یک تابع تعریف شده است ارائه دهد.
قبل از اینکه مایکروسافت پروتکل LSP را معرفی کند، توسعهدهندگان زبان از پلاگینهای پشتیبانی زبان برای هر ویرایشگر خارج مینوشتند، اما اکنون به لطف این پروتکل، سرور زبان یک بار پیادهسازی شده و در همه جا استفاده میشود.
هنگامی که یک برنامه افزودنی پشتیبانی زبان در VS Code نصب می شود، اساساً برجسته سازی نحو را دریافت می کند و سرور زبان را راه اندازی می کند. VS Code سرور زبان نصب شده را به عنوان یک فرآیند اجرا می کند و از طریق تماس های Json-RPC ارتباط برقرار می کند. اما برای ویرایشگر وب ما نمیتوانیم این سرورهای زبان را در مرورگر اجرا کنیم، بنابراین سرور زبان را در داخل محفظه docker اجرا میکنیم و تمام تماسهای JSON-RPC انجام شده توسط ویرایشگر را از طریق یک اتصال سوکت وب به سرور زبان منتقل میکنیم. می توانید این را به عنوان راهی برای لوله کشی در نظر بگیرید | RPC از طریق سوکت ها تماس می گیرد.
{
serverName: "GOPLS",
pathName: "/gopls",
serverPort: 80,
runCommand: "gopls",
runCommandArgs: ["serve"],
}
برای کد کامل، مخزن باطن را بررسی کنید.
بیایید در مورد ترمینال صحبت کنیم
VS Code از Xterm.js برای ترمینال یکپارچه خود استفاده می کند. Xterm.js یک شبیه ساز ترمینال با اکوسیستم افزونه/افزودنی غنی است. از آنجایی که کل فضای کاری کاربر ما داخل یک داکر کانتینر است و فقط قسمت جلویی آن از طریق وب ارائه می شود، ما به راهی نیاز داریم تا شبیه ساز ترمینال Xterm.js خود را به فرآیندی متصل کنیم که به نوبه خود با pty در docker تعامل دارد.
برای رسیدن به این هدف، از node-pty، xterm.js attach on استفاده کردم. Node-pty یک فرآیند فرزند ایجاد می کند که می تواند مانند یک ترمینال واقعی با سیستم عامل تعامل داشته باشد، اما ما به راهی برای انتقال دستورات و پاسخ ها از وب به بک اند در حال اجرا در داخل کانتینر داکر نیاز داریم، برای این کار من از آن استفاده کردم. افزودنی را برای xterm.js ضمیمه کنید. این شبیه به راه اندازی LSP عمل می کند، یعنی، هر ضربه کلید در ترمینال (xterm.js) از طریق اتصال سوکت به پشتیبان منتقل می شود و سپس به فرآیند node-pty وارد می شود و پاسخ تولید شده به نوبه خود بازگردانده می شود.
کد پشتیبان برای ترمینال:
این بخش پایانه وب IDE را به پایان می رساند.
ویژگی های اضافی:
ما یک کاوشگر فایل و یک ترمینال داریم، از آنجایی که فایلها یا دایرکتوریها نیز میتوانند از طریق ترمینال اصلاح شوند، ما به راهی برای انتقال این تغییرات به frontend نیاز داریم. برای این کار من از Chokidar استفاده کردم، این بسته به ما امکان میدهد فایل سیستم تماشاگر را راهاندازی کنیم (nodemon از chokidar نیز استفاده میکند) و از طریق تماسهای بعدی میتوانیم تغییرات سیستم فایل را با هم ارتباط برقرار کنیم.
قطعه کد بالا به اضافه شدن فایل های جدید گوش می دهد و یک رویداد سوکت را به frontend می فرستد تا UI همگام بماند حتی اگر فایل ها از ترمینال یا هر فرآیند دیگری ایجاد شوند.
امنیت و استقرار:
از طریق یک وب IDE ما اساساً به افراد در اینترنت دسترسی به محاسبات ابری رایگان می دهیم و احتمال سوء استفاده عوامل مخرب از چنین سیستمی بالا است. از آنجایی که backend در docker است، ما به راحتی میتوانیم استفاده از CPU و حافظه هر کانتینر را محدود کنیم و به جای دادن دسترسی root به کاربر، میتوانیم یک کاربر با امتیاز پایین ایجاد کنیم و ترمینال را از طریق این کاربر پخش کنیم.
Dockerfile:
کانتینر docker را با دستور اجرا کنید
docker run -p 80:80 -d زمین بازی
این فقط یک پروژه کوچک سرگرم کننده است، به دور از اینکه یک ویرایشگر کد کامل و امن باشد، اگر مشکلی پیدا کردید، لطفاً آن را در github گزارش دهید.
اگر این مقاله برای شما مفید بود، یک 💖 اینجا یا یک ⭐ در github بگذارید.
برای مطالب جالب من را دنبال کنید
اجتماعی:
https://www.linkedin.com/in/abdul-mohammad-a567b2183/
https://github.com/iam-abdul