Pull to refresh

Comments 26

Спасибо за статью. Возникло несколько вопросов:

Мощную и интуитивно-понятную компонентную систему, позволяющую стереть грань между разметкой и логикой приложения.

А мы разве не должны их отделять?

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

Можете описать подробнее? Как именно происходит синхронизация вашего реактивного стейта и тех изменений в DOM, которые может вносить какой-то 3rd-party модуль, например Jquery plugin.

Куда еще проще редакса спросите вы?

В каком месте Redux прост?

resolving данных, абстрактные маршруты

Можете пояснить по этим пунктам?

Возможность совершать ajax запросы из коробки.

Ну это скорее минус. Это реализовано отдельным модулем? Можно как-то выпилить удобно?

Серверный рендеринг. Правда на данный момент реализован с ограничением. Код выполняется и на сервере и на клиенте. В планах есть передача хотя бы части стэйта на клиент.

Гидрировать разметку на клиенте умеет? Нужно передавать весь стейт, а как иначе?

Отсутствие всего, что не предусматривают по умолчанию html и javascript. Никаких магических надстроек к разметке или коду.

В сравнении с чем?

Спасибо за интерес =)


А мы разве не должны их отделять?

Под стереть грань имеется ввиду декларативный подход к html разметке.


class Hello extends Akili.Component {
  created() {
     console.log(this.scope);
  }
}

<hello> ${ console.log(this) } </hello>

this.scope в компоненте тот же самый объект, что и this в разметке. Я считаю это очень удобно.


Можете описать подробнее? Как именно происходит синхронизация вашего реактивного стейта и тех изменений в DOM, которые может вносить какой-то 3rd-party модуль, например Jquery plugin.

Все биндинги в разметке привязаны к конкретным DOM узлам и не мешают работать с другими узлами. То есть можно легко совмещать компонентную систему фреймворка и стандартные фишки javascript. Вещи типа такого являются нормальными:


class Hello extends Akili.Component {
  compiled() {
     if(this.attrs.hideDiv) {
       $(this.el).find('.jquery').hide();
     }     
  }
}

<hello hide-div="true">
  <div class="jquery"></div>
</hello>

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


В каком месте Redux прост?

А что в нем сложного? По сути обычный event emitter с парочкой методов )


Можете пояснить по этим пунктам?

Под resolving data имеется ввиду, что указывая маршрут, мы в его обработчике можем вернуть Promise с данными. И вложенные маршруты не будут обработаны, пока не зарезолвится текущий.


router.add('app', '/app', {
  handler: (transition) => {
    return Promise.resolve('my app data')
  }
});

Абстрактные маршруты — это маршруты, у которых нет шаблона. То есть просто в обработчике делаешь что-то, что тебе нужно и все. Они могут быть частью иерархии маршрутов тоже.


Ну это скорее минус. Это реализовано отдельным модулем? Можно как-то выпилить удобно?

Можно просто не использовать его. Код этого сервиса занимает несколько килобайт.


Гидрировать разметку на клиенте умеет? Нужно передавать весь стейт, а как иначе?

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


В сравнении с чем?

В сравнении с другими фреймворками. Не хочется просто показывать пальцем )

Под стереть грань имеется ввиду декларативный подход к html разметке.

Не понимаю в чем здесь стирание грани, но ОК. Только вопрос, вам не кажется что точно также делают все остальные фреймворки? Даже более интуйтивно. Зачем вообще использовать this в шаблонах, а просто не использовать данные из скоупа как они есть:
class Hello extends Akili.Component {
  created() {
     this.scope.message = 'Hello world';
  }
}

<hello> ${ message } </hello>

Это еще лаконичнее и удобнее.

Все биндинги в разметке привязаны к конкретным DOM узлам и не мешают работать с другими узлами. То есть можно легко совмещать компонентную систему фреймворка и стандартные фишки javascript. Вещи типа такого являются нормальными:

Честно говоря, я говорил о чем-то более разумном и реальном. Самый банальный пример, например есть у нас такая мощная штука как DataTables (знаю что jquery это фууу, но для примера сойдет). И в данных (по вашему в скоупе) у нас лежит массив данных для таблицы.
this.scope.data = [{}, {}...];

Как вы будете синхронизировать состояние данные в скоупе с теми манипуляциями DOM, которые производит DataTables и в обратном направлении.
Например, мы добавили новый элемент в массив данных через ваш скоуп и DataTables также обновился.
this.scope.data.push({});

Или DataTables удалил элемент из DOM и он удалился из массива данных.

А что в нем сложного? По сути обычный event emitter с парочкой методов )

Такое ощущение, что вы сейчас ответили в контексте того, как Redux реализован изнутри. Тогда да, он крайне прост. Только юзеров вашего фреймверка не интересует простота реализации стора, если вы писали об этом. В использовании Redux очень сложен, так как весьма многословен и требует тонны бойлерплейта.

Под resolving data имеется ввиду, что указывая маршрут, мы в его обработчике можем вернуть Promise с данными. И вложенные маршруты не будут обработаны, пока не зарезолвится текущий.

Абстрактные маршруты — это маршруты, у которых нет шаблона. То есть просто в обработчике делаешь что-то, что тебе нужно и все. Они могут быть частью иерархии маршрутов тоже.

Разве такое не умеет любой нормальый роутер? Например, PageJS:

page('/app/*', (ctx, next) => {
    Promise.resolve('my app data').then((data) => {
         ctx.data = data;
         next();
    });
});

page('/app/posts', (ctx, next) => {
     console.log(ctx.data);
});

page('*', doSomething, oneMore, secondOne);

Причем имхо концепт middleware намного гибче.

Можно просто не использовать его. Код этого сервиса занимает несколько килобайт.

Это много. Лучше вообще не ключать его в стандартную сборку и шипить как отдельный модуль.

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

Иными словами, когда код выполняется на клиенте он заново производит рендеринг всех компонентов, которые уже были отрендерены на сервере. Видимо и запросы дергает все. Тогда это фигня, а не поддрежка SSR.

В сравнении с другими фреймворками. Не хочется просто показывать пальцем )

Такать не надо, просто интересно, что вы имеете ввиду под «магическими надстроеками к разметке или коду», которых у вас, как я понимаю, нет. Можно просто пару примеров.

Это еще лаконичнее и удобнее.

Дело в том, что в выражение можно добавлять глобальные переменные. Например, там уже есть event, utils, console и.т.д. А можно вообще любые свои:


Akili.options.globals = { my: 1 }

${ my + this.x } 

Как вы будете синхронизировать состояние данные в скоупе с теми манипуляциями DOM, которые производит DataTables и в обратном направлении.
Например, мы добавили новый элемент в массив данных через ваш скоуп и DataTables также обновился.

http://jsfiddle.net/vjarL1t6/50/
Пара комментариев к примеру.


  • Я не нашел как в DataTables получить чистый измененный массив. Пришлось пройтись циклом лишний раз, чтобы очистить лишние ключи.
  • Нужно иметь ввиду, что если бы DataTables работал не с копией переданного массива, то вообще ничего не надо было бы делать. Данные обновлялись бы сами, поскольку все объекты скоупа это Proxy.

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

Не согласен. Его "сложность" мягко говоря преувеличена.


Разве такое не умеет любой нормальый роутер

Это много. Лучше вообще не ключать его в стандартную сборку и шипить как отдельный модуль.

Это просто обычные сервисы, позволяющие реализовать SPA. Понятно, что в них не будет ничего сверх-нового, альтернатив масса. Смысл тут в том, что Akili это фреймворк. У человека должна быть возможность просто подгрузить один файл и написать полноценное приложение без зависимостей.


Иными словами, когда код выполняется на клиенте он заново производит рендеринг всех компонентов, которые уже были отрендерены на сервере. Видимо и запросы дергает все. Тогда это фигня, а не поддрежка SSR.

Я не концентрировался на этой задаче достаточно, но:


  • код на сервере исполняется полностью, без необходимости ничего переписывать/ добавлять. Пара строк и все готово.
  • Можно делать асинхронные операции в компонентах, они все тоже будет обработаны
  • Уже реализована система кэширования запросов. То есть в ближайшее время добавлю в SSR передачу этих данных, и запросы не будут выполняется на клиенте больше.
  • Что касается остального состояния, то это очень сложно сделать, может быть даже невозможно до конца. Потому что в идеале нам нужны не только данные, которые можно сериализовать и отправить.

Такать не надо, просто интересно, что вы имеете ввиду под «магическими надстроеками к разметке или коду», которых у вас, как я понимаю, нет. Можно просто пару примеров.

  • react — jsx
  • angular1 — своя модульная система, DI
  • angular 2+ — своя модульная система, своя разметка, DI, typescript

Это не значит, что все это не нужно и плохо. Но можно не хуже и без этого.

Дело в том, что в выражение можно добавлять глобальные переменные. Например, там уже есть event, utils, console и.т.д. А можно вообще любые свои:

И что? Одно другому не мешает. Можно организовать приоритизацию резолвинга выражений. Если выражение не найдено в контексте текущего компонента, ищем в глобалах. Хотя в целом глобалов все же лучше избегать.

Не согласен. Его «сложность» мягко говоря преувеличена.

Сложность понятие относительное, соответственно сложно может быть по сравнению с чем-то. Можете привести пример какого-то популярного стора, который был бы сложнее и многословнее чем Redux?

Смысл тут в том, что Akili это фреймворк. У человека должна быть возможность просто подгрузить один файл и написать полноценное приложение без зависимостей.

Фреймворк от слова «каркас». Причем тут ajax-запросы? Да и роутинг тут, по сути, сбоку-припёку. Если у меня SPA по типу «serverless» или не требующее роутинга, тогда зачем мне все это? Фреймворк — это об архитектуре и структуре, компонентах и их взаимодействии, а не о запросах к серверу и роутинге. Имхо.

Я не концентрировался на этой задаче достаточно, но:

Похоже что так. Вы так и не рассказали что у вас с гидрацией (hydrate)? Без этого SSR становится кривой надстройкой. Если вдруг не в курсе, можете почитать здесь.

код на сервере исполняется полностью, без необходимости ничего переписывать/ добавлять. Пара строк и все готово.

Обычное дело, ничего нового. Все так умеют.

Можно делать асинхронные операции в компонентах, они все тоже будет обработаны

Хук resolved() пожалуй единственная интересная штука в вашем фреймворке. Действительно это бывает полезно. Однако я уже видел подобные вещи, обычно они именуются как prefetch(), но смысл тот же. Единственная проблема с этим подходом — это не всегда удобно, когда есть конкретный хук, где можно такое осуществить. Лично я для себя выработал более гибкий подход, который не ограничевает меня фетчингом в рамках какого-то хука.

Уже реализована система кэширования запросов. То есть в ближайшее время добавлю в SSR передачу этих данных, и запросы не будут выполняется на клиенте больше.

Под кэшированием запросов вы подразумеваете сбор ответов в некую единую структуру для ее отпраки на клиент вместе со страницей или же настоящее кэширование ответов с сервера?

Что касается остального состояния, то это очень сложно сделать, может быть даже невозможно до конца. Потому что в идеале нам нужны не только данные, которые можно сериализовать и отправить.

А какие еще данные нам нужны? Можете привести пример?

react — jsx

Просто вид шаблонизатора, частью React не является. Можно и без него, а можно и с ним в других фреймворках.

angular1 — своя модульная система, DI

Тогда не было другой модульной системы, так что сорян. DI — обычное дело, пришеднее из бекенда.

angular 2+ — своя модульная система, своя разметка, DI, typescript

Почему своя? Там вроде ES6 модули вполне работают. Под своей разметкой вы подразумеваете директивы или что? typescript — диалект, опять же не изобретениие Angular, многие с React на нем пришут.

В целом, не вижу особых отличий и уж тем более преимуществ вашего фреймворка по сравнению с Vue, Ractive, Riot или Svelte. Все тоже самое, а местами даже хуже.

И что? Одно другому не мешает. Можно организовать приоритизацию резолвинга выражений. Если выражение не найдено в контексте текущего компонента, ищем в глобалах. Хотя в целом глобалов все же лучше избегать.

Приоритезация уже и так есть. Каждый скоуп наследуется от родительского. Поэтому впихивание сюда еще и глобальных переменных нарушило бы логику.


Под кэшированием запросов вы подразумеваете сбор ответов в некую единую структуру для ее отпраки на клиент вместе со страницей или же настоящее кэширование ответов с сервера?

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


Похоже что так. Вы так и не рассказали что у вас с гидрацией (hydrate)? Без этого SSR становится кривой надстройкой. Если вдруг не в курсе, можете почитать здесь.

А какие еще данные нам нужны? Можете привести пример?

Например, сохранение в переменные/свойства: функций, классов, экземпляров классов и.т.д.


class Hello extends Akili.Component {  
  created() {
    this.scope.setSomething = this.setSomething.bind(this);
  }

  compiled() {
     this.attr('x', fn => this.fn = fn);
     this.setSomething();
  }

  setSomething() {
     this.scope.data = this.fn();
  }
}

<hello x="${ () => 'test' }">
  <div on-click="${ this.setSomething() }">
   ${ this.data }
  </div>
</hello>

Как гидрация тут поможет? Сервер рендерит и возвращает:


<hello x="[object Function]">
  <div on-click="[object Event]">
   test
  </div>
</hello>

Пользователь кликает на див и ?

Приоритезация уже и так есть. Каждый скоуп наследуется от родительского. Поэтому впихивание сюда еще и глобальных переменных нарушило бы логику.

Стоп, у вас скоуп родительского компонента доступен в дочернем? А как же инкапсуляция и изоляция?

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

Ну это конечно не кэш. Просто передача начального состояния данных. Без этого SSR также не работает нормально.

Например, сохранение в переменные/свойства: функций, классов, экземпляров классов и.т.д.

Не понимаю, сохранение куда? Зачем их сохранять в разметку? У вас либо какой-то супер уникальный подход, либо вы что-то делаете не так.

Как гидрация тут поможет? Сервер рендерит и возвращает:

А почему у вас сервер возвращает какую-то ересь? SSR должен рендерить обычный HTML, без ваших конструкций. А гидрация просто жизнено необходима, потому что никому не хочется рендерить приложение и на сервере и на клиенте. Уж извините.

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

Это никак не мешает изоляции компонента. Зато является удобной фишкой для многих кейсов, когда изоляция не нужна.


Не понимаю, сохранение куда? Зачем их сохранять в разметку? У вас либо какой-то супер уникальный подход, либо вы что-то делаете не так.

А почему у вас сервер возвращает какую-то ересь? SSR должен рендерить обычный HTML, без ваших конструкций. А гидрация просто жизнено необходима, потому что никому не хочется рендерить приложение и на сервере и на клиенте. Уж извините.

Нет никаких конструкций. Это обычный html. Рендерить не хочется, но гидрация не сможет восстановить правильное состояние в некоторых случаях. Это конечно не значит, что ее реализовать совсем не нужно. На данный момент это достаточно трудоемкая задача, с не самым высоким приоритетом.

Это никак не мешает изоляции компонента.

С каких это пор доступность выражений из вышестоящего скоупа не мешает изоляции? Данные должны передаваться либо через пропсы (аттрибуты), либо через какой-то предсказуемый глобальный стор, либо компонент не изолирован.

Зато является удобной фишкой для многих кейсов, когда изоляция не нужна.

Если изоляция не нужна, то лучше использовать точечные и предсказуемые вещи, например вот так можно сделать в Ractive:

{
    isolated: false
}


Нет никаких конструкций. Это обычный html.

Кастомный тег hello (если это конечно не Web Component) и дерективы x и on-click — это не часть обычного HTML или каких-то управляющих конструкций, которые понятны браузеру. Да, спецификация в целом не запрещает всего этого, но это не значит что ваш сервер должен рендерить такие вещи. Именно поэтому у вас и возникают проблемы с передачей «функций, классов, экземпляров классов и.т.д.». Для того, чтобы ваш SSR стал рабочим, нужно присылать браузеру не это:

<hello x="[object Function]">
  <div on-click="[object Event]">
   test
  </div>
</hello>

А что-то вроде:
<div>
  <div>
   test
  </div>
</div>

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

Рендерить не хочется, но гидрация не сможет восстановить правильное состояние в некоторых случаях. Это конечно не значит, что ее реализовать совсем не нужно. На данный момент это достаточно трудоемкая задача, с не самым высоким приоритетом.


Задача не из простых, это правда. Но если использовать нормальные фреймворки, они с ней вполне справляются. Главное чтобы клиентский и серверный код был общий, а стейт данных, которые использовались сервером для SSR были переданы на клиент. Однако, насколько я понял, в вашем случае она усложняется выбором кривых подходов к фреймворку в целом.

Если есть желание подробнее разобраться в этой теме, можете прочитать мои статьи из цикла «Разработка изоморфного RealWorld приложения с SSR и Progressive Enhancement»:

  1. Введение
  2. Hello World
  3. Routing & Fetching
  4. Компоненты и композиция


Демка тут. Туториал еще не завершен.
Главное чтобы клиентский и серверный код был общий, а стейт данных, которые использовались сервером для SSR были переданы на клиент. Однако, насколько я понял, в вашем случае она усложняется выбором кривых подходов к фреймворку в целом.

Это не касается конкретно моего фреймворка, а вообще любого.
В вашем стейте, который возвращается в демке только простые данные, которые можно вернуть строкой, поэтому кажется, что все ок.


И демка почему-то отрисовывается дважды. Не стал вникал с чем именно это связано, но явно не нормальное поведение.

Это не касается конкретно моего фреймворка, а вообще любого.
В вашем стейте, который возвращается в демке только простые данные, которые можно вернуть строкой, поэтому кажется, что все ок.

Для начала, там они возвращаются не строкой, а полноценным JS объектом в window.__DATA__. При большом желании он может содержать и фукнции, только смысла в этом нет.

Еще раз, при нормальном подходе, для гидрации вам нужно передать только динамические данные, которые были использованы во время SSR. Почти в 100% случаев это данные из API. Так что я опять же не понимаю в чем проблема?

Если же суть вашей поблемы заключается в некой пре-компиляции динамических выражений из шаблонов, тогда в моем примере это тоже решается просто — на сервере заранее (buildtime) строится AST на основе шаблонов, где все динамические выражения заранее пре-компилируются. Так что в runtime работы с шаблонами нет вообще, только с готовым AST. Это оптимальный подход.

И демка почему-то отрисовывается дважды. Не стал вникал с чем именно это связано, но явно не нормальное поведение.

Она не обрисовывается дважды. Я тоже обратил внимание на двойное мигание, если открыть страницу в табе браузера первый раз. Если же вы ее просто перезагрузите, то двойного мигания не будет. Связано это с анимацией перехода, которую я использую. Учитывая, как дешево она мне далась, я пока готов этим пожертвовать. Главное что нет повторного рендеринга.

Для начала, там они возвращаются не строкой, а полноценным JS объектом в window.DATA. При большом желании он может содержать и фукнции, только смысла в этом нет.

Они в любом случаи возвращаются с сервера строкой. Поэтому функции он содержать не может, как и экземпляры классов и некоторые другие вещи, которые могут быть в стейте.

Так то у вас вообще код на клиент строкой приходит.))) Конечно же отправляется только дефиниция, все что содается в рантайме на сервере должно просто пересоздаваться в рантайме на клиенте. Вообще не должно быть в стейте никаких экземпляров, это какая-то проблема вашей реализации.

Вы себе, кроме всего прочего, еще проблему с кросс-ссылками заработаете при таком подходе. Стейт должен быть POJO. Для сериализации простых JS объектов, вместе с функциями и инстансами стандатных конструкторов, можно использовать например serialize-javascript .

Короче проблему вы себе сами придумали, честно говоря.
Примерно так я и думал. Также было бы интереснее посмотреть что-то более комплексное, например, можете прислать пример реализации такой вот интеграции: jsfiddle.net/pf8no0hn/14 (пример Ractive с использованием декоратора).
Вот и сравните реализацию и насколько ваш вариант многословнее. И ладно бы, если бы не было альтернатив, но их полно. Еще раз: Vue, Ractive, Riot, Svelte, все они умеет все то, что делает ваш фреймворк и даже больше и лучше.

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

Сравнил. Код на Ractive похож на конфигурацию. А в Akili выглядит гибким и расширяемым.


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


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


Akili был сделан с основной целью — получать удовольствие от процесса.

Сравнил. Код на Ractive похож на конфигурацию. А в Akili выглядит гибким и расширяемым.

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

Ваш код очень императивен и это не есть хорошо. Но если вы считаете, что на том же Ractive нельзя писать также императивно, вы ошибаетесь. Только зачем присать так сложно, не красиво и многословно, если можно писать декларативно и просто?

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

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

Akili был сделан с основной целью — получать удовольствие от процесса.


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

Вы когда машину покупаете, тоже спрашиваете продавца в чем киллер-фича или все-таки садитесь в салон, рассматриваете, пробуете покататься и в итоге выбираете ту, которая подходит именно вам?
Для примера, если посмотреть доки по Svelte, то можно подумать это тоже самое что и Vue + SFC . Но киллер-фича Svelte в том, что это компилятор и у него нет runtime. Компоненты компилируются во время buildtime в «stand-alone vanilla js». Размер бандла Svelte как правило получается в 2-3 раза меньше чем у Vue, а по бенчмаркам уступает только ванилле и inferno.

У Vue киллер-фича хотя бы в том, что они умудряются вбирать в себя все лучшие практики других фреймворков, при этом сохраняя простоту интерфейсов и довольно приемлемый вес. Ну и из «большой тройки» — это самый адекватный фреймворк.

Киллер-фичи Ractive вообще перечислять можно очень долго. Он умеет все что нужно.

Вы когда машину покупаете, тоже спрашиваете продавца в чем киллер-фича или все-таки садитесь в салон, рассматриваете, пробуете покататься и в итоге выбираете ту, которая подходит именно вам?


В отличие от большинства тех, кто прочел вашу статью, я как раз «заглянул в салон», а также внимательно посмотрел как «прокатились на ней» вы. Ничего особенного не увидел и если уж продолжать аналогию с машинами: купить ваш фреймворк это то же самое, что купить «Noname» авто вместо проверенный «Toyota», за те же деньги, но с меньшими функциями, да еще с плохой подвеской.

Я не увидел ничего что было бы сделано лучше, продуманнее, удобнее или инновационнее, чем у многих других фреймворков. Если сравнивать только с Angular и React, тогда ваш фреймворк имеет свою нишу. Проблема в том, что эта ниша давно полная уже, а вы не предложили ничего принципиально нового. Без обид.

Но киллер-фича Svelte в том, что это компилятор и у него нет runtime.

И что программист, которому надо просто на этом написать сайт или пользователь приложения от этого получают в итоге? Надо делать киллер-фичу ради киллер-фичи?


умудряются вбирать в себя все лучшие практики других фреймворков

Он умеет все что нужно

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


что купить «Noname» авто вместо проверенный «Toyota»

Я специально не проигнорировал цитаты выше. Потому что весь их смысл как раз вот в этой, последней цитате. Как вы думаете кто-то еще "заглянул бы в салон" кроме вас, если бы, скажем, vue еще не был написан, но его бы сейчас выложил я? Можете не отвечать на этот риторический вопрос ))


Но я не отрицаю, что если написать что-то действительно инновационное, то это может стать популярным и у "нонейма" =)

И что программист, которому надо просто на этом написать сайт или пользователь приложения от этого получают в итоге? Надо делать киллер-фичу ради киллер-фичи?

Много всего. Программист получает возможность писать маленькие, быстрые, автономные компоненты, на чистом JS (после компиляции) без необходимости решать многие проблемы этого JS. Кроме того, программист получае статический анализ кода и много других плюшек. Продробнее можете почитать тут и тут. Вообще тема AoT-компиляции сейчас набирает популярность.

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

Скорее это слова анти-велосипедиста))) Велосипедист пишет свой фреймворк только потому, что существующий использует двойные фигурные скобки, вместо одинарных, а это ущемляет его чувство прекрасного. Вот вы можете точно ответить, чего вам не хватило в том же Vue, чтобы писать свой фреймворк, который далает плюс-минус тоже самое?

Можете не отвечать на этот риторический вопрос ))

На самом деле я могу на него ответить. Феномен Vue очень прост — он появился вовремя. Дело в том, что изначальный Vue — это более примитивная калька с Ractive, который появился еще в 2012 года. Сравните:

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
});


var app = new Ractive({
  el: '#app',
  data: {
    message: 'Hello Ractive!'
  }
});


Тогда все плотно сидели на jquery и такие вещи как virtual dom (в Ractive это тогда называлось parallel dom), SSR c гидрацией (в Ractive это называется enhance), «component-scoped» стили (есть из коробки) и другие инновации Ractive были людям не понятны.

Прошло время, лицекнига вложились в PR реакта, сейчас все не любят jquery и любят реакт. Но реакт крайне специфичен и привносит кучу всяких идеалогий, которые многим противят. Angular долго был аутсайдером, потому что никак не релизился. Ну и в целом он сложнее и скорее для энтерпрайза. Vue скопировал Ractive и появился как раз вовремя, как альтернатива.

Ваша проблема к том, что вы не только не написали ничего нового, но и появились не вовремя. Ractive был инновационный, но не своевременный и без денег на PR. Vue не придумал ничего нового, но сделал это вовремя. Svelte придумал новое, но пока не понятно вовремя ли. Akili не придумал ничего нового и появился слишком поздно. Не вижу шансов на успех.
Я с вами почти согласен ) Спасибо за фидбэк.

Sign up to leave a comment.

Articles

Change theme settings