Публікація

Як виглядає фронтент для частково статичного клона Reddit

Я маю позитивний досвід роботи з Jekyll та Tailwind, що спокушає мене й надалі використовувати ці технології для будівництва статичного клону Reddit

Я маю позитивний досвід роботи з Jekyll та Tailwind, що спокушає мене й надалі використовувати ці технології для будівництва статичного клону Reddit. Хочу занотувати й інші бібліотеки з котрими в мене позитивний досвід роботи в контексті Jekyll.

Vite плагін Jekyll для зборки JS/CSS

Jekyll доволі спортанський двіжок, тому спочатку я подумав, що мені доведеться робити зборку ассетів десь поряд, але знайшов корисний плагін для зборки, який повністю покриває мої вимоги: зборку JS/CSS, перезборку при змінах, підтримка Tailwind. Єдиним недоліком є що інколи не бачить зміни в CSS файлах і доводиться примсово змінювати CSS, щоб тригернути перезбірку. Мабуть, це тому що інколи зміни в декольких файлах відбуваються дуже шивдко і наступна зміна відбовається в момент, коли працює збірка попередньої зміни. Треба погратися з опцією Vite watch.skipWrite.

Tailwind як фреймворк для CSS

Зізнаюся, я недооцінював Tailwind. Точніше, я до нього ставився скіптично через те що доводиться писати купу классів в HTML, через що шаблони перетворюються на смітник. Проте, я почав використовувати директиву @apply і переніс увесь жах списків классів у CSS фали. Тепер використовую підхід: спочатку пишу список классів в шаблоні, потім коли потрібно перевикористати список – виношу в клас. До самого фреймворку нарікань немає, працюю зі стандартним tailwind.config.js, лише додав до конфігу vite.config.ts наступне:

1
2
3
4
5
6
7
8
9
10
11
12
import { defineConfig } from "vite";
import RubyPlugin from "vite-plugin-ruby";
import tailwindcss from "tailwindcss";

export default defineConfig({
  plugins: [RubyPlugin()],
  css: {
    postcss: {
      plugins: [tailwindcss()],
    },
  },
});

AlpineJS як JS фреймворк

Я дізнався про AlpineJS десь в 2022-2023, написав декілька успішних проєктів з його використанням і вважаю його практичним замінником React та Vue. З моєї точки зору, він написаний настільки елегантно і має настільки мінімалістичний API, котрий покриває практично всі мої вимоги, що мені важко його з чимось порівнювати. Щось схоже є в Vue 1, AngularJS, LitHTML, проте все влаштовано набагато зрозуміліше, з меньшою кількістю кроків та сутностей.

Як і в Tailwind, AlpineJS дозволяє писати JS прям в HTML. Проте у мене наступний підхід: прості конструкції, які не заважають читанню коду, я залишаю в HTML, а основний код пишу в “компонентах”. Чому компоненти в лапках? Бо це прості функції. Як приклад, компонент головної сторінки Reprose:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import auth from "../../utils/auth";

window.home = () => ({
  init() {
    if (auth.check()) {
      location.href = "/finder";
    }
  },

  login() {
    location.href = "/auth";
  },

  logout() {
    auth.clear();
    location.reload();
  },
});

Можно подивитися як працювати з AlpineJS на прикладах репозиторія Reprose – директорія _frontend. Можу виділити компонент autocomplete.js – це обгортка над Awesomplete яка далася мені через велику напругу, проте я зрозумів що посилання на підключаємі бібліотеки не треба класти в стейт компонента, тому що AlpineJS намагається всі внутрощі компонента обгорнути в Proxy(). Проксі це темна сторона AlpineJS, датабіндінг котрий вимагає знати про нього і вміти працювати з ним, наприклад знати про Alpine.raw().

Single-Page Application завдяки Hotwire Turbo

Ця бібліотека додає обробники до всіх динамічних елементів на сторінці (посилання, форми) та робить перехід між сторінками через підгрузку контента через fetch(), тобто ви фактично залишаєтеся на тій самій сторінці, але підвантажування нового HTML відбувається в фоні. Ще бібліотека вміє завантажувати новий контент при наведенні курсора на посилання, що пришвидшує завантаження контенту та створює у користувача враження миттєвості при переході на іншу сторінку.

Додається нескладно і майже нічого не вимагає при конфігурації “за замовчуванням”:

1
import * as Turbo from "@hotwired/turbo"

Проте, треба знати про <turbo-frame>, це такі активні частки сторінки в котрі може підвантажуватися контент з інших сторінок і туди можно перенаправляти посилання та форми.

Генератор статичного сайту Jekyll

Дуже позитивні емоції, коли я згадую про Jekyll, тому що здається, що його потенценіал як зборщика для фронтенду недооцінений. Ми звикли до Vite/Webpack, нас не страшить репозторій з купою файлів на React, проте я засумував за простотою. Jekyll повертає відчуття передбачуванності – створив файл index.html, запустив bundle exec jekyll serve і побачив сторінку. Потрібні щаблони? Є темплейт-система Liquid котра пропонує достатній набор конструкцій.

Проте щось окрім статики Jekyll згенерувати не здатен. Я використовую Jekyll як основу для створення статичного HTML каркасу в який буде підвантажвуватися контент з API на PHP або з Cloudflare R2. Не весь контент на сайті потребує динаміки. Складаю в Jekyll максимально все що рідко змінюється. Наприклад, є відносно динамічний список категорій – можно запускати перезбірку статики раз на день. По крон-Action в гітхабі брати categories.json з API та класти в collections/categories.json, створювати комміт, що буде запускати перезбірку. Таким чином розділ категорій буде відносно оновлений. Теж саме можно робити з тегами.

Аудит імпортів з vite-bundle-visualizer, перенесення в динамічні імпорті

Потрібно не забувати виносити великі бібліотеки в окремі файли-чанки і підвантажувати їх динамічними import(). Я наштовхнувся на проблему, що перезбірка Vite займає десь 10 секунд. Це мене не влаштувало і я вирішив подивитися що кладеться в бандл. Для цього я знайшов визуалізатор імпортів і знайшов, що більше 50% бандлу займав markdown редактор. Я одразу переніс його в динамічний іморт – на UX це практично не вплинуло, проте швидість збірки тепер складає 1-3 секунди.

Запускається так – потрібно перейти у корінь проєкту де знаходиться vite.config.ts та запустити:

1
2
3
4
5
6
7
8
9
10
11
12
% npx vite-bundle-visualizer
vite v5.4.5 building for production...
✓ 256 modules transformed.
../public/vite/.vite/manifest-assets.json         0.00 kB │ gzip:   0.02 kB
../public/vite/.vite/manifest.json                0.90 kB │ gzip:   0.28 kB
../public/vite/assets/application-Bk0TIr6i.css   46.72 kB │ gzip:   8.62 kB
../public/vite/assets/index-BpMRkEUb.js         118.42 kB │ gzip:  26.67 kB │ map:   291.08 kB
../public/vite/assets/application-ztsoOpTm.js   230.53 kB │ gzip:  74.87 kB │ map:   925.13 kB
../public/vite/assets/easymde-BlVlLp7H.js       329.78 kB │ gzip: 109.50 kB │ map: 1,215.71 kB
✓ built in 2.45s

Generated at /var/folders/r1/k93_bcbd3jb2rph8_sqx7qnw0000gn/T/tmp-88006-5lpxzr7YHJ59/stats.html

Бібліотека для вставки SVG іконок для Jekyll

Бібліотека ще не протестована, проте в будь якому темплейтері шукаю плагін, який додає директиву для вставки SVG-іконок. Майже завжди знаходиться такий. Для Laravel Blade я використовую: blade-ui-kit/blade-icons. Залишаю посилання на бібліотеку в пості, щоб мати можливість повернутися та згадати про знахідку.

Посилання: sdumetz/jekyll-inline-svg

Велика колекція SVG іконок Tabler Icons

Огромна колекція SVG іконок, які вписуються майже в будь який дизайн. Вже декілька років працюю з цим ресурсом та робив їм донат. В колекції є майже все що мені потрібно в повсякденній розробці. Тим паче що з часом ще краще починаєш орієнтуватися в наборі, що сильно спрощує вибір.

Посилання: tabler-icons.io

SVG-анімовані спіннери

Набор якісних анімованих SVG-спінерів. Можно підібрати під ситуацію. Подобається, що такий анімований спіннер можно покласти як SVG-бекграунд і спіннер буде працювати.

Посилання: n3r4zzurr0/svg-spinners

Публікація захищена ліцензією CC BY 4.0 .

© jmas. Деякі права захищено.

Powered by Jekyll with Chirpy theme