image for post

Новый блог

Intro

Ну что ж, вот и пришла пора писать "hello world" в новом блоге. Это не первый мой блог, наверное как и у всех. Первым был бложик в старые добрые времена, еще на blogspot-е, впрочем ничего толкового я тогда написать еще не мог :)
Затем были попытки на jekyll, hugo на борьбу с которыми уходил весь запал и желание писать ушло. Во времена выхода dotnet 3.0 и превьюх 3.1 для интереса попробовал сделать блог на blazor, с рендером md на клиенте - получилось неплохо, msbuild-ный таск генерил при билде список постов и инфу по ним, на клиенте его получал блейзор, отрисовывал и вобщем-то работало все сносно, однако тогда еще не было тримминга сборок и скачиваемый размер был большим, в итоге с мобилок первый запуск был крайне долгим. Дальше мне довелось поработать с WASM (и с Blazor в том числе) чуть поглубже и мне не понравилось. Основные претензии - работа с памятью и скудность API по сравнению с JS. При работе с WASM нужно помнить, что выделяемая память не шринкается, сделав free() никто в браузер больше эту память не отдаст, она останется выделенной под WASM даже если вы ее не используете. Связанный с этим косяк - профайлинг утечек та еще боль, выделенные объекты в WASM в профайлере не увидишь, еще неприятнее искать ссылки на DOM из внутряшек Blazor-а. Ну а вторая претензия и так должна быть понятна, пишешь под WASM на одном языке, потом приходится переключаться на JS, ибо нет никакой возможности заюзать WebWorker API или AudioContext-ы например. В Rust-е вроде как получше с биндингами, но то же без interop-а никуда.

Ладно, что-то меня понесло, но я хотел рассказать какой путь был пройден чтобы прийти к тому, что без JavaScript никуда (хотя скорее связки TypeScript -> JavaScript). Итак мы дошли до того что хорошо бы писать блог на JavaScript, куда дальше?

React vs Vue vs Angular

Во времена Backbone и первых Angular-ов я пробовал проникнуться ng*-ными атрибутами, но мне показалось это жуткой болью иметь в атрибутах по-сути свой язык. Хотя последний Angular был мне рекомендован коллегой, как наиболее похожий на что-то энтерпрайзное (IoC, TypeScript only etc) я так и не могу смириться с этим обилием управления через атрибуты. Вычеркиваем Angular. Настало время гуглить и сравнивать Vue vs React, в целом картина понятна - рынок юзает React, опыт с ним будет наиболее релеватный. В процессе гугления Vue мне показался менее стройным, да и к тому же попытки поюзать React у меня уже были. Спойлер: не шибко приятные. React это не фреймворк, а библиотека, для полноценного сайта ему необходимо выбрать еще 100500 библиотек, типа Redux vs MobX (хранение состояния), роутеров, систем стилей, webpack vs vite (систем билда) etc.

Все это безумно утомляет и заставляет разбираться в кучах тонкостей того или иного выбора. Чтобы уменьшить боль от реакта люди сделали еще большее количество framework-ов на его основе, в том числе и сами авторы React-а тоже. Одни из основных это create-react-app, Gatsby, NextJS.

Что выбрать?

Gatsby vs NextJS vs create-react-app vs Astro

Ранее у меня был pet проект с create-react-app и мне не понравилось то, что чтобы добавить что-то в вебпак конфиг нужно было пройти 9 кругов ада. Из коробки было этого не сделать и было толи 2 толи 3 старых пакета позволяющих модифицировать сгенеренный конфиг, один из них даже работал, но при миграции на новую мажорную версию все это отваливалось.

В общем с create-react-app знакомство не задалось. Перейдем к Gatsby, начало было многообещающим, мне понравилась идея стоящая за graphql подходом, генерация typescript типов к frontmatter-у например, короче годно. Проблемы правда тоже были, например стартовые темплейты для документации, они просто не работали. Философия Gatsby - для всего берешь плагин, и вот их качество прямо скажем не очень, на момент когда я его взял уже вышел React 17 как пару месяцев, а MDX 2.x уже был как полгода, при этом плагины просто не поддерживали их, и надо либо было даунгрейдиться либо отказываться от плагинов. Вспомнил dll hell и всплакнул. Короче Gatsby показался неплохим, но страдающим из-за отсутствия финансирования и как следствие отсутствие качественной поддержки.

NextJS - то что я в итоге выбрал. У NextJS есть разные варианты использования и SSR и SSG (static site generation) и всякие гибридные штуки и прочее прочее. Т.к. бэкенд писать на JS это что-то из области хипстеров, я рассматривал только SSG ну и в целом он не плох. Но и не хорош :) В кратце идея там простая и понятная как генерится сайт: есть 2 функции getStaticPaths() и getStaticProps(). Первая генерит параметры пути (URI params), а вторая принимает эти URI params и уже генерит пропсы для отображения странички. Хочешь в базку сходи во время билда, хочешь mdx скомпиль или md прочитай, все под твоим полным контролем и это круто. Однако на экспорте передаваемые страничке параметры (page props) сериализуются в json и кладутся вместе в выходную папку, так что не все так радужно.

Более того он ЖУТКО медленый на билде, люди генерящие по 12к страничек говорят о времени билда под 45 минут :) К тому же next никак это дело не кэширует, и инкрементальный билд именно SSG (перегенерация только изменившихся страниц) отсутствует. Ну я до такого кол-ва страничек не дорос, но отсутствие кэширующего механизма внутри и между getStaticPaths и getStaticProps это прямо боль, пришлось выдумывать самому (см. object-hash). Еще из болячек - интернализация или в простонародье i18n.

В NextJS она есть из коробки, и ты даже успеваешь ее внедрить и порадоваться, но потом делаешь next export и оказывается что это неподдерживаемая штука для SSG, причем i18n в SSG втащить можно, но это не то решение из коробки и довольно длительное время Vercel это не фиксит и не собирается похоже. Hot-reload для MD/MDX контента нет, и настроечкой в конфиге это не фиксится, чтобы организовать watching к файлам контента надо написать свой сервер, благо NextJS выдает тебе SDK, но дальше крутись как хочешь. (см. chokidar)

Ну вы поняли уже наверное, что к SSG у разрабов NextJS отношение посредственное, однако жить можно конечно.

После того как пописал костыли к NextJS решил посмотреть на менее энтерпрайзных собратьев - Astro. Астро показался неплохим вариантом, однако ничего шибко примечательного относительно SSG я не увидел, те же подходы с getStaticPaths() где я так и не увидел кэширования (каждая страничка может заново перечитывать весь список постов и компилить mdx например).
Хотя есть и плюсы, например не надо самому думать про pagination, md/mdx compilation pipeline и все такое.

Поискав еще варианты могу резюмировать, что достойных вариантов static site only по-сути и нет, нигде не стоит это как первоочередная штука.

(╯°□°)╯︵ ┻━┻

Ладно что-то и так много написал, потом может напишу как сделал i18n, темы, static site search (нет не Algolia, wasm-based stork, на расте) и прочие штуки для NextJS.

Copyright © 2023

Version: 0.2.24

Настройки: