Всем привет!
Давно я ничего не писал, но это не значит, что я совсем отошел от дел :) Просто никто ничего и не спрашивал. Но сейчас я буду восстанавливать активность ибо есть много полезного материала.
Дело в том, что в этом году я много работал и освоил много интересных и полезных техник. Плюс ко всему поработал в СберТехе, где еще прокачал скилы в командной работе (на нашем проекте работало более 300 специалистов, это совсем не то, что дома фрилансить). Поэтому, уволившись в начале октября, я принялся переписывать свою PrismaCMS, дабы она более соответствовала современным требованиям, а именно, чтобы с ней можно было работать в команде, поддерживала техники CI/CD и т.п. В итоге получился довольно интересный продукт. Собственно, https://prisma-cms.com тоже переписывается на нем, и хотя работа эта еще не закончена, я все же буду выкладывать промежуточные варианты и рассказывать примерно что и как делал.
Итак, первое, что я сделал, это еще раз пробежался по рынку и посмотрел что есть из готового для создания современных веб-проектов.
Требований было несколько:
- SEO-friendly. Предыдущая версия моего движка вполне себе справлялась с созданием каких-нибудь CRM, где SEO вообще никакой роли не играло, но я понимаю, что платформа должна подходить для создания практически любого уровня сайтов, в том числе и eCommerce, где SEO-требования очень высокие. Чаще всего без нормального SEO сайт просто не сможет привлечь покупателей.
То есть должна быть возможность легко задавать мета-теги страницам, четкие серверные коды а-ля 200, 404, 401, редиректы и т.п., а так же удобный роутинг страниц. - Качественный сборщик конечных скриптов. При этом важно, чтобы он умел делать отдельные бандлы для отдельных страниц, чтобы по мере наращивания функционала не все в кучу собиралось (чтобы не рос бесконечно общий бандл), а был один базовый бандл для стартового функционала сайта и, заходя на отдельные страницы, подгружался нужный для их работы код, если еще не был загружен. Это важно, чтобы гугл-тесты показывали хороший результат производительности, ведь чем хуже показатели, тем хуже позиция сайта в поисковой выдаче.
- Минимальный объем функционала "из коробки". Это должен быть именно фреймворк, а не готовая CMS со своим заложенным функционалом какой-то определенной направленности. То есть важно, что бы поддерживался самый важный базовый функционал, но чтобы это легко можно было расширять и дорабатывать, и не запутаться в тоннах кода. Да, если это взять как есть, то вот так сразу сайт не сделаешь. Но на этом вполне можно будет сделать пару-тройку заготовок и их уже использовать для создания конечных сайтов. Забегая вперед, скажу, что первая такая заготовка будет сделана в обозримом будущем и это будет такой аналог shopModx, только на JS.
- Это должен быть уже довольно зрелый программный продукт, на котором уже реализованы и работают конечные сайты, чтобы это был не какой-то очередной супер-стартап, а проверенный в бою продукт.
- И главное - поддержка TypeScript. Да, я долго писал на чистом JS, но теперь я переходу на TS, потому как даже в одного очень сложно обслуживать свой JS-код в чистом виде, ведь javascript не умеет в строгую типизацию, и легко передать в вызываемый метод не те параметры и ожидать совсем не того, что на самом деле можешь получить. Ну, мне очень сложно здесь объяснить почему все так, если вы не знакомы с TypeScript. Но я планирую провести ряд вебинаров и на примерах рассказать.
Ну и как водится, все это надо проверять в боевых условиях, поэтому первым делом я взялся переписать https://prisma-cms.com на новом движке, чтобы было не в теории, а на практике понятно, что и как работает, а что нет. И вот всю самую суть этого маленького эксперимента можно обозначить этой картинкой :)
Честно сказать, я думал все будет проще и быстрее. То есть next-js к текущей версии сайта я прикрутил довольно быстро и в целом все заработало. Но Дьявол кроется в мелочах. Я же хотел, чтобы у меня сайт работал на новых технологиях и быстро. А у меня старая версия была сделана с уклоном больше в сторону функционала. Чего только стоят одни только фильтры. Но для работы многих этих компонентов требуется GraphQL-схема на стороне клиента. То есть прежде чем страница загрузится, сначала должен выполниться запрос на сервер, получить оттуда схему, распарсить ее и т.п., и только после этого сможет отрисоваться страница. А этом даже на не слабом компьютере занимает 0.2-0.4 секунды. А про мобильники я вообще молчу. Вот я и решил выпилить эти схемы, а компоненты сделать более независимые. И, как оказалось, это совсем не простая задача. То есть мне пришлось переписывать многие свои компоненты. Точнее, я планировал чутка подредактировать один-два компонента, но в итоге пришлось практически полностью переписать все основные компоненты. У меня же сайт не монолит, а использует кучу отдельных компонентов. При этом их пришлось переписывать самую их основу, выпиливая все старое вспомогательное, включая dev-сервер, чтобы они полностью соответствовали новым технологиям и основному проекту.
Если вдаваться в детали, то старые компоненты были основаны на create-react-app и react-scripts, а упаковывались с помощью nwb. И вот react-scripts до сих пор не умеет в нормальный Server-Side-Rendering, а nwb не умеет в TypeScript (да и вовсе по ходу проект загнулся). Так что в качестве дев-среды для компонентов тоже пришлось вводить next-js, а упаковку выполнять нативными средствами самого TypeScript.
И тут большая радость, что практически все компоненты основаны на заготовке @prisma-cms/component-boilerplate, так как всю новую основу по сути я делал только в одном месте, а в компоненты просто подгружал гитом, резолвил конфликты и допиливал конечный функционал. И вот тут имеет смысл перечислить фичи, которые входят @prisma-cms/component-boilerplate "из коробки":
- TypeScript
- SCSS/SASS
- Eslint
- Formatter
- Jest/TS-Jest
- Storybook
- Next-JS as dev-server
- Git hooks via husky
- Npm version scripts
- Дорабатываю функционал в компоненте.
- Упаковываю и публикую его в npm registry.
- Обновляю зависимость на конечном сайте.
- Проверяю работу и если что-то не так, выполняю все по кругу.
- Каждый компонент все равно имеет свой самостоятельный node_modules. То есть у вас не будут работать нормально контексты и прочие инглтоны, так как каждый пакет тащит свой собственный инстанс и они никак не связаны.
- Вытекает из первого пункта. Я начал использовать функциональные компоненты реакта, и вот они категорически против, если используется более одной версии реакта. То есть все подключенные зависимости должны использовать единый реакт и не иначе. Классические class-based компоненты реакта более лояльны в этом плане были и yarn link еще хоть как-то спасал.
- Выполнить установку зависимостей
- Выполнить билд компонента
- Выполнить тесты
И вот если хоть какой-то этап не выполнится успешно, то гитхаб уведомит меня о возникшей проблеме.
И все это делается автоматически! То есть если раньше на это у меня уходило 15-30 минут, то сейчас я просто выполняю npm version и переключаюсь на другой пакет (ну или что другое делать). А если мне надо таким образом вылить все пакеты в воркспейсе, то я могу это сделать всего одной командой: yarn workspaces run npm version major|minor|patch. И все. Все пакеты соберутся, опубликуются, выльются на гитхаб и пройдут все прописанные тесты, и если где-то что-то не так, я получу уведомления только по проблемным пакетам. И не буду сидеть и простоя пялиться в процесс, наблюдая за выполнением, тратя на это зря время.
В итоге, еще на двух зависимостях в проекте, моя эффективность работы выросла раз в пять, в прямом смысле. И это еще были относительно небольшие компоненты. Сейчас у меня в проекте 7 зависимостей, включая такой сложный компонент как @prisma-cms/front-editor, в рамках одного которого только было переписано несколько тысяч строк кода. И я думаю, что без всего этого внедренного инструментария я бы еще очень долго все это переписывал.
Результат же за полтора месяца получился следующий:
И это только по самому проекте, не считая изменений в зависимостях, а там тоже совсем не одна тысяча строк. И главное отличие от того, как работа велась ранее, это то, что в браузер я практически не смотрел. Это раньше было так: на основном мониторе редактор кода, а на другом мониторе браузер, в котором сразу обновляется страница при изменении кода. Вот сидишь, пишешь код и наблюдаешь за результатом. А сейчас практически вся работа делается чисто глядя в редактор. А он подсказывает "Здесь ты не тот тип передаешь. А там у тебя зависимость сломалась. Здесь ты вообще бредишь."... Не редко, мой код выглядел вот так:
И вот такой кошмар разгребался всего за день, после чего код становился чистый и пушистый :)
Вот, собственно, опытом такой работы я и планирую поделиться. Все это описывать в статьях - ооочень много буков получится и будет очень скучно, так что я предлагаю провести вводный вебинар на пару часиков и там уже коллективно решить на сколько все это интересно. Если интерес будет, я запущу тестовый курс обучения программированию на этой платформе. На ней можно будет не просто компоненты писать, а создавать полноценные сайты. При этом не придется лезть в такие дебри, куда лезу я. Все самое сложное я уже делаю. Вам же остается только дописывать конечный продукт.
Комментарии с предложениями и вопросами очень приветствуются.
P.S. Предварительную версию сайта выложил здесь: https://new.prisma-cms.com/
Исходники традиционно на гитхабе, сейчас в отдельной ветке: https://github.com/prisma-cms/prisma-cms.com/tree/next-js
Там еще не все сделано, но все же можно вполне оценить разницу по скорости загрузки страницы и работы сайта в целом. Вся информация берется из одного АПИ-сервера, то есть полностью соответствует информации здесь, и когда будет доработан, заработает на основном домене, а эта версия уйдет на поддомен. Все упаковано в контейнеры и управляется из одного docker-compose проекта https://github.com/prisma-cms/docker.
Исходники новой заготовки для проектов, о которой и шла речь, вот здесь: https://github.com/prisma-cms/nextjs
Кто уже умеет во все это, можете поиграться.