Поясню за JS фреймворки

 Публичный пост
3 мая 2020  3545

Кто я? Я frontend разработчик с каким-то опытом. Писал на каком-то кол-ве фреймворках. На jquery я писал во времена старта карьеры, сильно позже писал на react государственный (Россия) портал, которым, наверняка вы пользовались, сейчас пишу на Angular 9 в большом банке и Vue для Европейской клиники. Хочу поделиться своим опытом.

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

1. jQuery

Это вообще не фреймворк. Это библиотека. Была придумана во времена динозавров, когда стандарты работы с DOM во всех браузерах были разные. jquery предлагал свой стандарт и инкапсулировал работу с DOM. Это позволяло не думать о том, какой браузер и как в этом браузере добавить класс элементу. Уже позже для jquery придумали карусели и bootstrap.

Плюсы: простой, как кувалда, есть много красивых готовы календариков, каруселей и бутстрап.

Минусы: код неизбежно превращался в лапшу

2. Backbone

Он добавлял в jquery немного архитектуры: модный на тот момент MVC, но по своей сути он остался jquery со всеми его плюсами и минусами

Плюсы: код не так быстро превращался в лапшу

Минусы: у нас все ещё нет нормального тулинга, сборку нужно делать руками, а код все равно превращается в лапшу

3. React

Революция и виртуальный DOM. Сначала его начали хейтить за "HTML в Javascript коде". До этого нас все учили (MVC, да), что логика должна быть отделена от отображения, а тут натебе, все опять в перемешуку.

Изначально все его описывали как всего лишь "V" в "MVC", но быстро про MVC все забыли и перешли на FLUX.

Итак, что нам дал React? В первую очередь это виртуальный DOM. Это значит, что все изменения сначала считаются в памяти (быстро), потом считается diff с текущим DOM и вносятся соответствующие правки в DOM. То есть мы минимизируем работу с DOM, что дает дикий прирост в перфомансе.

Следующая парадигма: компоненты. Компоненты — это круто. Берем наше приложение, декомпозируем его на компоненты и строим приложение "из готовых блоков". Круто, модно, удобно.

Подход «данные вниз, события вверх». Это означает, что компонентам мы передаем данные и подписываемся на события, когда хотим получить данные от компонента. Это удобно, дает понятный dataflow, но есть и минусы. Компоненты образуют дерево и, если мы хотим обменяться данными между соседними нодами - нам нужно стрельнуть событие вверх, вплоть до общего родителя по цепочке, а потом прокинуть их вниз до нужно компонента. Эту проблему в будущем решит FLUX, а конкретно, самая популярная его реализация redux.

Тулинг: изначально его не было. Все мы руками писали наши конфиги для webpack, а многие это делают до сих пор. Позже появился cli create-react-app, который позволил быстро развернуть проект на react с "настройками по умолчанию" который часто подходили под большинство кейсов, но так же есть возможность избавиться от него и дописать конфиг вебпака как вам нужно.

Работа с данными: самым популярным для стейт менеджмента стал redux. Он пропагандирует подход иммутабельных данных. То есть данные напрямую менять нам запрещено, а изменение происходит за счет "чистых функций" (pure function). Эти ф-ии получают на вход текущей стейт и т.н. action с payload, то есть непосредственно действие, которое мы хотим произвести с нашим стейтом. Функция же должна вернуть на основе всего этого новый, обновленный стейт. Зачем же это все надо? Это позволяет "прозрачно" работать с данными и легко тестировать состояние приложения. Чистые функции крайне легки в тестировании. Ещё это решает проблему с обменом данными между соседними компонентами. Наш стейт теперь хранится не в общем для всех родителе, а отдельно от приложения и доступен во всех компонентах (действительность же чуть сложнее, компоненты различают на контейнеры, который умеют в стор и презентационные компоненты, который просто красиво рисуют, но так глубоко не хочу погружаться)

Типизация. Люди делятся на 2 типа: первые любят типизацию, вторые младше 21 (с) Типизация - это круто. Как минимум потому, что помогает IDE автодополнять нам код :) А ещё предотвратит кучу ошибок на этапе сборки проекта. Для react доступен typescript и flow. Вдаваться в подробности не будем. Но typescript более популярный, но не такой строгий как flow. Но она доступна, хоть и не из коробки.

Плюсы: Быстрый, хорошая архитектура, удобно работа со стейтом, тестируемый

Минусы: Все ещё скудный тулинг, многим не нравиться JSX, большой порог вхождения

4. Angular 2+

Вообще есть 2 большие ветки ангуляра - AngularJS (Angular 1.x) и Angular 2+. Как не трудно догадаться сначала был AngularJS, а потом гугл решил все переосмыслить и выкатил вторую версию не похожую на первую ВСЕМ КРОМЕ НАЗВАНИЯ. Я буду говорить о второй ветке (на данный момент уже 9 версия), так как первая давно легаси и я мало про нее могу рассказать.

Что такое ангуляр? Для меня это дорогущий набор инструментов. Фирменный, с шикарном противоударном кейсом. Там есть все, что только может потребоваться тебе в повседневной работе.

Тайпинг: Ангуляр написан на typescript. Тайпинг приезжает из коробки. Многих это отталкивает, нужно учить новый язык. На практике - валидный Javascript - это валидный Typescript. Пишите на js, все что вы заметите - это продвинутые подсказки IDE и расширение файлов ts, а не js. А если вы научитесь typescript, то 80% ошибок избежите на этапе сборки.

Тулинг: Angular поставляется с cli утилитой. Она умеет стартовать приложение, генерировать код (можно писать свои генераторы и кастомные команды). На этапе создания проекта вы можете выбрать свой любимый препроцессор стилей, включать ли роутер и т.п.

Ынтерпрайз: ангуляр на первый взгляд очень страшный и пахнет java. Ну в самом деле, все эти декораторы @Component, @Injectable, @Module и т.п. выглядит жутко. К этому нужно привыкнуть. Это не плохо, это просто так есть.

Стуктура проекта: ангуляр дает стрктуру проекта и стайлгайды, которым стоит следовать. Что это дает нам? А то, что при переходе с одного проекта angular на другой - у вас мало что меняется. Все лежит там же, где и на прошлом проекте. И вообще выглядит одинаково. Это круто

DI: Ох, инъекция зависимостей. Мое любимое! Как я раньше без нее жил? Для тех, кто не знает в 2 словах: работа с данными ведется в "сервисах". Это такие классы, где мы пишем методы, который как-то получают данные, а так же в этих классах эти данные хранятся. Только эти классы мы сами не создаем, а поручаем это ангуляру. В своих компонентах мы просто говорим "Ангулр, дай мне сервис UserService" (ага, просто в конструкторе объявляем этот сервис И ВСЕ). Ангулр сам догадается как его создать (например этот сервис может иметь свои зависимости, аггуляр сам это разрулит) и принесет нам инстанс этого сервиса.

rxjs: Весь ангуляр основан на парадигме реактивного программирование. Все представляется в виде потоков данных, на которые мы подписываемся и как-то реагируем. Это сложно, но невероятно удобно.

И ещё много-много всего, что приезжает нам из коробки. Работа с сетью (http запросы) - есть HttpClient, работа с service worker? Их есть у меня. Работа с формами? Вот тебе FormBuilder - дерзай. Хочешь модный Drag and drop? Пожалуйста, 2 директивы и вот у тебя самописная доска трелло.

Но за все нужно платить. Порог входа в ангуляр невероятно высок, если вы новичок во фронтенде - он сломает вам мозг. Так же он очень большой и толстый. Какие-то простые вещи на нем делают очень многословно. Где в ректе 2 компонента и 4 файла в ангуяр будет три десятка файлов и четыре сервиса. Если вам нужна страничка для кота - не стоит его брать, но, если вы пишите сложно приложение - стоит присмотреться.

Плюсы: есть все и из коробки, типизация, тулинг, архитектура

Минусы: огромный порог вхождения, сложность, многословность, занимает много места

5. vuejs

О, vue классный. Простой, удобный, понятный. Писать на нем сможет даже твоя бабушка. Я за вечер обучил go backend разработчика, а потом он мне неделю в телеге хвастался, как он переписал весь фронтэнд на проекте за ночь. Но давайте по порядку

Тулинг: vue дает нам cli, который сгенерирует проект, настроит роутер и сборку. Как и с react можем написать свой вебпак с блэкджеком и куртизанками.

vue file: все компоненты vue хранятся в файлах с расширение vue. Там есть 3 секции template, script и style. Очевидно для верстки, логики и стилей. Это удобно, все в одном месте. Но если компонент большой - станет больно.

работа с dom: очень просто, поменял данные - тут же отрисовалось. события вешаются просто атрибутом.

Плюсы: очень простой, сложность сравнима с jquery, но лапша у вас уже не получится, позволяет писать огромные приложения, это полноценный фреймворк

Минусы: vue файлы. Кому-то они не нравятся, но справедливости ради - они не обязательны. можно по старинке все хранить в js, иногда магия vue с реактивностью ломает мозг (или сама себя и все взрывает), сложно прикрутить типизацию

Эпилог

Отлично, так что же мне выбрать то? Ну, как и везде - отталкивайтесь от своей задачи. Если вам нужна страничка для кота: vue или react, если вы пишите большой и страшный Ынтерпрайз - смотрите в сторону ангуляра. Он для этого очень хорошо подходит, но я видел (и сам писал) ынтерпрайзы на react и vue. Ну а jquery и backbone лучше не рассматривать для новых проектов.

Как-то так у меня получилось. Вопросы и комментарии задавайте. Всем добра.

(Я не знаю зачем я это писал. Скорее всего, второй бокал пива был лишний, но, наверное для этого мы все тут собрались). Всем бобра.

53 комментария 👇
Вастрик Блогер, питонист, мизантроп 3 мая 2020

Взял на себя смелось причесать вёрстку поста, чтобы избавиться от эффекта стены текста. Теперь как-то более уважительно к читателю.

  Развернуть 1 комментарий

Откровенно говоря, впервые встречаю простое и человеческим языком на русском написанное сравнение всего этого зоопарка. Спасибо от пишущих на jquery и не понимающих «нахера вы усложняете со своими фреймворками». Теперь понятно нахера.

  Развернуть 1 комментарий

Годная систематизация, пишиищщо

  Развернуть 1 комментарий

В рекате стоит посмотреть в сторону MobX. Для 99% кейсов подходит — и не нужно париться с офигеть каким лапшичным Redux.

  Развернуть 1 комментарий

Почему-то практически все игнорируют "старую прописную истину" https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367 🥴

  Развернуть 1 комментарий

@XcNih4ZNxLNhGduD, ты чоо, effector рулит 🙂

  Развернуть 1 комментарий

Круто. А можно ещё 3 строчки про свелт?

  Развернуть 1 комментарий

К сожалению, у меня нет продуктового опыта Свелт. Мне нечего сказать про него хорошего или плохого. Но слышал от коллег, что какие то пет проджекты на нем вполне успешно пишутся.

  Развернуть 1 комментарий

“Три строчки” про свелте.

Свелте похож на Vue тем, что стили, разметка и скрипт для компонента лежат в одном файле. Отличается от всех остальных тем, что у нет рантайма. То есть, нет стокилобайтного файла svelte.js, который необходимо импортировать в бандл на каждой странице, чтобы всё работало. Вместо это, весь .svelte код превращается в обычный JS на этапе сборки. При этом в комплекте сразу идёт: изоляция стилей, реактивность на уровне языка и точечные изменения DOM без Virtual DOM.

Плюс: очень быстрый и компактный код.

Минус: по распространённости он пока уступает остальным. Работы мало (нет), библиотека компонентов скудная, комьюнити дружное, но не такое большое, как у реакта. Хотя в продакшене его уже используют взрослые дяди вроде Mail.ru, goDaddy или 1Password.

  Развернуть 1 комментарий
Vitaliy Teamlead автор 3 мая 2020

Все они компилируются в читый JS, другого мир ещё не придумал (кроме web assembly, но мы же все тут в сами здоровые люди?).

По поводу vue и больших проектов. Пишется, ещё как. Если ты не видешь суслика, не значит, что его нет.

Начать писать можно на чем угодно при каком угодно уровне. Это так не работает, что если у тебя опыта менее 2 лет, то npm тебе не даст поставть react :)

Статья - не статья, а изложение опыта автора. Я не притендую на глубокую аналитику.

  Развернуть 1 комментарий

кстати, что про web assembly скажете? Не совсем в тему конечно, но звучит круто — написал на rust, запустил везде?

  Развернуть 1 комментарий

@dkol, тоже под задачи, wa не идет, как замена js и его экосистеме, а как большой брат для сложных вычислений на клиенте

  Развернуть 1 комментарий

Ангуляр действительно хорош тем, что это коробочное решение. DI позволяет творить энтерпрайз-чудеса, стайл-гайд (если его соблюдают) обеспечивает читаемость кода. Когда я после 3 лет на своём ангуляр-проекте пришёл в другую контору, где тоже был ангуляр, то очень быстро разобрался в архитектуре, тулинге, смог читать чужой код.

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

Зато мне в реакте нравятся возможности использовать элементы ФП. Ангуляр жестковат для этого. Если знаете, напишите, как в нём удобно реализовать high-order components, например :)

Короче, ангуляр — порядок и определённость, риакт — анархия и творчество!

  Развернуть 1 комментарий

Да, отличные аналогии. Все так и есть :)

  Развернуть 1 комментарий
Vitaliy Teamlead автор 8 мая 2020

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

  Развернуть 1 комментарий
Petr Korolev ETHusiast in open-source & privacy 10 мая 2020

Красота, спасибо за отличный dive into frontend! Язык изложения простй и понятный, читать приятно!

ps. еще можно доплнить и сказать, что этот клуб - тоже VUE :)

  Развернуть 1 комментарий

Клёвый стиль изложения, спасибо!
Реакт-Ангуляр-Вью-Джейквери всегда на слуху, используются и в энтерпрайзах и в стартапах, про них куча статьей на каждом углу.

А можешь так же на пальцах пояснить про «длинный хвост» других js-фреймворков, пожалуйста? Есть ли тому же Свелту место в энтерпрайзе? Надо ли что-то знать про Эмбер-Метеор-Полимер? А ещё я слышал от коллег восторженное что-то про Аурелию, которая будет убийцей других фрейморков — врут поди люди или есть в ней что-то революционное?

Ну и последний вопрос: есть ли какой-то фреймворк, который можно подключать в маленький проект (лендос, PoC/MVP) как раньше подключался Джейквери (одним тегом <script>) и быстро вот безо всякого cli, вебпаков и танцев с бубнами вокруг компиляции тайпскрипта в нативный джаваскрипт получить все эти удобства на фронтэнде? Я знаю только один такой — Mithril, но он скорее мёртв, чем жив.

Спасибо!

  Развернуть 1 комментарий

Есть ли какой-то фреймворк, который можно подключать в маленький проект (лендос, PoC/MVP) как раньше подключался Джейквери (одним тегом <script>)

Vue же. Там прям на самой первой странице написано как.

  Развернуть 1 комментарий

@norguhtar, да, все верно. Подтягиваешь JS с CDN, в тэге script пишешь new Vue({...}) и погнали. Причем в контукртор ты указываешь елемент, за который будет отвечать vue, и дальше этого элемента он не полезет (ага, как в jquery). Ну и так же никто тебе не запретит сделать несколько таких элементов и несколько vue инстансов.

Если наложить все вышесказанное на кейс с лендосом, то на странице ты можешь создать, например, форму обратной связи, которой будет рулить vue (валидация формы, http запросы, может какие нибудь автодополняшки для адреса) и, какой-нибудь калькулятор "натыкай свой тариф и узнай сколько будешь платить".

  Развернуть 1 комментарий

С остальными у меня нет большого опыта, что бы как то их оценивать. Читал только начальные тутриалы с офф. сайта.

  Развернуть 1 комментарий

Хорошая сбалансированная статья!

На мой взгляд, не упомянут чудовищно важный аргумент - "популярность на рынке" (выражаемая в кол-во вакансий, кол-во известных проектов, кол-во stackoverflow вопросов и ответов).

Только из-за этого одного аргумента я, например, к сожалению, не возьму ничего кроме Реакта для нового проекта. Потому что это ну почти 90% всех проектов сейчас (да, цифра разная для разных стран. Stackoverflow например показывал статистику по странам). Вот такая "несправедливость". Но принимать решение использовать не самый-популярный-вот-сегодня фреймворк в новом проекта - очень опасное решение.

  Развернуть 1 комментарий

@kirillgroshkov, vue и react как два брата: одни и те же концепции. Мы спокойно нанимаем react devs, скорость погружения без опыта во vue: недели. Обратное тоже справедливо. Я лет 6 писал на реакте, перешёл во vue: вообще одно и то же :)
Да, есть свои особенности, о которых нужно почитать, но это мелочи.

  Развернуть 1 комментарий

😱 Комментарий удален его автором...

  Развернуть 1 комментарий

@KfBHpCXO4j0iV1bQ, напрямую можно, но не сталкивался с проблемой «искать кто» в контексте инпутов и т.п.
Мне нужно чуть больше инфы о проблеме, чтобы не гадать

  Развернуть 1 комментарий

Случай про "статистику по странам". Проводил митап Stockholm.js в Стокгольме. Задал вопрос аудитории про фреймворк. Из ~100 человек 99 подняли руку на Реакт, 1 на Ангуляр. Вот такая статистика. Скандинавия очень про-Реакт.

  Развернуть 1 комментарий

У меня знакомый работает на одну Шведскую компанию (не Икея :D). Да, любят они реакт.

  Развернуть 1 комментарий

jQuery
Минусы: код неизбежно превращался в лапшу

Еще во времена jQuery было очень модно пихать данные в аттрибуты элементов DOM, а потом их оттуда использовать. Sort of State Management :)

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

Времена те, я надеюсь, прошли, а вот унаследованный код остался.

  Развернуть 1 комментарий

Судя по плюсам и минусам, кажется, что Vue - лучший выбор (для маленьких и больших проектов).

  Развернуть 1 комментарий

Мощность vue-экосистемы значительно меньше, чем у react. Это нужно принимать во внимание.

  Развернуть 1 комментарий

@i209, кстати, а есть что сказать про Flutter 3?

  Развернуть 1 комментарий
Anatoly Shipitsin Специалист по НЕХ 3 мая 2020

Vuejs маловато. Как бы основной вопрос а как на нем нормально писать большие приложения? В основной доке как-то маловато.

  Развернуть 1 комментарий

@norguhtar, так же, как и на реакте. Концептуально они одинаковы (vue2). Во vue3 возможности расширены - pinia, плюс нормальное низкоуровневое управление в любой момент. Реактивный стор взрывает мне мозг своими возможностями. Но архитектура компонентов остаётся такой же. А уж какой подход к дизайну крупного проекта выберете - это уже к Вам вопрос.

  Развернуть 1 комментарий

@i209, непонятно чем vue 3 кардинально отличается. Композишен, если что, можно использовать и во второй версии (https://github.com/vuejs/composition-api), как и Pinia

  Развернуть 1 комментарий

@djaler, я и не говорил про «кардинально» и composition api не упоминал.

  Развернуть 1 комментарий

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

  Развернуть 1 комментарий

@djaler, я рендер-функцию, доступную везде. Во vue2 возможности использования меньше (ну или я - затупок, не разобрался)

  Развернуть 1 комментарий

@norguhtar, по-моему, вообще ни одна дока не объяснит "как писать большие приложения". Инструкция к молотку объясняет как пользоваться молотком, а уже что и как с его помощью можно делать - это другое

  Развернуть 1 комментарий

У Реакта:

большой порог вхождения

Я, возможно, предвзят, но на Реакте с хуками невероятно низкий порог вхождения, ниже, чем писать на чистом JS.

У Vue:

позволяет писать огромные приложения

Ни одно большое энтэрпрайзное приложение не использует Vue. Facebook, Netflix, Airbnb, Slack – все используют Реакт. Удивляюсь тому, как много Vue разработчиков на рынке.

У Реакта так же есть большой плюс в виде React Native.

Статья, мягко говоря, очень устарела — сейчас уже появилось много новых фреймворков, например, веб компоненты, или Svelte, который комплируется в чистый JS.

  Развернуть 1 комментарий

Алибаба юзает вуй
Гитлаб юзает вуй

Если покопать думаю ещё смогу примеров найти

  Развернуть 1 комментарий

@Cherkashin, гитлаб да - юзает (но там нет никаких сложных UI интеракций, и в сравнение с фб/нетфликсом это не идет), алибаба - особо не видел. Алибаба (по крайней мере али) использует какой-то свой фреймворк.

Если начать считать приложения на Реакте, счет "больших приложений" явно не в сторону Vue.

  Развернуть 1 комментарий

@blits, про счёт согласен, спору нет)
Из предыдущего моего ответа не читается, но моя мысль о том, что Vue стоит того чтобы тратить время и силы на его использование)

Скоро 3я часть из беты выйдет, станет совсем хорошо.

  Развернуть 1 комментарий
🕵️ Юзер скрыл свои комментарии от публичного просмотра...

@skhalavchuk,

во-первых, все компилируются в чистый JS потому что клиенты умеют только чистый JS.

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

что энтерпрайс это только реакт и ангуляр

Эмм, я не жалуюсь. Я не против того, что реакт на энтэрпрайзах. Я против того, что Vue используется на больших проектах.

есть куча новых

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

  Развернуть 1 комментарий

@blits, pornhub, gitlab- vue. Удивлю, но даже в fb есть vue.
https://github.com/vuejs/awesome-vue#enterprise-usage

  Развернуть 1 комментарий

@i209, Только вью это все равно треш, как был два года, так и остался))

  Развернуть 1 комментарий

😱 Комментарий удален модератором...

  Развернуть 1 комментарий

@blits, ваши аргументы оспорить сложно :)

  Развернуть 1 комментарий

Еще есть stimulusjs — я использую его в продакшене.

И еще если вы не хотите тащить jQuery то в стандартной библиотеке уже есть куча всего: You-Dont-Need-jQuery

  Развернуть 1 комментарий

Очень понравилась статья, просто и доступно написано 👍

Хотела бы спросить совета. Дано: большой энтерпрайз апп на AngularJS, костяк был написан в очень быстром темпе около 5-6 лет назад (авторы/архитекторы - по профилю .Net-чики). На сегодня несколько десятков разработчиков регулярно выкатывают апдейты на прод с новыми фичами и багфиксами. Практически все они - full stack developers (но основная экспертиза - .Net).

Проблемы: код очень запутанный (ням-ням, спагетти!), фронт not responsive, тормозит; масштабировать продукт очень сложно - например, для локализации не получилось сделать даже РОС.

Сейчас стоит выбор - переезжать потихоньку на React или на Angular 9. Что бы посоветовали?

Asking for a friend ☺️
Спасибо!

  Развернуть 1 комментарий

Angular 9. Большие аппы намного легче поддерживать с ним, особенно если все будут следовать стайлгайдам официальным. Ну и RXJS офк. Кстати, я для i18n исползую transloco, в принципе ничо так.

  Развернуть 1 комментарий

@Roniakia, cпасибо 🙇‍! Transloco выглядит интересно, и "дружит" с Lokalise, который планировали использовать для управления локализацией (https://lokalise.com/blog/angular-localization-with-transloco/) 👍

  Развернуть 1 комментарий
🕵️ Юзер скрыл свои комментарии от публичного просмотра...

Не так давно я погружался в фронтенд с нуля, имея за плечами опыт C#. Проще всего мне зашла связка React + MobX. Все это на тайпскрипте, т.к. vanilla js это просто ужас.
Все остальное мне напоминало какие-то извращенные самоистязания. Особенно Angular и Redux в реакте.

  Развернуть 1 комментарий

React так-то тоже не фреймворк, а просто библиотека

  Развернуть 1 комментарий

😎

Автор поста открыл его для большого интернета, но комментирование и движухи доступны только участникам Клуба

Что вообще здесь происходит?


Войти  или  Вступить в Клуб