Обычно под .NET разрабатывают в Visual Studio, собирая и запуская приложения локально на компьютере. А что если IDE работала бы прямо в браузере? Как Figma, только для .NET приложений.

Мы задались именно этой целью — сделать онлайн IDE для .NET.

Сейчас в нашем инструменте уже работает:

  • ✏️ Редактор UI на XAML (подмножество WPF) с drag-and-drop.

  • Компиляция C# и XAML полностью в браузере без участия сервера.

  • ?️ Запуск приложения прямо в браузере в изолированном окружении.

  • ☁️ Сохранение проектов на сервере и возможность скачать их для Visual Studio.

Можно поиграться и попробовать предварительную версию: https://xaml.io

А ниже — рассказ о том, как это всё работает под капотом.

История: от UI-редактора к IDE

Год назад мы сделали прототип UI-редактора на OpenSilver и запустили его как отдельное приложение в браузере. Я подробно писал об этом в предыдущей статье.

Мы думали, что это будет скорее демо, но браузерная версия неожиданно оказалась популярнее, чем мы ожидали.
И главный вопрос от пользователей был:

«А как написать code-behind

От этого запроса мы постепенно пришли к идее: А что если сделать полноценную IDE полностью в браузере? Так и появился этот проект.

Онлайн IDE: всё на OpenSilver

OpenSilver (GitHub) — это фреймворк с открытым исходным кодом, который позволяет запускать WPF и Silverlight приложения в вебе и других средах.

Наша IDE сама по себе является OpenSilver-приложением, написанным на XAML, C# и немного JavaScript. Это стало возможным благодаря WebAssembly: внутри браузера работает облегчённая версия Mono, а поверх неё — наше .NET-приложение.

Если открыть вкладку Network в DevTools, можно увидеть множество знакомых DLL из мира .NET. Размер загружаемых файлов может показаться большим, но это осознанное решение: мы не используем trimming и другие оптимизации, чтобы IDE могла поддерживать любые функции фреймворков, которые могут понадобиться в пользовательских проектах.

Логично, что разрабатываемые в онлайн IDE проекты — это тоже OpenSilver-приложения. Однако к ним можно относиться как к обычным WPF-проектам, ведь наша цель — максимальная совместимость.

Кстати, в любой момент текущий проект можно скачать и открыть в Visual Studio или VS Code, продолжив работу локально. Если установить одно из наших расширений, будет доступен и привычный UI-редактор.

Drag-and-Drop редактор

Мы хотели, чтобы интерфейсы можно было создавать максимально быстро и удобно — как в старые добрые времена WinForms, когда можно было просто перетащить элемент на форму и сразу увидеть результат.

В нашем редакторе есть библиотека из 100+ готовых компонентов, которые можно использовать прямо из панели инструментов. Просто перетаскиваете элемент на рабочую область — и он тут же появляется в визуальном редакторе, а XAML код автоматически обновляется в реальном времени.

Редактор поддерживает двухстороннюю синхронизацию:

  • можно изменять интерфейс как вручную в XAML файле,

  • так и через визуальный редактор — изменения будут моментально отражаться в обеих частях.

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

В результате мы получили инструмент, который помогает не просто верстать XAML, а полноценно проектировать интерфейсы в браузере.

Как работает компиляция в браузере

Компиляция — ключевой вызов для нашей идеи.
Мы решили попробовать запустить компилятор Roslyn прямо в браузере, чтобы весь процесс был полностью клиентским. Для этого использовали Nuget-пакет Microsoft.CodeAnalysis.CSharp.Scripting.

Компилятору надо предоставить ссылки на все используемые DLL во время компиляции. Пробовали разные подходы, в итоге пришли к выводу грузить DLL просто через HttpClient.

После нескольких экспериментов нам удалось всё завести!

В упрощённом виде процесс компиляции C# файлов выглядит так:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

// --- Входные данные ---
var baseUrl = "https://my-app.com";
var dllsList = new List<string>
{
    // e.g. "_framework/System.Runtime.dll"
};
var csSources = new List<string>
{
    "public class Foo { public int X => 42; }"
};

// --- Готовим все необходимое ---
var parseOptions = new CSharpParseOptions(LanguageVersion.Latest);
var httpClient = new HttpClient { BaseAddress = new Uri(baseUrl) };

var metadataReferences = await Task.WhenAll(dllsList.Select(async dll =>
{
    byte[] bytes = await httpClient.GetByteArrayAsync(dll);
    var ms = new MemoryStream(bytes, writable: false);
    return MetadataReference.CreateFromStream(ms, filePath: dll);
}));

var syntaxTrees = csSources.Select(src => CSharpSyntaxTree.ParseText(src, parseOptions));

// --- Компилируем ---
var compilation = CSharpCompilation.Create(
    assemblyName: "MyAssemblyName",
    syntaxTrees: syntaxTrees,
    references: metadataReferences,
    options: new CSharpCompilationOptions(
        OutputKind.DynamicallyLinkedLibrary,
        optimizationLevel: OptimizationLevel.Release,
        concurrentBuild: false
    )
);

using var peStream = new MemoryStream();
var emitResult = compilation.Emit(peStream);
if (!emitResult.Success)
{
    var diagnostics = string.Join("\n", emitResult.Diagnostics.Select(d => d.ToString()));
    throw new Exception("Compilation failed:\n" + diagnostics);
}

peStream.Position = 0;
byte[] dllBytes = peStream.ToArray();

А полный процесс сборки приложения:

  1. Получаем .xaml и .cs файлы.

  2. Транспилируем XAML в C#. Для этого у нас есть написанный нами транспилятор.

  3. Все полученные C# файлы компилируем в dll c готовым приложением.

Проблема: заморозка интерфейса

Roslyn — мощная штука, но инициализация компилятора на старте занимает 3-5 секунд. Это не критично, но блокировать UI на всё это время — так себе идея.

Решение — вынести компиляцию в Web Worker, чтобы не блокировать главный поток браузера.

Так как OpenSilver приложения совместимы с Blazor, мы использовали пакет KristofferStrube.Blazor.WebWorkers.

Теперь компиляция работает в отдельном потоке:

  • IDE отправляет в воркер сообщение.

  • Воркер компилирует проект.

  • В ответ возвращает готовую dll.

Запуск приложения

Хорошо, мы получили готовую dll. Теперь её нужно запустить.

В OpenSilver есть несколько загрузчиков (launchers):

Для онлайн IDE мы используем Browser загрузчик.

Всё работает через iframe:

  1. В iframe открывается загрузчик.

  2. IDE передает ему скомпилированные dll-ки.

  3. Приложение запускается прямо в браузере.

Как IDE остаётся отзывчивой при сбое приложения

Во время разработки пользовательский код может вести себя непредсказуемо — например, зависнуть из-за ошибки или начать выполняться бесконечно. Если бы приложение выполнялось в том же процессе, что и IDE, это могло бы заблокировать интерфейс и сделать невозможным дальнейшую работу.

Чтобы избежать этого, мы разделили окружения:

  • IDE работает на одном домене и остаётся полностью изолированной.

  • Приложение запускается в iframe на другом домене, в своём собственном контексте выполнения.

Благодаря этому, даже если запущенное приложение зависнет, IDE останется отзывчивой. В крайнем случае браузер автоматически завершит проблемный процесс, не затрагивая саму IDE.

Планы на будущее

К сожалению, не всегда получается уделить достаточно времени IDE, поэтому движемся небольшими шагами.

Вот что хотим сделать в обозримом будущем:

  • Автодополнение C# кода
    Планируем поднять языковой сервер в Web Worker.
    С C# есть надежда на Roslyn.
    С XAML будет сложнее, но мы думаем, как подойти к этой задаче.

  • AI-ассистент
    Сейчас у нас есть ассистент, который помогает писать XAML-код.
    В будущем мы хотим интегрировать полноценного ассистента, который сможет написать целое приложение.

    Мы рассчитываем не писать такого ассистента с нуля, а найти готовое решение — на C# или JavaScript — и встроить его в нашу IDE.
    Все необходимые условия у нас уже есть: IDE умеет управлять проектом, компилировать код, получать ошибки и запускать приложение.
    Этого должно быть достаточно, чтобы подключить внешнего ассистента прямо в браузере.

  • Возможность делиться проектами
    Уже в разработке. Можно будет отправить ссылку и показать свой проект коллегам или друзьям.

  • Оптимизировать производительность
    Тут много над чем надо поработать.

Попробовать самому

Можно попробовать прямо сейчас:

  1. Заходим на xaml.io

  2. Набрасываем интерфейс через drag-and-drop или пишем XAML вручную.

  3. Добавляем C# код.

  4. Нажимаем Run и запускаем приложение в браузере.

Заключение

Надеемся, вам понравится наша онлайн IDE и вы найдете её полезной.
Спасибо всем, кто дочитал статью до конца — ваш интерес мотивирует нас развивать проект дальше!

Комментарии (3)