Новый блог
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.