برنامه نویسی

یکپارچه سازی WebContainer API با Node.js

نوشته آنتونلو زانینی✏️

Node.js یک پلت فرم محبوب و قدرتمند برای ساخت برنامه های کاربردی وب مقیاس پذیر و کارآمد است. با این حال، در برخی موارد، ممکن است نیاز به ساخت یک برنامه Node.js برای اثبات مفهوم سریع یا با همکاری سایر توسعه دهندگان باشد.

ایجاد محیط‌های محلی می‌تواند یک ناراحتی بزرگ باشد، به‌ویژه هنگام تلاش برای نمونه‌سازی سریع ایده‌ها، آزمایش با کتابخانه‌های منبع باز، همکاری با همکاران یا بازتولید اشکالات. اینجاست که WebContainers مبتنی بر مرورگر وارد عمل می شود.

در این مقاله نحوه ایجاد محیط‌های Node.js فول استک که می‌توانند در عرض چند ثانیه راه‌اندازی شوند و بلافاصله با یک کلیک قابل دسترسی و اشتراک‌گذاری باشند، بحث خواهد شد. پوشش خواهیم داد:

WebContainers چیست؟

WebContainers مبتنی بر مرورگر، همچنین به عنوان کانتینرهای مبتنی بر وب شناخته می‌شوند، محیط‌های زمان اجرا هستند که به توسعه‌دهندگان اجازه می‌دهند بدون نیاز به نصب نرم‌افزار یا زیرساخت اضافی، کد را اجرا کرده و برنامه‌ها را در یک مرورگر وب اجرا کنند. این WebContainer ها معمولاً توسط فناوری هایی مانند Docker، Kubernetes یا WebAssembly پشتیبانی می شوند و یک محیط زمان اجرا سازگار و ایمن برای توسعه وب فراهم می کنند.

با WebContainers مبتنی بر مرورگر، توسعه‌دهندگان می‌توانند بدون نیاز به راه‌اندازی یک محیط توسعه محلی یا تکیه بر ماشین‌های مجازی مبتنی بر ابر، برنامه‌ها را مستقیماً در مرورگر بسازند، آزمایش کنند و مستقر کنند. در عوض، یک WebContainer یک محیط ایزوله در مرورگر ایجاد می کند که شامل تمام وابستگی ها، کتابخانه ها و منابع سیستم مورد نیاز برای اجرای یک برنامه است. این محیط جدا از ماشین محلی توسعه‌دهنده یا هر زیرساخت مبتنی بر ابر است و یک محیط اجرا سازگار و ایمن برای برنامه فراهم می‌کند.

توسعه دهندگان می توانند با برنامه در حال اجرا در WebContainers با استفاده از یک رابط مبتنی بر وب، که یک رابط کاربری گرافیکی برای تعامل با برنامه و فایل های مرتبط با آن فراهم می کند، تعامل داشته باشند. WebContainer API همچنین یک رابط خط فرمان برای اجرای دستورات سیستم و اجرای کد مستقیماً در مرورگر ارائه می دهد.

درباره پروژه نمونه ما

این مقاله شما را از طریق مراحل لازم برای ایجاد یک برنامه Express.js جدید و پیکربندی آن به عنوان WebContainer برای استقرار و مدیریت کارآمد برنامه های کاربردی وب راهنمایی می کند.

چه یک توسعه دهنده وب با تجربه باشید و چه تازه با WebContainers شروع کرده اید، این راهنمای عملی درک جامعی از نحوه شروع کار با WebContainers در Node.js ارائه می دهد.

شما می توانید کد منبع کامل این پروژه را در GitHub من پیدا کنید.

راه اندازی اولیه

برای شروع، ما یک پوشه جدید برای ذخیره پروژه خود ایجاد می کنیم:

mkdir WebContainers

cd WebContainers
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

یک پروژه جدید npm را راه اندازی کنید:

npm init
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مطمئن شوید که Node.js روی سیستم شما نصب شده است:

node -version
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر Node.js نصب نشده است، لطفاً راهنمای رسمی را برای نصب آن دنبال کنید یا از Node version manager استفاده کنید.

npm init دستوری است که برای مقداردهی اولیه یک پروژه جدید Node.js استفاده می شود. هنگامی که این دستور را در ترمینال خود اجرا می کنید، npm از شما می خواهد اطلاعاتی را در مورد پروژه خود وارد کنید، مانند:

  • نام پروژه
  • نسخه
  • شرح
  • نقطه ورود
  • نویسنده
  • مجوز

هنگامی که این اطلاعات را ارائه کردید، npm یک a ایجاد می کند package.json فایل را در فهرست راهنمای پروژه خود با تمام ابرداده ها و پیکربندی پروژه خود ارسال کنید.

را package.json فایل یکی از اجزای اصلی توسعه Node.js است زیرا حاوی وابستگی ها و اسکریپت های مورد نیاز برای ساخت، آزمایش و استقرار برنامه شما است. با دویدن npm init و با پر کردن اطلاعات لازم، می توانید یک پروژه Node.js جدید ایجاد کنید و به راحتی وابستگی ها و پیکربندی آن را با npm مدیریت کنید.

مطالب بعدی را به مطالب خود اضافه کنید index.html فایل:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>node.js WebContainers</title>
   <link rel="stylesheet" href="styles.css"/>
</head>
<body>
<div class="container">
   <div class="editor">
       <textarea>Editor</textarea>
   </div>
   <div class="preview">
       <iframe src="placeholder.html"></iframe>
   </div>
</div>
<div class="terminal"></div>
<script type="module" src="/index.js"></script>
</body>
</html>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اضافه کردن placeholder.html فایل برای نمایش محتوای اولیه در iframe:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Loading placeholder</title>
</head>
<body>
   Installing dependencies...
</body>
</html>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما از Vite برای ساخت و اجرای برنامه خود استفاده خواهیم کرد. آن را در زیر نصب کنید:

npm install vite@4.1.0
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

یک اسکریپت اضافه کنید تا برنامه ما در آن اجرا شود package.json:

{
 "name": "WebContainers",
 "version": "1.0.0",
 "description": "node.js WebContainers application",
 "main": "index.js",
 "scripts": {
   "start": "vite"
 },
 "dependencies": {
   "vite": "^4.1.0"
 }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون می توانیم برنامه اولیه خود را با این دستور اجرا کنیم:

npm start
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

شما باید برنامه ساده را در مرورگر خود مشاهده کنید. مکان پیش فرض در مرورگر است http://localhost:5173. برنامه ما در مکان پیش فرض مرورگر بیایید جذابیت بصری برنامه خود را افزایش دهیم. فایل را درج کنید styles.css:

* {
 box-sizing: border-box;
}

body {
 margin: 0;
 height: 100vh;
}

.container {
 display: grid;
 grid-template-columns: 1fr 1fr;
 gap: 1rem;
 height: 50%;
 width: 100%;
}

textarea {
 width: 100%;
 height: 100%;
 resize: none;
 border-radius: 0.5rem;
 background: black;
 color: greenyellow;
 padding: 0.5rem 1rem;
}

iframe {
 height: 100%;
 width: 100%;
 border-radius: 0.5rem;
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

راه اندازی مجدد برنامه؛ شما باید موارد زیر را ببینید: برای مشاهده استایل ما، برنامه را راه اندازی مجدد کنید

راه اندازی WebContainers با Express.js

Express.js یک چارچوب برنامه کاربردی وب برای Node.js است که به توسعه دهندگان اجازه می دهد برنامه های وب سریع و مقیاس پذیر با ویژگی هایی مانند میان افزار، مسیریابی و موتورهای قالب بسازند. این ساده و انعطاف پذیر است و آن را به یک انتخاب محبوب در میان توسعه دهندگان تبدیل می کند.

برای اهداف نمایشی، من آن را در برنامه خود ادغام کرده ام، اما در محیط تولید واقعی، برنامه Express.js ما جدا از برنامه اصلی ما خواهد بود. بعداً می‌توانید هر برنامه Express.js را به WebContainers متصل کنید.

ایجاد اپلیکیشن Express.js

یک پوشه جدید به نام ایجاد کنید app:

mkdir app
cd app
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

درون app پوشه، به دو فایل نیاز داریم: index.js و package.json. index.js یک برنامه ساده Express.js است که متن “Hello World” را بر روی آن برمی گرداند root مسیر:

import express from 'express';
const app = express();
const port = 3111;

app.get('/', (req, res) => {
 res.send('Hello World!');
});

app.listen(port, () => {
 console.log(`The application can be accessed at http://localhost:${port}, as it is now live.`);
});
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای اجرای برنامه باید وابستگی ها را نصب کنیم. موارد زیر را در قسمت اضافه کنید app/package.json فایل:

{
 "name": "example-app",
 "type": "module",
 "dependencies": {
   "express": "latest",
   "nodemon": "latest"
 },
 "scripts": {
   "start": "nodemon --watch './' index.js"
 }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

و وابستگی های خود را در داخل نصب کنید app پوشه:

npm install
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون می توانید برنامه Express.js خود را با دستور زیر اجرا کنید:

npm start
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

و نتیجه را در ادامه مشاهده کنید http://localhost:3111: در حال اجرای برنامه Express.js ما

یکپارچه سازی WebContainers

پس از اتمام کار با برنامه Express.js، می‌توانیم به پوشه ریشه برگردیم و به کار روی WebContainers ادامه دهیم:

cd ..
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اول از همه، اجازه دهید WebContainers را در برنامه خود نصب کنیم:

npm install @webcontainer/api@1.0.2
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما یک فایل به نام ایجاد می کنیم index.js، جایی که ما ثابت ها را برای دستکاری عناصر HTML و ایجاد یک نمونه WebContainers اعلام می کنیم:

import {WebContainer} from '@webcontainer/api'

const iframe = document.querySelector('iframe')
const textarea = document.querySelector('textarea')

let WebContainersInstance
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

یک شنونده رویداد بارگذاری برای شی پنجره اضافه کنید:

window.addEventListener('load', async () => {
   console.log('Window is loaded')
})
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد خودکار بارگذاری فایل

بیایید یک بارگیری خودکار فایل ایجاد کنیم تا مطمئن شویم که فایل‌های Express.js ما در WebContainers بارگیری می‌شوند.

یک فایل جدید ایجاد کنید autoloader.js و محتوای زیر را داخل آن قرار دهید:

const fs = require('fs')

const INPUT = 'app'
const OUTPUT = 'files.js'
// List of files to include into WebContainers
const files = ['index.js', 'package.json']
const exportLine = 'export const files = '

const content = {}

files.forEach(file => {
   const buffer = fs.readFileSync(`./${INPUT}/${file}`)
   content[file] = {
       file: {
           contents: buffer.toString()
       }
   }
})

fs.writeFileSync(OUTPUT, `${exportLine}${JSON.stringify(content, null, 2)}`)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

توصیه می شود اسکریپت های خود را به گونه ای آماده کنیم که این کد قبل از شروع پروژه اجرا شود. تغییر بخش اسکریپت در package.json فایل:

"scripts": {
 "start": "npm run prepare && vite",
 "prepare": "node ./autoloader.js"
},
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

آخرین تغییرات باید در index.js file: داده ها را از فایل ایجاد شده وارد کرده و آن را به پنجره ویرایشگر ما پیوست کنید:

// …
import {files} from "./files"

// …

window.addEventListener('load', async () => {
   textarea.value = files['index.js'].file.contents

   console.log('Window is loaded')
})
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون می توانید برنامه را اجرا کنید:

npm start
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مطمئن شوید که مطالب از شما app/index.js در پنجره ویرایشگر ظاهر می شود.

اجرای WebContainers

اکنون، یک نمونه WebContainers جدید را نمونه‌سازی می‌کنیم:

window.addEventListener('load', async () => {
   textarea.value = files['index.js'].file.contents

   WebContainersInstance = await WebContainer.boot()
   await WebContainersInstance.mount(files)

   console.log('Window is loaded')
})
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در بیشتر مرورگرهای محبوب، ممکن است با خطای یک قاب مسدود مواجه شوید. ما باید هدرهایی را برای مطابقت با پیکربندی Vite اضافه کنیم. ایجاد یک vite.config.js فایل با محتوای زیر:

export default {
   server: {
       port: 5173,
       headers: {
           'Cross-Origin-Embedder-Policy': 'require-corp',
           'Cross-Origin-Opener-Policy': 'same-origin',
       },
   }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس، صفحه را مجدداً بارگیری کنید (Control+Command+R در macOS، Control+Shift+R در ویندوز) برای جلوگیری از کش کردن و راه اندازی مجدد سرور Vite.

نصب وابستگی ها

زمان آن فرا رسیده است که وابستگی های پروژه Express.js را در داخل WebContainer نصب کنیم. تابع دیگری را به index.js فایل:

async function installDependencies() {
   const installProcess = await WebContainersInstance.spawn('npm', ['install'])

   installProcess.output.pipeTo(new WritableStream({
       write(data) {
          console.log(data)
       }
   }))

   return installProcess.exit
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این تابع را در load پاسخ به تماس:

window.addEventListener('load', async () => {
   textarea.value = files['index.js'].file.contents

   WebContainersInstance = await WebContainer.boot()
   await WebContainersInstance.mount(files)

   await installDependencies()

   console.log('Window is loaded')
})
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

پس از اجرای برنامه، می توانید کل فرآیند نصب وابستگی را در کنسول مرورگر مشاهده کنید.

اجرای یک سرویس Express.js در داخل WebContainers

ما آماده اجرای برنامه Express.js در داخل WebContainers هستیم. اضافه کردن یک تابع در index.js فایل:

async function startDevServer() {
   const serverProcess = await WebContainersInstance.spawn('npm', ['run', 'start'])

   serverProcess.output.pipeTo(new WritableStream({
         write(data) {
             console.log(data)
         }
     }))

   WebContainersInstance.on('server-ready', (port, url) => {
       iframe.src = url
   })
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این تابع را در داخل load پاسخ به تماس:

window.addEventListener('load', async () => {
   textarea.value = files['index.js'].file.contents

   WebContainersInstance = await WebContainer.boot()
   await WebContainersInstance.mount(files)

   await installDependencies()

   startDevServer()

   console.log('Window is loaded')
})
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

پس از نصب همه وابستگی ها، می توانید پاسخ برنامه express.js را در پنجره iframe مشاهده کنید.

ویرایش برنامه Express.js در داخل WebContainer

صرف خواندن برنامه Express.js بیهوده خواهد بود. ما باید توانایی اصلاح آن را داشته باشیم. یک تابع را اضافه کنید index.js فایل:

async function writeIndexJS(file, content) {
   await WebContainersInstance.fs.writeFile(`/${file}`, content)
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما می خواهیم همه رویدادهای ورودی را از پنجره ویرایشگر بگیریم و آنها را در پنجره منعکس کنیم iframe پنجره یک شنونده رویداد در داخل اضافه کنید load پاسخ به تماس:

window.addEventListener('load', async () => {
   textarea.value = files['index.js'].file.contents

   textarea.addEventListener('input', (e) => {
       writeIndexJS('index.js', e.currentTarget.value)
   })

   // …
})
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اضافه کردن ورود به سیستم زیبا با xterm

در اصل، ما برنامه اصلی Express.js خود را در یک WebContainer یکپارچه کرده ایم. با این حال، هدف ما این است که به جای اتکا به کنسول در مرورگر، لاگ زیبا را وارد کنیم. این یک راه راحت‌تر برای دسترسی به فایل‌های گزارش و حفاری در فرآیند نصب کامل وابستگی در صورت نیاز فراهم می‌کند.

بیایید یک وابستگی جدید نصب کنیم:

npm install xterm@5.1.0
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

xterm یک کتابخانه جاوا اسکریپت است که شبیه ساز ترمینال مبتنی بر وب با دنباله های فرار ANSI، کاراکترهای یونیکد و سایر ویژگی ها را ارائه می دهد. استفاده و سفارشی سازی آن آسان است و آن را به انتخابی محبوب برای افزودن رابط ترمینال به برنامه های کاربردی وب تبدیل می کند.

ما باید عنصر HTML را با کلاس ضبط کنیم terminal و ترمینال را به آن وصل کنید. وارد كردن xterm و سبک های آن به index.js:

//…
import {Terminal} from 'xterm'
import 'xterm/css/xterm.css'
//…
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

و یک متغیر برای عنصر HTML ترمینال اضافه کنید:

const iframe = document.querySelector('iframe')
const textarea = document.querySelector('textarea')
const terminalElement = document.querySelector('.terminal')
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ترمینال را در load پاسخ به تماس:

window.addEventListener('load', async () => {
   //…

   const terminal = new Terminal({
       convertEol: true,
   })
   terminal.open(terminalElement)

   //…
})
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما باید نمونه ترمینال را در تمام توابعی که به خروجی نیاز داریم پاس داده و آن را جایگزین کنیم console.log. Refactor the installDependencies تابع:

async function installDependencies(terminal) {
   const installProcess = await WebContainersInstance.spawn('npm', ['install'])

   installProcess.output.pipeTo(new WritableStream({
       write(data) {
           terminal.write(data)
       }
   }))

   return installProcess.exit
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همینطور برای startDevServer تابع:

async function startDevServer(terminal) {
   const serverProcess = await WebContainersInstance.spawn('npm', ['run', 'start'])

   serverProcess.output.pipeTo(new WritableStream({
       write(data) {
           terminal.write(data)
       }
   }))

   WebContainersInstance.on('server-ready', (port, url) => {
       iframe.src = url
   })
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نمونه ترمینال را به توابع موجود در load پاسخ به تماس:

await installDependencies(terminal)

startDevServer(terminal)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برنامه را مجددا راه اندازی کنید. نتیجه نهایی باید به این صورت باشد: برنامه نهایی ما در مرورگر اجرا می شود کل کد منبع را می توان در GitHub من یافت.

نتیجه

WebContainers مبتنی بر مرورگر وقتی با Node.js ترکیب می‌شوند، ابزاری قدرتمند برای توسعه‌دهندگان وب هستند، به خصوص اگر به دنبال ساده‌سازی فرآیند توسعه و بهبود گردش کار خود هستید. این کانتینرها راه حلی سبک و مقیاس پذیر برای ساخت و استقرار برنامه های کاربردی وب ارائه می دهند که به توسعه دهندگان این امکان را می دهد تا به راحتی کد خود را در یک محیط ایمن و ایزوله آزمایش و مستقر کنند.

از آنجایی که Node.js در توسعه وب همچنان محبوب است، WebContainers مبتنی بر مرورگر روشی نوآورانه و کارآمد برای استفاده از قابلیت‌های آن در تنظیمات جدید ارائه می‌کند. با گنجاندن این فناوری در گردش کار خود، می توانید بهره وری خود را افزایش دهید و برنامه های کاربردی وب با کارایی بالا را به راحتی ایجاد کنید.

به طور کلی، WebContainers مبتنی بر مرورگر با Node.js افزودنی ارزشمند برای هر جعبه ابزار توسعه وب هستند و پتانسیل آنها برای نوآوری و بهینه سازی فقط در آینده افزایش می یابد.


با ردیابی خطای Node مدرن LogRocket در چند دقیقه راه‌اندازی کنید:

1. برای دریافت شناسه برنامه به https://logrocket.com/signup/ مراجعه کنید.
2. LogRocket را از طریق NPM یا تگ اسکریپت نصب کنید. LogRocket.init() باید سمت مشتری نامیده شود نه سمت سرور.

NPM:

$ npm i --save logrocket 

// Code:

import LogRocket from 'logrocket'; 
LogRocket.init('app/id');
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برچسب اسکریپت:

Add to your HTML:

<script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

3. (اختیاری) پلاگین ها را برای ادغام عمیق تر با پشته خود نصب کنید:

  • میان افزار Redux
  • میان افزار ngrx
  • افزونه Vuex

در حال حاضر آغاز شده است

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا