У рубриці DOU Проекторвсі охочі можуть презентувати свій продукт (як стартап, так і ламповий pet-проект). Якщо вам є про що розповісти — запрошуємо взяти участь. Якщо ні — можливо, серія надихне на створення власного made in Ukraine продукту. Питання і заявки на участь надсилайте на editors@dou.ua.
Привіт всім читачам! Мене звати Юрій. Я затятий «дотнетчик» або принаймні намагаюся виступати в його ролі :) Працюю з .NET Framework/Core близько 2 років, Angular/React — близько півроку. Вчився в основному сам, скажімо так, лопату в руки і до роботи! Подобається відкривати нові горизонти деяких технологій, таких як AI/ML, RoboTech, також хочу вивчити кілька мов програмування — RLang, Python. Вирішив написати про ідею, яку я розробляю близько півроку — двіжок, що дозволяє будувати динамічні сайти.
Ідея
Проект написаний на молодій платформі .NET Core 2.0, використовуючи .NETStandard2.0, реліз яких вийшов нещодавно. Двіжок вирішує проблему довгого завантаження сторінки і відкриває можливості для динамічного підвантаження виглядів (View). Він працює за таким самим принципом, як Angular.
Ідея написати таку штуковину з’явилася після роботи з ASP.NET Core MVC. Мені було цікаво, чому така сильна технологія не має часткового рендерінга виглядів на клієнтській частині. Почав читати, копати, стараючись добратися до самих глибин ASP.NET Core MVC. Також я працював з Angular 1/2 з Typescript. Так само стало цікаво, чому досі не було спроб зробити схрещену технологію, яка могла дозволити розробникам рендерити дані, як на сервері так і на клієнтській частині. Оскільки таких технологій не знайшов, вирішив написати свою. Тим більше було цікаво розібрати ASP.NET Core з середини, знайти всі його сильні і слабкі сторони, щоб я сам, як розробник, міг використовувати ці знання в роботі.
Реалізація
Для початку я хотів би висвітлити основний принцип роботи BibaViewEngine.
Користувач робить запит, як на звичайний сайт, за посиланням. Двіжок поверне index.html з вже підключеним скриптом, який запускає процес компіляції. Наступним прийде скомпільований основний компонент у вигляді HTML-коду з сервера, який розміститься у вказаному елементі на сторінці. Далі підключений скрипт буде шукати контейнери з раутингом і елементи з певним атрибутом, які будуть слугувати посиланням для раутінга і робити наступний запит на компонент по урлу, за яким перейшов користувач. По запиту сервер поверне скомпільований компонент. Далі, натискаючи на спеціальні посилання, скрипт буде робити запит на сервер і отримувати скомпільований HTML-код, вставляючи його в контейнер для роутів.
Тепер я би хотів поговорити про проблеми, з якими зіткнувся під час розробки BibaViewEngine.
Перше — це мало документації. Довелося ознайомитися з базовою документацією, що надає «Майкрософт». Потім «методом наукового тику» шукав потрібні мені АПІ, які би дозволили налаштувати базовий раутинг і компіляцію.
Наступною проблемою стала компіляція, а точніше вибір — написати свій компілятор чи знайти й використати існуючий. На своєму невеличкому досвіді випробував різні версії реалізації велосипеду, але все ж я, як і кожен програміст, з часом дійшов до висновку, що багато де реалізований велосипед — це краще, тому треба його відшукати і використати. Користуючись цим правилом, я намагався знайти компілятор, який зможе мені скопілювати і прирівняти якийсь простий вираз на в’юсі. Наприклад:
Context.Name + “ is the name of Context”.
Знайшов такий, але він мені не підійшов. Говорив з людьми в гіттері. Мені запропонували не легкий, як на мене, варіант, але робочий — шматок з реалізації інтерактивного рядка в Visual Studio. Вирішив відкласти це питання для наступних версій.
Незважаючи на ці переломні моменти, мені таки вдалося реалізувати невеличку частинку з бажаного, і про це я вам розкажу.
Оскільки я вирішив реалізувати паттерн MVVM, треба було чимось мотивувати цей процес. Я його мотивував компонентами з темплейтами. Компонент — це клас на серверній частині, який наслідує клас Component. До речі, цей принцип я запозичив у Angular 2. В коді виглядає так:
public class AppComponent : Component { public AppComponent(BibaCompiler bibaCompiler) : base(bibaCompiler) { } }
Базовий клас Component має в собі реалізацію компіляції темплейта, який пишеться разом з компонентом. Виглядає це так. Коли ви створюєте клас компонента, можна створити файл з такою самою назвою, що і клас, тільки з розширенням .html.
Client |-AppComponent.cs |-Appcomponent.html
Базовий клас при створенні екземпляру компонента з DI буде шукати файл з розширенням .html з такою ж назвою, що і .cs файл компонента, потім буде його компілювати, заміняючи значення в спеціальних дужках на значення з компонента. Наприклад:
AppComponent.cs public class AppComponent : Component { public string Title { get; set; } = “Hello world!”; public AppComponent(BibaCompiler bibaCompiler) : base(bibaCompiler) { } }
AppComponent.html<div><h1> ([Title])</h1></div>
Скомпільований темплейт буде виглядати так:
<div><h1>Hello world!</h1></div>
Наступний крок — раутинг.
Базова поведінка раутинга проста — на сервер від клієнта приходить запит з необхідним раутом, тобто посиланням на компонент. Сервер постарається знайти компонент в таблиці раутингів, потім створити екземпляр цього компонента, провести компіляцію і повернути скомпільований html клієнту.
Раутинг працює трішки складніше, ніж компіляція. Щоб отримати можливість використовувати раутинг, потрібно зробити такі кроки: створити роути на сервері; реалізувати контейнер і посилання на клієнті.
Клієнтська частина поки що має небагато можливостей і знаходиться на стадії глибокої розробки. Дуже багато фіч ще не готові, але в процесі. Тим не менше потрібний функціонал для роботи з базовими фічами вже готовий.
Бібліотечка для роботи з BibaViewEngine копіюється з файла-ресурсу BibaViewEngine в папку wwwroot під час запуску проекту і автоматично додає посилання на цей файл в index.html.
Результати
У підсумку можу сказати, що з цим пакетом цілком можна писати маленькі проекти. Але все ж він вимагає багато тестувань і доопрацювань.
Найголовніші цілі були досягнуті:
- Реалізовано компіляцію HTML з паттерном MVVM. Простенький компілятор, написаний мною.
- Простий раутинг. Можливість призначити на кожен раут окремий компонент.
- Компонентна система. Компонент може мати у собі темплейт, тобто HTML, який буде компілюватися з в’юмоделькою.
- Пробна версія активізації контролерів до рауту на клієнтській частині.
Плани:
- Розширити можливості компілятора або спробувати знайти краще рішення.
- Знайти і застосувати прирівнювач виразів (expresion evaluator).
- Реалізувати дочірні раути для основних.
- Застосувати авторизацію як мінімум для coockie. В подальшому — для JWT i OAuth.
Джерела з документацією: github.com/...iatorstorm/BibaViewEngine
Приклад: github.com/...torm/BibaViewEnginesample
Доступні фічі:
- Реалізація раутинга. Можна додати контейнер, в якому буде редеритися кожен темплейт з сервера (задокументовано).
- Можна створювати контролери, які активуються після отримання скомпільованого темплейта з сервера по рауту (не задокументовано). Цю фічу можна побачити наразі тільки в семплі за посиланням.
Насолоджуйтесь новими технологіями :)