Skip to main content
LadeStack LogoLadeStack
Architecture 5 мин чтения 15 марта 2026 г.

Архитектура GB Coder: двухдвижковая среда веб-разработки в браузере

Технический разбор двухдвижковой архитектуры GB Coder: интеграция Monaco Editor с изолированной песочницей исполнения без задержек.

Схема двухдвижковой архитектуры GB Coder

Современные браузерные редакторы кода сталкиваются со сложной технической дилеммой: разработчикам необходимы интеллектуальный анализ кода, автодополнение и диагностика уровня настольной Visual Studio Code, но при этом требуется мгновенное выполнение с живым предпросмотром без зависания основного интерфейсного потока.

При проектировании GB Coder — флагманской веб-среды разработки LadeStack — мы отказались от ресурсоемких серверных контейнеров в пользу клиентской двухдвижковой архитектуры (Dual-Engine Architecture). В этой статье подробно рассматривается, как GB Coder координирует Monaco Editor, изолированные песочницы iframe и структурированные каналы сообщений для достижения субмиллисекундного цикла исполнения прямо в браузере.


Архитектурные вызовы браузерных IDE

Традиционные браузерные редакторы обычно тяготеют к одной из двух крайностей:

  1. Удаленные облачные виртуальные машины: Каждое изменение файла отправляется через WebSockets в серверный контейнер (Docker или микро-ВМ Firecracker). Обеспечивая совместимость с POSIX, этот подход порождает сетевые задержки, значительные постоянные затраты на инфраструктуру и полную неработоспособность в офлайн-режиме.
  2. Прямое выполнение в основном потоке: Простые песочницы выполняют код напрямую в контексте верхнего уровня с помощью eval() или бесконтрольной вставки DOM. Единственный бесконечный цикл while(true) намертво замораживает вкладку браузера, приводит к потере данных и создает угрозы межсайтового скриптинга (XSS).

GB Coder решает обе проблемы, физически разделяя языковой интеллект (статический движок) и среду исполнения (динамическая песочница).

┌────────────────────────────────────────────────────────┐
│               ОСНОВНОЙ КОНТЕКСТ БРАУЗЕРА               │
│                                                        │
│  ┌─────────────────────────┐  postMessage (RPC)        │
│  │   Ядро Monaco Editor    │ ──────────────────────┐   │
│  │ (AST / Синтаксис / Линт)│                       │   │
│  └─────────────────────────┘                       │   │
└────────────────────────────────────────────────────┼───┘
                                                     │
                                                     ▼
┌────────────────────────────────────────────────────────┐
│             ИЗОЛИРОВАННЫЙ КОНТЕКСТ IFRAME              │
│               sandbox="allow-scripts"                  │
│                                                        │
│  ┌─────────────────────────┐  Blob Object URL          │
│  │  Виртуальный DOM и лог  │ ◄──────────────────────   │
│  │ (Чистый изолированный)  │                           │
│  └─────────────────────────┘                           │
└────────────────────────────────────────────────────────┘

Движок 1: Интеграция Monaco Editor и языковые воркеры

Интерфейс редактора построен на движке Monaco Editor от Microsoft, выполняемом в выделенных Web Workers. Это гарантирует, что разбор синтаксического дерева (AST), сопоставление скобок и проверки типов TypeScript не конкурируют с потоком рендеринга пользовательского интерфейса.

// Инициализация пула воркеров Monaco
import * as monaco from 'monaco-editor';

self.MonacoEnvironment = {
  getWorkerUrl: function (_moduleId: string, label: string): string {
    if (label === 'typescript' || label === 'javascript') {
      return '/workers/ts.worker.bundle.js';
    }
    if (label === 'html' || label === 'handlebars') {
      return '/workers/html.worker.bundle.js';
    }
    if (label === 'css' || label === 'scss' || label === 'less') {
      return '/workers/css.worker.bundle.js';
    }
    return '/workers/editor.worker.bundle.js';
  }
};

Вынос анализа кода в фоновые потоки позволяет GB Coder стабильно сохранять частоту 60 кадров/с даже при наборе текста в объемных файлах на тысячи строк.


Движок 2: Изолированный контекст исполнения

Для отображения результатов выполнения без риска для безопасности и стабильности основного приложения, GB Coder динамически создает HTML-документ внутри изолированного контейнера <iframe>.

<iframe
  id="gb-preview-frame"
  sandbox="allow-scripts allow-modals"
  csp="default-src 'self' 'unsafe-inline' blob: data:; img-src * data: blob:;"
  src="about:blank"
  title="GB Coder Live Execution Preview"
  aria-label="Live Execution Sandbox"
></iframe>

Ключевым инженерным решением здесь является намеренное отсутствие атрибута allow-same-origin. Без него фрейм предпросмотра считается уникальным источником (null). Даже при выполнении небезопасного скрипта он физически не может получить доступ к:

  • Хранилищу LocalStorage и токенам ladestack.in
  • Файлам cookie и активным сессиям
  • DOM-дереву интерфейса оболочки IDE

Двунаправленный RPC: перехват консоли

Для вывода логов исполнения во встроенный терминал GB Coder песочница перехватывает штатные методы объекта console и сериализует аргументы через границу окон:

// Скрипт перехвата, внедряемый в песочницу
(function installConsoleProxy() {
  const originalLog = console.log;
  const originalError = console.error;

  function serialize(data) {
    try {
      return JSON.parse(JSON.stringify(data));
    } catch (e) {
      return String(data);
    }
  }

  console.log = function (...args) {
    window.parent.postMessage({
      type: 'GB_CODER_CONSOLE_EVENT',
      level: 'log',
      payload: args.map(serialize),
      timestamp: Date.now()
    }, '*');
    originalLog.apply(console, args);
  };

  console.error = function (...args) {
    window.parent.postMessage({
      type: 'GB_CODER_CONSOLE_EVENT',
      level: 'error',
      payload: args.map(serialize),
      timestamp: Date.now()
    }, '*');
    originalError.apply(console, args);
  };
})();

Основное приложение обязательно верифицирует отправителя события перед выводом данных в терминал:

window.addEventListener('message', (event: MessageEvent) => {
  const previewFrame = document.getElementById('gb-preview-frame') as HTMLIFrameElement;
  if (!previewFrame || event.source !== previewFrame.contentWindow) {
    return;
  }

  const { type, level, payload } = event.data ?? {};
  if (type === 'GB_CODER_CONSOLE_EVENT') {
    appendTerminalMessage(level, payload);
  }
});

Сравнительная таблица архитектур

Характеристика Облачные IDE (Docker) Прямой Eval в браузере Двухдвижковая GB Coder
Задержка исполнения 300 – 1200 мс (сеть) < 1 мс (опасно) < 2 мс (локальная память)
Офлайн-режим ❌ Требуется интернет ⚠️ Нестабильно ✅ 100% готов к офлайну
Защита от сбоев ✅ Хост защищен ❌ Вкладка намертво зависает ✅ Хост защищен изоляцией
Приватность данных ⚠️ Исходный код в облаке ✅ Локально ✅ 100% без отправки кода
Серверные затраты $5 – $25 в месяц / польз. $0 $0 (ресурсы клиента)

Надежная персистентность через IndexedDB

Чтобы защитить работу от случайного закрытия вкладки, GB Coder использует сохранение в локальную базу данных IndexedDB с дебаунсом 300 мс.

import { openDB } from 'idb';

const DB_NAME = 'gb_coder_workspace';
const STORE_NAME = 'project_files';

export async function persistActiveBuffer(filename: string, content: string): Promise<void> {
  const db = await openDB(DB_NAME, 1, {
    upgrade(database) {
      if (!database.objectStoreNames.contains(STORE_NAME)) {
        database.createObjectStore(STORE_NAME, { keyPath: 'filename' });
      }
    }
  });

  await db.put(STORE_NAME, {
    filename,
    content,
    updatedAt: Date.now()
  });
}

Заключение

Двухдвижковая архитектура наглядно доказывает: для профессиональной веб-среды разработки не требуются затратные серверные фермы. Разделение синтаксического анализа и изолированного исполнения обеспечивает молниеносный отклик, абсолютную приватность и нулевую стоимость инфраструктуры.

Опробуйте GB Coder в действии на странице описания GB Coder или запустите среду на code.ladestack.in. С дополнительными руководствами можно ознакомиться в документации для разработчиков.

More Engineering Articles