Не знаю как до вас донести это, и насколько осторожно следует подбирать слова.
Мне больно от того, как сейчас происходит создание пользовательских интерфейсов, а существующие подходы кажутся каким‑то недоразумением. И поймите, речь обо всех платформах — веб, мобилки, десктоп. Будучи разработчиком, и исследуя «новые» способы реализации UI, сквозь годы опыта смотришь на все это дело с тяжелым вздохом, мотаешь головой из стороны в сторону, и все что хочется — захлопнуть крышку ноутбука и заняться чем‑то другим. А сталкиваясь с этим изо дня в день на работе — не знаю, как мы не кричим от этого, правда не знаю.
И нет, не стану говорить о том, что текущие инструменты не работают, это неправда. Приложив достаточное количество усилий, и да, возможно, несколько раз ударив себя же по лицу, вы с их помощью выполните все или почти все возложенные на вас задачи.
Вопрос лишь в том — какой ценой.
Простите за банальнейший пример с молотком, но взяв вместо него плоскогубцы или кирпич, расправиться с гвоздем в целом тоже не проблема. Да, пока вы будете орудовать этим, придется отбиваться от других, выкрикивая — «ну забивается же, че вы?!».
Но, по итогу свою задачу вы выполните.
Вопрос все тот же — насколько это было целесообразно, удобно, эффективно и безопасно?
(говорить будем преимущественно за веб)
Да, вероятно если зарыться куда‑то глубоко, в исходники любой из платформ, можно попытаться найти какой‑то базовый архитектурный изъян, некое аппаратное ограничение, несовместимость, или выявить изначально неверный подход. Даже если вы отыщете подобное, начинать лечение системы с такого несколько глупо, — на это, по сути, нельзя повлиять. Нельзя просто взять и внести изменения во что‑то фундаментальное, особенно когда на нем держится почти весь интернет, и когда оно не принадлежит вам. И точно также не имея за спиной достаточной поддержки сообщества, ресурсов корпорации, или феи на плече — нельзя просто взять и написать весь веб с 0.
Поэтому начнем с чего‑то более высокоуровневого, с чего‑то более доступного, с того, что по сути, находится в нашей ответственности, как frontend‑разработчиков и касается каждого из нас.
Но прежде небольшое отступление.
Позвольте напомнить, что на дворе уже почти 2025ый. Всесторонняя цифровизация, повсеместные нейросети, 5g, блокчейн, роботы, электрокары, спутники, Илон Маск в конце концов.
Тому же вебу уже сколько? 35 лет? А сколько длится борьба ui‑фреймворков? лет 20?
А сколько их было, в том числе непопулярных? Сотня, две?
Ну довольно, вернемся к нашей теме.
Начнем с кусочков кода — освежим картинку в голове.
Просто бегло посмотрите на это. У меня ощущение что можно вообще ничего не говорить.
React
<div>
<h1>Todo List</h1>
<input
type="text" value={newTodo}
onChange={(e) => setNewTodo(e.target.value)} placeholder="Add a new task"
/>
<button onClick={addTodo}>Add Todo</button>
<ul>
{todos.map(todo => (
<li key={todo.id}>
{todo.text}
<button onClick={() => removeTodo(todo.id)}>Delete</button>
</li>
))}
</ul>
</div>
Vue
<div>
<h1>Todo List</h1>
<input v-model="newTodo" type="text" placeholder="Add a new task" />
<button @click="addTodo">Add Todo</button>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
<button @click="removeTodo(todo.id)">Delete</button>
</li>
</ul>
</div>
Angular
<div>
<h1>Todo List</h1>
<input [(ngModel)]="newTodo" placeholder="Add a new task" />
<button (click)="addTodo()">Add Todo</button>
<ul>
<li *ngFor="let todo of todos">
{{ todo.text }}
<button (click)="removeTodo(todo.id)">Delete</button>
</li>
</ul>
</div>
Svelte
<div>
<h1>Todo List</h1>
<input bind:value={newTodo} placeholder="Add a new task" />
<button on:click={addTodo}>Add Todo</button>
<ul>
{#each todos as todo (todo.id)}
<li>
{todo.text}
<button on:click={() => removeTodo(todo.id)}>Delete</button>
</li>
{/each}
</ul>
</div>
Верно, это просто синтаксис шаблонов основных фронтовых фреймворков и библиотек.
(верстка ToDoList)
Что объединяет все примеры?
HTML и схожие конструкции? Возможно, но нет. Суть в том что все это лишь синтаксический сахар.
Напомню, синтаксический сахар — способ написания кода, с целью сделать его более понятным, уместным и удобным для программиста. Еще раз, суть синтаксического сахара — упростить код, сделать его более выразительным, при этом не изменяя базовую функциональность языка. Если посмотреть на это обывательски — он может быть абсолютно любым, — вы можете пихнуть в него всего пару букв, или матерное слово, или даже вставить эмоджи, а на выходе все это дело будет преобразовываться в реальный код. Таким образом вы можете скрыть вызов одной маленькой функции, или целую портянку длиной в несколько модулей всего за одну букву.
Что это дает? Как минимум — возможность реализовать это иначе.
Забудьте на минуту о своем прошлом опыте, нюансах реализации фронтенда, веба, о тех.наследии, о том как работает святая троица и как происходит рендеринг, про общепринятость и нормы. С учетом абзаца выше, ответьте себе — разрабатывая синтаксис для описания пользовательских интерфейсов, имея абсолютно развязанные руки, вы бы тоже сделали его таким? Тоже бы проектировали его похожим на старую разметку, использовали бы теги, угловые скобки для них? Также маскировали бы название компонента под тег? Слепили бы в нелепую кашу html css и js? Реализовали бы основные конструкции рендеринга именно так?
Добрая половина интернета уже давно не просто странички в браузере, это полноценные приложения, некоторые из которых столь огромны что с их объемом не справляются современные IDE (да, монолиты исчезают, но их по‑прежнему много).
Меняются потребности, мы в поисках новых подходов — к реактивности, к способу задания стилей, к организации кода, к стандартизации. Так почему не сделать некоторую небольшую «революцию» в сторону иного синтаксиса.
Почему бы не сделать его более приятным, более простым, чистым, и читаемым, более нативным в конце концов.
Как мы знаем, интерфейсы, это далеко не только веб.
Так что давайте посмотрим — что там у других.
Небольшая историческая справка:
android
до 2017 - Интерфейс создавался через XML, основной язык — Java
2017 - Основным языком для разработки становится Kotlin
2020 - Jetpack Compose позволяет разрабатывать UI без XML, используя Kotlin
ios
до 2014 - UI строится на Objective-C с XML-подобной разметкой
2014 - Появление Swift с простым синтаксисом
2019 - SwiftUI заменяет XML-разметку на декларативный синтаксис
ios/android
2018 - выход первой версии Flutter
Посмотрим, как это все выглядит
Java, Kotlin (до появления Jetpack Compose)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter new task"
android:inputType="text" />
<Button
android:id="@+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Todo" />
<RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Kotlin + Jetpack Compose
Column(modifier = Modifier.padding(16.dp)) {
Text(text = "Todo List", style = MaterialTheme.typography.h5)
TextField(
value = newTodo,
onValueChange = { newTodo = it },
label = { Text("Add a new task") },
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp)
)
Button(onClick = {
if (newTodo.isNotBlank()) {
todos = todos + Todo(newTodo, Random.nextInt())
newTodo = ""
}
}) {
Text(text = "Add Todo")
}
Spacer(modifier = Modifier.height(16.dp))
LazyColumn(modifier = Modifier.fillMaxWidth()) {
items(todos) { todo ->
TodoItem(todo = todo, onDelete = { id ->
todos = todos.filter { it.id != id }
})
}
}
}
SwiftUI
some View {
VStack {
TextField("Add a new task", text: $newTodo)
.padding()
.textFieldStyle(RoundedBorderTextFieldStyle())
Button(action: {
if !newTodo.isEmpty {
todos.append(newTodo)
newTodo = ""
}
}) {
Text("Add Todo")
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(5)
}
List(todos, id: \.self) { todo in
Text(todo)
}
.padding()
}
.padding()
}
Flutter
Scaffold(
appBar: AppBar(
title: Text('Todo List'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextField(
controller: _controller,
decoration: InputDecoration(labelText: 'Add a new task'),
),
SizedBox(height: 10),
ElevatedButton(
onPressed: _addTodo,
child: Text('Add Todo'),
),
SizedBox(height: 20),
Expanded(
child: ListView.builder(
itemCount: _todos.length,
itemBuilder: (ctx, index) {
final todo = _todos[index];
return ListTile(
title: Text(todo['text']),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => _removeTodo(todo['id']),
),
);
},
),
),
],
),
),
);
Если отбросить сложный анализ с уклонном на особенность платформ, реактивность и прочие нюансы, глядя на любой из примеров можно увидеть следующие. У нас есть теги/компоненты, наша задача — выстроить из них некую композицию, передать в них необходимые пропс, связать их с данными, навесить на них слушатели, и прописать некоторую минимальную логику.
Это, пожалуй, все основные составляющие шаблона. Где остальное? где‑то выше или ниже, в теле компонента. А шаблон должен быть чистым. Иначе как вы его потом читать будете?
Да, я не шибко в восторге от реализаций на мобилках, их шаблоны по‑прежнему полны излишеств, и поэтому выглядят крайне грязно. Но то, что они сделали в свое время и впрямь революция. Думаю, не трудно догадаться что я предвзят к html/xml, и поэтому рад что подобный синтаксис, хотя бы на этих платформах ушел в прошлое, или преимущественно был спрятан под капот. Также не поддерживаю подход с полным отделением верстки от логики, не вижу, как это возможно в современных реалиях (про xml).
Ну что, у вас есть: tagName, props и children.
Еще раз: input, { name: "", onClick } и someChild. Осталось только объединить их (ну почти)))
И на этом все? Пока да.
Разумеется, дело не только в шаблоне.
Да и данная работа — лишь вступление, в одну статью все разом не впихнуть.
Ее цель только в том, чтобы спросить вас — вам правда нравится описывать шаблоны компонентов подобными способами? Не видите ли в этом чего-то отталкивающего, чего-то что можно качественно улучшишь? Скажите, вас правда не тошнит с текущих подходов веба, с существующих фреймворков, и той же верстки?
И нет — не призываю вас идти на баррикады, или бросать любимое дело, фреймворк, или работу.
Просто хочу чтобы вы осознали — рано или поздно это случится, мы уйдем от старых подходов, какими бы фундаментальными и устоявшимися они не казались.
Год, два, пять... Все это произойдет, вот увидите
Это моя первая публикация. Не знаю - надо ли оно вообще кому‑то или нет.
Пока я окончательно не выгорел и не бросил свое ремесло, возникла мысль написать серию статей касательно фронтенда, веба, разработки в целом, и вероятно на некоторые другие общие около ит‑шные темы. Возможно, найдутся люди, которым пригодились бы мои наработки, сэкономили бы им какое‑то время — несколько месяцев или даже лет.
Посмотрим, как пойдет, и возможно все это будет и на ютубе, а возможно и нет, в общем напишите что‑нибудь нехорошее снизу, спасибо!
Комментарии (54)
Synopticum
08.12.2024 10:37Что сказать-то хотел?
fcrng Автор
08.12.2024 10:37Существующие подходы к разработке интерфейсов не соответствуют времени,
требуют значительных качественных улучшений.
например - стоит пересмотреть синтаксис шаблонов, и это только самое начало.
(одна из целей статьи - поставить под сомнение текущий синтаксис и решения)
это вводная статья, более подробный разбор и конкретные реализации будут дальше
VasiliiV
08.12.2024 10:37Я сам долго читал и думал о чем же речь…на половине остановился. Спасибо в любом случае за статью автору.
jonic
08.12.2024 10:37Все это сводится к тому что шаблон не один файл как мы привыкли в года сайтостроения, да и тогда это было плохим тоном, за это какашничество пхп и не любили в том числе. Декларативный стиль гораздо удобнее, просто оперировать надо именно что компонентами ui. Например - компонент карточки товара, который в свою очередь состоит из более простых компонент (заголовок, карусель, описание, кнопка корзины, стилизованный контейнер), которые часто даже state less. В чем проблема то?
fcrng Автор
08.12.2024 10:37Один файл = один компонент
Шаблон в нынешних условиях не отделим. Да, он может прилетать на фронт отдельно,
в виде верстки. но потом гидратация, и на нем уже навешана вся логика.
Но отделить его в процессе разработки при декларативном подходе - нереально.
Да, декларативный подход эффективнее,
но должна оставаться возможность работать с каждым компонентом/тегом по отдельности
Ничего против него не имею, речь лишь о его синтаксисе
Чем высокоуровневые компоненты, тем интереснее, вы правы.
Проблема в синтаксисе.
В том что js, css, html хоть и являются отдельными языками, но в текущих
условиях мы используем их вместе, как единое целое.
Отсюда и рождаются эти нескончаемые выдуманные синтаксисы, где код мы пишем в строку,
(htm`<input name={name} />`) в виде неуклюжего месива из трех технологий.
Суть в том что этот синтаксис можно значительно улучшить, сделать нативным
тема последующих докладов.
victor-homyakov
08.12.2024 10:37Слепили бы в нелепую кашу html css и js?
js, css, html хоть и являются отдельными языками, но в текущих условиях мы используем их вместе, как единое целое
(htm
<input name={name} />
) в виде неуклюжего месива из трех технологийНигде - ни в статье, ни в комментарии выше - не увидел ни капли CSS. Вы точно понимаете, что такое CSS?
fcrng Автор
08.12.2024 10:37Не хотелось загрязнять примеры еще сильнее
Да и не влезет все в одну статью, если еще и за css расписывать)
Хотя, вы правы - упомянул, стоило хотя бы в примеры добавитьНа всякий, отпишусь какое отношение css имеет к шаблону
Шаблон = верстка (html + css) + логика (js)
css = стили
они кладутся в отдельный файл, либо лежат рядом с компонентом как во вью и свелт, либо используются с помощью css-in-js, как часто бывает в реакт.
Но в том или ином виде стили присутствует в шаблоне
Самый «безобидный» вариант — это конечно className: "wrapper" и вынос стилей за скобки
Но на деле они могут быть объявлены таким <StyledButton />
таким className={styles.button}, таким style={{ color: '#333' }}
или таким способом className="flex justify-center"полагаю это тема отдельной статьи
jonic
08.12.2024 10:37Воу Воу, полегче. Суть того что у вас простыни в непонимании разделения на компоненты. Я же специально сказал, что например есть компонент заголовок, картинка, описание, кнопка. Из этих компонент делаются компонент карточек. Оборачивается все это в компонент страницы, компонент списка. На этом этапе мы уже биндим реальные данные. И компонент страниц буквально втыкаем в компонент навигации, при этом нам без разницы будет это вся страница, модалка или сайд бар - при грамотном подходе везде отобразится ровно то что нам нужно. Это и называется декларативно. Это и значит что мы в любом момент времени можем взять компонент и его зависимости компонентов и проверить. А можем взять компонент и замокать его дочерние компоненты что бы проверить логику. И это лучше чем кидать все в кучу или размывать по дереву в далекие дали.
fcrng Автор
08.12.2024 10:37Вероятно мы недопоняли друг друга. Возможно виной тому то, что я не дописал фразу
"Шаблон не отделим от КОМПОНЕНТА" Именно поэтому там "1 файл = 1 компонент".
Ну и пошло поехало. А с вашим текущим комментарием я полностью согласен)
nin-jin
08.12.2024 10:37Я просто оставлю это здесь: https://page.hyoo.ru/#!=xl437w_w1mpfo
fcrng Автор
08.12.2024 10:37Ну, тут хотя бы уместно) Хорошая статья, жаль только, что снова сводите все к своим кракозябрам
deeemons
08.12.2024 10:37Не понял, против чего готовим революцию. Увидел вопросы к угловатым скобочкам (согласен, не очень красиво) и общие рассуждения, что подход устарел. Можно пример по существу? PS читал часть про фронтенд
fcrng Автор
08.12.2024 10:37Против текущих подходов. В данном случае - против текущего синтаксиса шаблона.
Шаблон может быть написан нативно, без применения синтаксического сахара.
В нем необязательно использовать теги, и совсем необязательно указывать атрибуты каким-то странным способом. Например так name={name} или так :key="todo.id".
Тоже самое касается стилей и логических конструкций, если посмотреть в примеры - каждый фреймворк имеет свой "уникальный" синтаксис для их реализации, чего можно избежатьStepanovAlex
08.12.2024 10:37Вы против "однообразной рутины кода"?
Есть мнение, что эффективный путь - использовать нейронки, настроив контекст так чтобы сформулировать задачу для конкретного UI структурно, на русском языке, и получить нужный код. Этот путь уже приводит эффективно к результатам и имеет большие перспективы, в отличие от пути придумывания очередного универсального фреймфорка для веб.fcrng Автор
08.12.2024 10:37Правда не знаю как вам ответить)
Не уверен, но вроде еще не настал тот страшный момент, когда нейросеть просто отсматривает весь код проекта, принимает на вход задачку из джиры и заливает свое решение на гитхаб за нас. Во всяком случае пока это не универсально)
Рутина пока никуда не ушла, и не уйдет. Верстку с макета все еще переносим мы. Даже если это сделать кодгеном - за ним все по прежнему придется править и проверять. Если гпт накидает вам какой-то код - вам его читать, обдумывать и проверять. На чем этот код будет написан? На тех же самых кривых инструментах.
Что-то изменилось? Пока не особо, хотя в части нового способа поиска информации и набрасывания структуры, - гпт неслабо выручает и меняет игру уже несколько лет.Код мы чаще читаем чем пишем => спрятаться от страшного кода накрыв лицо ладонями не выйдет.
Если что без негатива)
powerman
08.12.2024 10:37В целом, идея описывать шаблоны на основном языке разработки (если я правильно понял куда Вы клоните в статье) не нова, и вполне жизнеспособна. Но и пользу от синтаксического сахара не стоит недооценивать. Просто в качестве сахара иногда может выступать удачный API вспомогательной библиотечки-хелпера, с помощью которой и на основном языке можно сделать приемлемо выглядящий DSL.
fcrng Автор
08.12.2024 10:37Думаю вы первый, кто выкупил суть, во всяком случае среди комментирующих)
В статье я ругался не на сахар, а на его синтаксис в текущих решениях.
Но вообще да, при хорошей возможности, я бы конечно избегал его использования
kaskolive
08.12.2024 10:37Вода, вода. Как хорошо что автор сгорел. Даже любопвтно в каком возрасте это произошло.
fcrng Автор
08.12.2024 10:37Пояснили бы хоть немного за воду)
А про выгорание - к возрасту оно никак не привязано.
17, если хотите, или 37. что меняет то это)
годы опыта тут тоже особо не причем. кто-то выгорает уже спустя год, а кто-то в ит всю жизнь и что скажут ему то и делает, ни шага влево ни шага вправо, и про выгорание знать не знает
hint000
08.12.2024 10:37Надеялся, что будет о том, что гвозди UI забивают очень криво. С одной стороны доски торчит шляпка, с другой стороны вылазит остриё гвоздя, штаны порвёшь в любом случае. Но [пока] свелось к тому, что если их криво забивать правильным молотком, то будет гораздо лучше. :) Да, в массе своей UI ужасны, в вебе, на мобилках и на десктопе. Не только из-за забивания кирпичами. И статьи с критикой очень нужны, чтобы хоть каждый следующий разработчик не шел по тем же самым граблям, по которым уже прошла целая армия. Всё равно спасибо, что поднимаете тему.
supercat1337
08.12.2024 10:37Чтобы не было каши в коде, html, css и js отделяют друг от друга. Каша приемлема, если компонент маленький, потому что все лежит рядом и все на поверхности.
Не спроста же придумали отделять вёрстку, стили, скрипты. Стратегия разделения нативных html, css, js существует с момента их изобретения. Обычно вся путаница начинается там, где нужно связывать эти области:
html - js: биндинг к элементам страницы, создание, удаление, работа с событиями
html - css: там больше вопрос идёт про элегантное использование стилей в локальном скопе, чтобы они не влияли глобально на весь документ. Уже скоро проблемы не будет в связи с реализацией css scope.
js - css: мало, кто работает с CSSOM, но тем не менее, часто встречается в кейсах, когда надо подгружать новую цветовую тему для интерфейса. Обычно пара строк кода, которая сводится к удалению и подгрузке нового stylesheet.
Даже если проблемы выше каким-то способом решены, то следующим вопросом становится возможность переиспользования, тут обычно говорим о компонентном подходе, о способах интеграции компонента в документ через html или JavaScript.
А какую проблему из перечисленных выше решает ваш новый шаблонизатор? Будет он работать в рантайме или нужна транспиляция?
fcrng Автор
08.12.2024 10:37По отдельности, как это было когда-то они используются все реже. Несколько раз написав лендос или что-то другое - приходим сперва к библиотеке, потом к фреймворку.
А поскольку современные приложения переполнены логикой, это ведет к тесному переплетению трех технологий. Через жс мы заправляем по сути вообще всем. Хотя несомненно часть фич реализуется так сказать по старинке. С использованием всех возможностей, селекторов и тд.
Основной посыл статьи - поставить под сомнение текущие реализации шаблонов.
Предложить людям подумать на эту тему. Представить каким этот шаблон мог бы быть, и подумать что не так с существующими. Прямых ответов я здесь пока не давал.
Если посмотреть на рынок - все хотят транспилируемый - 100. Но даже для него можно попробовать прокачать синтаксис.
Мне по душе полная нативность и рантайм. Хотелось бы чтобы для разработчика за все на фронте отвечал js. А что и как будет спрятано за ширму - дело реализации.supercat1337
08.12.2024 10:37Ну, вот ради интереса. Скажите, что не так в этом коде:
// empty ref object for dom-element const output = new Ref; // create reactive item const counter = new Atom(0); function minus() { counter.value--; } function plus() { counter.value++; } // create dom-tree and bind refs to elements const fragment = html` <div> <button @click="${minus}"></button> <text-node ref="${output}"></text-node> <button @click="${plus}"></button> </div> `; bindToText(counter, output.element); document.body.append(fragment.element);
Этот код нативный, без транспиляции, работает c использованием сторонних библиотек.
fcrng Автор
08.12.2024 10:37Нативность всегда приветствуется отдельным респектом
Но как по мне, если интересует лишь она, а на остальное в общем то плевать, можно просто взять preact или еще что-то такое
Первое что бросается в глаза в вашем примере - формирование шаблона за счет прямых инъекций js в шаблонную строку
* очередной html-подобный мутант (очевидно для задания реактивщины будут использоваться специальные атрибуты, которые к html никакого отношения не имеют. полагаю их парсинг происходит регуляркой, а после в императивном стиле все указанное в шаблоне волшебство будет навешивается на свежий узел)
* каждый раз нужно писать ${ }, и выглядит это в целом очень отталкивающе
* если атрибутов будет много придется прописывать их каждый по отдельности поскольку ...obj или что-то такое сделать не выйдет
* для формирования очень простой верстки, с минимумом логики - подходит,
для всего более сложного придется привязывать все атрибуты самостоятельно, тоже самое касается и прописания логики
* функции plus minus будут вставлены туда в своем строковом представлении, с замыканиями так не выйдет
* как я понимаю, композиция компонентов, их связывание будет происходить ручками. иначе в рамках данного синтаксиса придется как-то изрядно извращаться, особенно с передачей пропсВообще первое на что обращаешь внимание - синтаксис. Причем не важно это фреймворк или яп. Он не должен отталкивать, как происходит у меня в данном случае)
Но обычно, когда начинаешь писать свою первую рендерилку, приходишь именно к такому. Дальше анализировать не хочется, надеюсь ответил)
supercat1337
08.12.2024 10:37А вы точно знаете что такое tag template? Шаблонные строки - это нативный синтаксис языка. А тег-функции - это супер возможность использования этого синтаксиса.
Функции plus, minus не вставлены строковым представлением, это видно из кода. Их ссылки отправлены в качестве параметров к тег-функции. Можно заменить на анонимную функцию, без проблем.
Внутри функции html нет регулярок, dom-дерево создается из template-элемента и через importNode импортируется в неймспейс текущего документа. И да, после создания элементов, императивно все навешивается, а как еще?
В тег-функции вы можете передавать разные типы параметров, не только строки, но и объекты. Композиция реализуется максимально нативно.
fcrng Автор
08.12.2024 10:37Тут прошу прощения, это первое что я увидел, и хз почему подумал о другом)
Да, конечно знаю, один из самых интересных js-хаков.
В таком случае из того что написал выше - убираем бред про прямые инъекции и вставку plus minus, и никакие регулярки тут разумеется не нужны, все верно.
А в остальном вроде все, суть та же
Не понял только про склейку компонентов, как она выполнена в вашей реализации?supercat1337
08.12.2024 10:37А что остается?
Уродский синтаксис - это дело привычки, это синтаксис js.
очередной html-подобный мутант - это валидный html вообще-то.
каждый раз нужно писать ${ } - да, это нативный синтаксис.
как я понимаю, композиция компонентов, их связывание будет происходить ручками - просто вставить компонент один в другой? тут нет проблем.
Что я пропустил?
По поводу синтаксиса - можно писать и без использования спец-атрибутов. Тогда что остается? Только функции-биндеры, которые будут привязываться к элементам для изменения из атрибутов или свойств.
fcrng Автор
08.12.2024 10:37А условный рендеринг, рендеринг списков, конструкции будут примерно как preact, правильно понимаю?
html` <div class="app"> <${Header} name="ToDo's (${page})" /> <ul> ${todos.map(todo => html` <li key=${todo}>${todo}</li> `)} </ul> ${show && html` <button onClick=${() => this.addTodo()}>Add Todo</button> `} </div> `;
supercat1337
08.12.2024 10:37Технических препятствий для этого кейса нет. В вашем примере это банальный jsx в обертке tag-функции.
fcrng Автор
08.12.2024 10:37Основное недопонимание было за счет того что я представлял себе что-то типо preact - представлялись всяческие нагромождения в виде одной шаблонной строки вложенной в другую, псевдо-jsx из примера выше.
Перед глазами нет реализации, поэтому сидим гадаем)
Так, возможно дошло. Как понял - вы вообще не подсовываете в шаблон подобную логику, в шаблоне описываете теги, атрибуты и слушатели. А все остальное - композицию компонентов, условный рендеринг, рендеринг списков, дополнительную логику и прочие "сложности" прописываете где-то рядом, так?
Мне конечно не близка идея формирования верстки подобным образом, но в целом звучит неплохо за счет полной нативности.
Это ведь все лишь верстка - есть как минимум 3 способа ее задать. НО - Важно ведь смотреть как оно в целом устроено и работает. Например - что у вас возвращает компонент (только разметку или какие-то еще якори необходимые для работы с ним), как устроена реактивность, как пробрасываются пропс, как очищаются вложенные компоненты при удалении корневого, как происходит очистка, что по эффектам, нужен ли патчинг изменений вносимых в дом и тд и тд.
Если подскажите название либы или дадите ссылку, я могу взглянуть для полного понимания. Особенно интересен код компонента с рендрингом списка, и связыванием компонентов между собой.Пишу если что без негатива, хочу понять
OldVitus
08.12.2024 10:37Основной посыл статьи - поставить под сомнение текущие реализации шаблонов.
Поставил бы под сомнение шаблоны как таковые.
fcrng Автор
08.12.2024 10:37Императивно прописывать атрибуты для тегов, и вкладывать один в другой ручками? Правда не знаю как сейчас можно обойтись без шаблонов, особенно если смотреть масштабно, на перспективу
Надеюсь правильно понял ваше предложение.
Озвучьте ваше виденье, если нетрудно
OldVitus
08.12.2024 10:37Декларативный HTML/XML макет, императивно (ручками :) шатаем из прямо связянного с макетом скрипта
--hello-world component <div beans-as="hello-world" beans-shadow="mode=closed;delegatesFocus=true"> <h1 beans-body></h1> <input beans-ref="input" placeholder="type your name here"> <h2>Hello <span beans-ref="name">Anonymous</span>!</h2> <script> $ref.input.oninput = (e) => { this.beanUpdate($ref.input.value) } this.onBeanUpdate = (data) => { $ref.name.innerText = data || 'Anonimous' } </script> </div> --root of app <div beans-as="double-hello-world"> <hello-world>Hello first</hello-world> <hr> <hello-world>Hello second</hello-world> </div>
как-то так, здесь два компонента, один использует другого
всё это заливается в фабрику
-
из фабрики берётся скриптом и монтируется туда, куда нужно
fcrng Автор
08.12.2024 10:37Но это ведь по сути тоже своего рода шаблоны)
Для того чтобы заставить это полноценно работать, понадобится немало клея, который будет всем этим заправлять. По итогу у вас и получится библиотека, или фреймворк. А что поменялось то, слегка иной способ задания компонентов? Как не жонглируй троицей технологий, и всеми подобными подходами, в среднем получится что-то вроде синтаксиса свелт. Который возможно будет разнесен на три отдельных файла, или скрипты и стили напрямую будут объявляться в разметки, как у васПервый вопрос который себе задаешь глядя на любой синтаксис - хочется ли тебе писать на этом. И тут у меня ответ - нет, я бы не стал, слишком устал от этого)
OldVitus
08.12.2024 10:37Макеты - не шаблоны, клея 2k (с lazy loading модулей 3.7k), работаем прямо с DOM
живых объектов, как в детстве :)Как не жонглируй троицей технологий, и всеми подобными подходами, в среднем получится что-то вроде ...
других технологий нам браузер не предоставил, они привычные и достаточно наглядные
fcrng Автор
08.12.2024 10:37Как я понял, вы говорите уже о какой-то конкретной реализации, и вашем опыте с ней.
Но дьявол в деталях, нужно целиком отсматривать предложенное вами решение, анализировать проекты. активно писать на нем.
Из своего опыта, о ваших наработках я могу судить исключительно по синтаксису в примерах. И мне он не кажется хоть сколько то привлекательным. Если он правда такой, - заманчивей писать на вью. СубъективщинаOldVitus
08.12.2024 10:37Как я понял, вы говорите уже о какой-то конкретной реализации, и вашем опыте с ней.
Ну а был бы смысл говорить о чём-то не конкретном? ;)
Но дьявол в деталях, нужно целиком отсматривать предложенное вами решение, анализировать проекты. активно писать на нем.
Весь дьявол в DOM API, думаю Вы с ним знакомы не понаслышке, библиотека просто даёт возможность масштабировать наиболее очевидное совмещение HTML и JS
Из своего опыта, о ваших наработках я могу судить исключительно по синтаксису в примерах.
Здесь нет синтаксиса - его вовсе нет.
И мне он не кажется хоть сколько то привлекательным. Если он правда такой, - заманчивей писать на вью. Субъективщина
Субъективщина :)
netukag
08.12.2024 10:37В статье довольно много мыслей, но, какие из них можно сделать выводы, непонятно. Только то, что что-то не так с шаблонами.)
Вообще для меня все примеры, что с веба что с мобилок выглядят одинаково. Да, в нашем приложении будет место, где описывается, из каких компонентов состоит компонент, как они стилизуются, а сверху довешивается интерактивность.
Если стоит задача "технически" привести всё к использованию js, то можно просто делать React.createElement('table', {style, onClick}).
Если же нужно реально разделить разметку, стили и интерактивность, то в вебе это тоже вопрос решенный - описываем разметку, отдельно навешиваем селекторами стили на элементы, отдельно навешиваем обработчики событий. Но в таком варианте это уже в целом да, другая архитектура приложения.
fcrng Автор
08.12.2024 10:37Да, честно сказать уже сам жалею, что соединил воедино материал, и некоторые свои мысли и эмоции, предысторию стоило опубликовать отдельно)
React.createElement('table', { style, onClick }).
Реакт и без этого отталкивает, а если так его использовать, то лучше уж вообще пойти на кассу работать) Но да, суть будет примерно такая, если превратить все в js. Вы правы.
Разве что выглядеть это может значительно лучше)
Не, разделять на три разные технологии не мой подход, это уход в написание каких-то лендингов, я скорее за абзац выше
А по поводу примеров в статье. На мой взгляд они абсолютно разные) Мне невероятно больно от всего xml подобного, в особенности когда это дело начинают смешивать с какой-то js логикой.
Так вот - основное различие в том, что в мобилках все сводится до сути - есть компонент, есть пропсы к нему. Остается лишь выстроить из них композицию, +некоторая логика на основном языке. И все это нативно, без xml и строковых шаблонов.
И также важно, что у них нет необходимости склеивать между собой 3 разных языка, как это происходит у нас. Пожалуй это один из основных моментов который стоит учесть и обдумать
Благодарю за ком, вы один из немногих кто что-то выкупил)
StepanovAlex
Сложные задачи имеют сложные решения.
Не может существовать никакого простого и единого решения для UI, потому что это сложная задача.
fcrng Автор
Вся разработка в целом идет по спирали, она циклична если хотите
Мы пишем что-то, в процессе понимаем - что-то не так, меняем подход/начинаем сначала
раньше под каждую платформу писали отдельно, сейчас есть альтернатива в виде KMP и flutter.
пройдет время, на них будет написано огромное количество приложений,
в процессе выявятся изъяны, доработки, неверные подходы =>
насколько возможно внесут правки, а после - появятся новые инструменты разработки,
И так до тех пор, пока решение не будет найдено
Разумеется, таблетка для всей разработки не появится по щелчку пальцев (если, конечно, нам не поможет ИИ).
Все будет постепенно и относительно узкоспециализировано.
Прежде на каждом направлении появится свой единый инструмент.
А уже после все это дело будет как-то объединяться, сводится во что-то еще.
Вопрос времени
Что касается фронтенда (в вебе) — это возможно уже сейчас, поэтому я здесь
Темы на пару отдельных статей, благодарю за вопрос
powerman
На фронте, безусловно, всё ещё творится полная порнография. Но единый инструмент - это тоже перебор. Посмотрите на бэк, или на нативные десктопные приложения - там нет такого мельтешения технологий и фреймворков как на фронте, да, есть некоторая сменяемость языков, но в целом пока никаких признаков того, что всё текущее разнообразие заменит единый инструмент - потому что задачи всё-таки несколько отличаются, и под разные задачи нужны разные инструменты. Крайне маловероятно, что на весь фронт, в отличие от бэка, задача ровно одна и её идеально решит единый инструмент. Мобилки в этом плане действительно отличаются, но там причина не в том, что единый инструмент решает все вопросы, а в том, что вся экосистема достаточно сильно контролируется одной (или второй) компанией, плюс оно всё-таки заметно моложе и веба и тем более десктопа.
fcrng Автор
Еще раз - речь о тенденции. А не о том что по щелчку пальцем все "лишние" языки исчезнут, а все старые проекты в миг будут переписаны на идеальный яп)
Все постепенно. Фронт что в вебе точно можно объединить. Причем уже сейчас. Просто задачи такие никто не ставит. Есть рынок, есть три "фреймворка" и заказчиков это устраивает. В их интересах чтобы эти фреймворки существовали и поддерживались. Да, они по разному устроены под капотом. Но задачи выполняют абсолютно одни и те же. И на выходе у всех один и тот же язык - js.
Это не android и ios. Это одна и та же платформа - браузер.
powerman
Ну, условно, на бэке тоже одна и та же платформа - линух. Но никаких тенденций в эту сторону не наблюдается.
fcrng Автор
Ну задач таких не стоит, говорю же)
У бэкендеров кстати и впрямь все как-то более приемлемо как будто бы)
Ни один знакомый бэкендер мне ни разу не жаловался на свою работу, или язык на котором он пишет. В то время как от фронтов регулярно что-то да слышишь, да и от мобильщиков тоже
powerman
Ну, на мой взгляд (очень издалека, я полноценно фронт не писал уже много лет) похоже на то, что TS принципиально проблему разработки фронта не решил, хоть с ним и стало явно лучше. У JS шансов её решить нет в принципе - всё, что из него можно было выжать уже давно выжато. Так что сейчас всё выглядит так, что надежда осталась только на WASM. Но написание полноценного фронта целиком на WASM сегодня упирается в то, что на JS уже написана тьма виджетов/компонентов/библиотек без которых современный фронт сделать сложно, использовать их параллельно с WASM не очень хочется потому что портит всю идею (да и технические сложности при таком подходе тоже наблюдаются), а шансы переписать всё реально полезное и нужное с JS на WASM пока выглядят туманными. Вполне возможно, что если кто-то сделает реально хорошую и обширную библиотеку(и) UI-компонентов на WASM, то это станет game changer для фронтенд-разработки.
fcrng Автор
Разговоры за wasm идут очень давно. Но его по прежнему используют лишь как ускорялку для кусков программы. Сам js да - весьма ограничен. и не успевает покрывать те возможности которых от него требует рынок. Да и развивается, по моему субъективному, вообще не в ту сторону, и крайне медленно. А TS что есть, что его нет, под капотом он ведь не добавляет новых возможностей. Точно также как и расширения в студии, которые чисто помогают писать нам код, но на конечную функциональность никак не влияют.
Сейчас как по мне важнее то, что решение, как будто бы, не ищут. Ни замену для js, ни альтернативную ветку его развития. Все словно остановилось, возможно из-за кризиса
powerman
По WASM это не просто разговоры, я лично видел проекты и на Go и на Rust (но, скорее всего, похожие есть и на других языках), которые позволяют писать фронт на этих языках. Пока не появляется желание быстро-дёшево подключить какой-нибудь привычный UI виджет (банальный выпадающий список с type-ahead результатами или удобный календарик) это всё даже неплохо работает. Но в этот момент ты выясняешь, что либо тебе надо реализовать такой виджет самостоятельно с нуля на этом языке, либо добавлять в проект JS плюс решать проблему как объяснить этому конкретному WASM-движку что какой-то кусочек DOM будет обновляться не им а сторонней JS-библиотекой и решать вопросы взаимодействия/синхронизации между ними. И это совершенно не тот объём работы (и времени на него), который бизнес считает приемлемым сегодня для решения такого рода задач.
fcrng Автор
Согласен, задачи несопоставимые.
В остальном - не знаю что ответить)
Не вижу перспектив для васма в ближайшее время.
Он есть и есть, где-то используется. Пишем мы по прежнему на жс.
На раст уже десяток лет хотят переписать все и вся, но опять же, по итогу, в браузере, мы по прежнему будем писать на жс.
Нужно доработать его, или заменить. Других решений не вижу