Skip to content

Commit

Permalink
docs: Update the "Behind the scenes..." portfolio project
Browse files Browse the repository at this point in the history
  • Loading branch information
gorzelinski committed Nov 18, 2024
1 parent 7179e32 commit d697a8a
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 95 deletions.
101 changes: 55 additions & 46 deletions content/portfolio/gorzelinski/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Behind the scenes of my website
description: 'After several months of designing, coding, and writing, I have finally published my website.'
date: 2022-07-07T16:00:00+02:00
updated: 2022-07-07T16:00:00+02:00
updated: 2024-11-18T15:30:00+02:00
image:
alt: 'Collage of mockups with my website'
src: 'gorzelinski-cover.png'
Expand Down Expand Up @@ -57,47 +57,50 @@ I wanted this site to be typography-oriented, so I spent another chunk of time l

## Design System

Having essentials and some content, I started to create a design system. I wanted it to be flexible, consistent, and easily scalable. I made abstract design primitives (elements) like buttons and headings.
Having essentials and some content, I started to create a design system. I wanted it to be flexible, consistent, and easily scalable. I made abstract design primitives (elements) like buttons and headings. I used them in many different contexts to build more complex and concrete components and sections.

![Design primitives - buttons](buttons.png)

I used them in many different contexts to build more concrete components like this one - landing section of home page.

```jsx
import React from 'react'
import { useTranslation } from 'react-i18next'

import { Hero, H1, P, Button, Tile } from '../elements'
import Typewriter from './typewriter'

const Landing = () => {
const { t } = useTranslation('components/landing')

return (
<Hero>
<Tile as="header">
<H1 $decorative aria-label={t('aria')}>
<Typewriter
strings={[
t('typewriter.design'),
t('typewriter.code'),
t('typewriter.write'),
t('typewriter.create')
]}
></Typewriter>
</H1>
<P $type="lead">{t('description')}</P>
<Button as="a" $type="primary" $grow href="#say-hello">
{t('cta')}
</Button>
</Tile>
</Hero>
)
}

export default Landing
[Panda CSS](https://panda-css.com/) is a CSS-in-JS library that allows us to define some base styles alongside multiple variants of a particular component. This way, we define a library of components that is very convenient to use. Here's how the above button component looks in code (I showed only the base styles because the original code is 300 lines long).

```tsx title="Defining a recipie for a button in Panda CSS"
import { cva } from '@/styled-system/css'
import { sharedTransitionProperties } from '../../utils'

export const button = cva({
base: {
display: 'inline-flex',
alignItems: 'center',
gap: 's',
padding: 's',
fontFamily: 'heading',
fontWeight: 'medium',
letterSpacing: 'wide',
textDecoration: 'none',
transitionProperty: 'background-color, color',
...sharedTransitionProperties,
cursor: 'pointer',
_disabled: {
cursor: 'not-allowed',
pointerEvents: 'none'
},
'& > span': {
flexShrink: 0
}
}
variants: {
// Button variants like primary, outline, etc.
},
defaultVariants: {
// Chose default variants when button is used without any
},
compoundVariants: [
// Compound variants allow for more complex logic
]
})
```

And yes - styles are written in TypeScript. It's unusual, but it's really convenient. You don't even need to remember your design tokens - autocompletion has you covered.
With design primitives, components, and sections, I created responsive templates for every page.

![Templates of home and portfolio pages](templates-home-portfolio.png)
Expand All @@ -112,26 +115,32 @@ I found that flexibility is desirable during the whole process. Same as breaks -
>
> &mdash;<cite> David Bowie</cite>
## Gatsby
## ~~Gatsby~~

To implement my website, I used Static Site Generator - Gatsby. Pages are built and optimized in the generation process, even before the user requests them. Websites created with this approach are usually more efficient than traditional solutions like WordPress.
~~To implement my website, I used Static Site Generator - Gatsby. Pages are built and optimized in the generation process, even before the user requests them. Websites created with this approach are usually more efficient than traditional solutions like WordPress.~~

But if pages are prebuilt, how to know which theme the user chose? Implementing the theme-switching feature was an unexpected challenge for me. But, after reading about Gatsby's build process and testing, I managed to make it work smoothly.
~~But if pages are prebuilt, how to know which theme the user chose? Implementing the theme-switching feature was an unexpected challenge for me. But, after reading about Gatsby's build process and testing, I managed to make it work smoothly.~~

## Next.js

"If it ain't broke, don't fix it," people say. Even though my previous website was working pretty well, working on it became harder and harder. That's why I migrated to a new tech stack. Mostly. It was also an opportunity to learn something new, so [Next.js](/blog/next-js-overview-in-1000-words/) became my new framework. It's also based on React, so I didn't need to learn everything from scratch.

However, both of those tools differ significantly. Gatsby has a rich ecosystem of plugins. You're thinking about functionality, and there is probably a plugin providing it. This system is a double-edged sword, however. You can effortlessly implement a new functionality but may have a problem when a plugin is no longer supported. In Next.js, you need to implement more things manually. You need to know better what you're doing, but it's more flexible and easier to maintain in the future.

## Testing

Besides manual testing, I wrote automated tests. I used `Jest` for component testing. To test integration between components and more complex user behavior, I used `Cypress` with `cypress-axe`. Those tests cover different website aspects - accessibility, internationalization, SEO, and more.
Besides manual testing, I wrote automated tests. I used Jest for component testing. ~~To test integration between components and more complex user behavior, I used Cypress with cypress-axe. Those tests cover different website aspects - accessibility, internationalization, SEO, and more.~~

I also migrated my E2E test suites to Playwright. It offers full parity with Cypress and more. I won't spend much time explaining the differences between these two frameworks because I wrote a blog post comparing them - [Playwright vs. Cypress - comparison of E2E testing frameworks](/blog/playwright-vs-cypress-comparison-of-e2e-testing-frameworks/).

## GitHub

I'll try to add content and features to my website regularly, so long-term maintenance was the aim from the start. I enabled continuous integration with Github actions to minimize the number of bugs and gain more confidence in my project. Every change in the codebase triggers a series of checks and tests.

![Graph of tasks in continuous integration](ci.png)

I use Conventional Commits to format messages and GitHub Flow as a branching strategy.

<Callout variant="info">
Playwright runs tests in parallel by default, so I could significantly simplify my CI GitHub Action. Now, it's just one job with a configuration similar to Playwright's default.

I recently updated my website to a new technological stack with TypeScript and Next.js. I touched every part of my website, so there is much to write about. I'll update this project soon. Stay tuned!
![Graph of tasks in continuous integration v2](ci-v2.png)

</Callout>
I use Conventional Commits to format messages and GitHub Flow as a branching strategy.
106 changes: 57 additions & 49 deletions content/portfolio/gorzelinski/index.pl.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Kulisy powstawania mojej strony
description: 'Po kilku miesiącach projektowania, kodowania i pisania, w końcu opublikowałem moją stronę.'
date: 2022-07-07T16:00:00+02:00
updated: 2022-07-07T16:00:00+02:00
updated: 2024-11-18T15:30:00+02:00
image:
alt: 'Kolaż makiet z moją stroną internetową'
src: 'gorzelinski-cover.png'
Expand Down Expand Up @@ -30,7 +30,7 @@ Nie jest to poziom szkiców Da Vinciego, ale były przydatne zanim zabrałem si

## Wireframes

Wireframes powinny być pomiędzy szkicami, a prototypami o wysokiej szczegółowości. Nie przejmując się za bardzo fontami i kolorami, zrobiłem wiele takich makiet.
Wireframes powinny znajdować się pomiędzy szkicami, a prototypami o wysokiej szczegółowości. Nie przejmując się za bardzo fontami i kolorami, zrobiłem wiele takich makiet.

![Makiety sekcji landing](wireframes-landing.png)

Expand All @@ -48,7 +48,7 @@ Na wyborze kolorów spędziłem więcej czasu niż chciałbym przyznać. Ale po

## Typografia

Chciałem, aby strona była zorientowana na typografię, więc kolejny kawał czasu spędziłem poszukując krojów pisma. Moim celem było zestawienie nowoczesnego fontu bezszeryfowego z bardziej klasycznym szeryfowym. Potrzebowałem także fontu do fragmentów kodu.
Chciałem, aby strona była zorientowana na typografię, więc kolejny kawał czasu spędziłem poszukując odpowiednich fontów. Moim celem było zestawienie nowoczesnego fontu bezszeryfowego z bardziej klasycznym szeryfowym. Potrzebowałem także fontu do fragmentów kodu.

![Montserrat - font dla nagłówków](montserrat.png)

Expand All @@ -58,52 +58,56 @@ Chciałem, aby strona była zorientowana na typografię, więc kolejny kawał cz

## Design system

Mając podstawy i trochę treści, zacząłem tworzyć system projektowania. Chciałem aby był elastyczny, spójny i łatwo skalowalny. Stworzyłem małe, abstrakcyjne elementy jak przyciski i nagłówki.
Mając podstawy i część treści, zacząłem tworzyć system projektowania. Chciałem, aby był elastyczny, spójny i łatwo skalowalny. Stworzyłem abstrakcyjne, prymitywne elementy takie jak przciski i nagłówki. Wykorzystałem je w wielu różnych kontekstach do zbudowania bardziej złożonych komponentów i sekcji.

![Elementy projektowe - przyciski](buttons.png)

Używałem tych elementów w wielu różnych kontekstach, aby stworzyć bardziej konkretne komponenty, jak ten - pierwsza sekcja na stronie głównej.

```jsx
import React from 'react'
import { useTranslation } from 'react-i18next'

import { Hero, H1, P, Button, Tile } from '../elements'
import Typewriter from './typewriter'

const Landing = () => {
const { t } = useTranslation('components/landing')

return (
<Hero>
<Tile as="header">
<H1 $decorative aria-label={t('aria')}>
<Typewriter
strings={[
t('typewriter.design'),
t('typewriter.code'),
t('typewriter.write'),
t('typewriter.create')
]}
></Typewriter>
</H1>
<P $type="lead">{t('description')}</P>
<Button as="a" $type="primary" $grow href="#say-hello">
{t('cta')}
</Button>
</Tile>
</Hero>
)
}

export default Landing
[Panda CSS](https://panda-css.com/) to biblioteka CSS-in-JS, która pozwala na definiowanie bazowych stylów wraz z wieloma wariantami konkretnego komponentu. W ten sposób, definiujemy bibliotekę komponentów, z której przyjemnie się korzysta. Poniżej pokazalem jak powyższy przycisk wygląda w kodzie (ograniczyłem style do tych bazowych, ponieważ oryginalny kod jest długi na 300 linii).

```tsx title="Definiowanie przepisu na przycisk w Panda CSS"
import { cva } from '@/styled-system/css'
import { sharedTransitionProperties } from '../../utils'

export const button = cva({
base: {
display: 'inline-flex',
alignItems: 'center',
gap: 's',
padding: 's',
fontFamily: 'heading',
fontWeight: 'medium',
letterSpacing: 'wide',
textDecoration: 'none',
transitionProperty: 'background-color, color',
...sharedTransitionProperties,
cursor: 'pointer',
_disabled: {
cursor: 'not-allowed',
pointerEvents: 'none'
},
'& > span': {
flexShrink: 0
}
}
variants: {
// Button variants like primary, outline, etc.
},
defaultVariants: {
// Chose default variants when button is used without any
},
compoundVariants: [
// Compound variants allow for more complex logic
]
})
```

I tak - style są definiowane w TypeScripcie. Nietypowe, ale bardzo wygodne. NIe musisz nawet pamiętać swoich design tokenów - autouzupełnianie ci pomoże.

Mając elementy, komponenty i sekcje, stworzyłem responsywne szablony dla każdej strony.

![Szablony strony głównej i portfolio](templates-home-portfolio.png)

Mój design nie jest skończony i bardziej przypomina proces. Cały czas go rozwijam. W związku z tym możesz zagrać w "znajdź różnicę" pomiędzy tym pokazem, a aktualną wersją mojej strony.
Mój design nie jest skończony i bardziej przypomina proces. Cały czas go rozwijam. W związku z tym możesz zagrać w "znajdź różnicę", pomiędzy tymi szablonami, a aktualną wersją mojej strony.

![Szablony strony o mnie i bloga](templates-about-blog.png)

Expand All @@ -113,26 +117,30 @@ Zauważyłem, że elastyczność jest pożądana podczas całego procesu. Podobn
>
> &mdash;<cite> David Bowie</cite>
## Gatsby
## ~~Gatsby~~

~~Do zaimplementowania mojej strony użyłem generatora stron statycznych - Gatsby. Strony są budowane i optymalizowane w procesie generowania, nawet zanim użytkownik ich zażąda. Strony internetowe stworzone przy pomocy tego podejścia są zwykle wydajniejsze niż tradycyjne rozwiązania jak WordPress.~~

~~Jeżeli strony są generowane wcześniej, skąd wiedzieć jaki motyw wybrał użytkownik? Zaimplementowanie funkcjonalności zmieniania motywów było dla mnie niespodziewanym wyzwaniem. Ale po przeczytaniu o procesie budowania i testach udało mi się zrobić, aby działało to gładko.~~

Do zaimplementowania mojej strony użyłem generatora stron statycznych - Gatsby. Strony są budowane i optymalizowane w procesie generowania, nawet zanim użytkownik ich zażąda. Strony internetowe stworzone przy pomocy tego podejścia są zwykle wydajniejsze niż tradycyjne rozwiązania jak WordPress.
## Next.js

Jeżeli strony są generowane wcześniej, skąd wiedzieć jaki motyw wybrał użytkownik? Zaimplementowanie funkcjonalności zmieniania motywów było dla mnie niespodziewanym wyzwaniem. Ale po przeczytaniu o procesie budowania i testach udało mi się zrobić, aby działało to gładko.
Słyszy się, że "jeżeli coś działa, to nie ruszaj". Pomimo, że poprzednia wersja mojej strony działała całkiem nieźle, to działanie _nad nią_ stawało się coraz trudniejsze. Dlatego przemigrowałem mój stos technologiczny. Głównie dlatego. Była to też niezła okazja do nauki czegoś nowego, dlatego [Next.js](/pl/blog/next-js-overview-in-1000-words/) stał się moim nowym frameworkiem. On także bazuje na Reac'ie, więc nie musiałem uczyć się wszystkiego od zera. Jednakże, oba te narzędzia różnią się znacznie. Gatsby oferuje bogaty ekosystem pluginów. Myślisz o jakiejś funkcjonalności i najprawdopodobniej istenie na to wtyczka. Jest to jednak broń obosieczna. W łatwy sposób możesz dodać funkcjonalność, ale zaczynasz mieć problem, gdy któryś z pluginów przestaje być wspierany. W Next.js, więcej rzeczy musisz implementować ręcznie. Musisz mieć lepsze pojęcie o tym co robisz, ale daje ci to elastyczność i łatwiejsze zarządzanie w przyszłości.

## Testowanie

Poza manualnymi testami, napisałem zautomatyzowane testy. Użyłem frameworka `Jest` do testowania komponentów. Do testowania integracji pomiędzy komponentami i bardziej złożonych zachowań użytkownika, wykorzystałem framework `Cypress` wraz z `cypress-axe`. Te testy pokrywały różne aspekty strony - dostępność, internacjonalizację, SEO i więcej.
Poza manualnymi testami, napisałem zautomatyzowane testy. Użyłem frameworka Jest do testowania komponentów. ~~Do testowania integracji pomiędzy komponentami i bardziej złożonych zachowań użytkownika, wykorzystałem framework Cypress wraz z cypress-axe. Te testy pokrywały różne aspekty strony - dostępność, internacjonalizację, SEO i więcej.~~

Przemigrowałem także zestawy moich testów E2E, wykorzystując Playwright. Oferuje on parytet funkcjonalności w stosunku do Cypressa, a nawet więcej. Nie będę może poświęcał tu wiele czasu na wyjaśnianie różnic pomiędzy nimi, bo napisałem post, który je porównuje - [Playwright vs. Cypress - porównanie frameworków do testowania E2E](/blog/playwright-vs-cypress-comparison-of-e2e-testing-frameworks/).

## GitHub

Będę się starał dodawać treści i funkcjonalności regularnie, dlatego długotrwała konserwacja była celem od początku. Uruchomiłem ciągłą integrację wykorzystując akcje GitHub, aby zminimalizować liczbę błędów i zyskać więcej pewności co do mojego projektu. Każda zmiana w kodzie uruchamia serię weryfikacji i testów.

![Graf zadań w ciągłej integracji](ci.png)

Używam konwencji Conventional Commits do formatowania wiadomości i GitHub Flow jako strategię rozgałęziania.

<Callout variant="info">
Playwright, w domyśle, uruchamia testy równolegle, więc mogłem znacznie uprościć moją akcję GitHub CI. Aktualnie jest to jeden job z konfiguracją zbliżoną do tej domyślnej od Playwright'a.

Niedawno uaktualniłem moją stronę do nowego stosu technologicznego wykorzystując TypeScript i Next.js. Dotknąłem każdej części mojej strony, więc jest wiele do napisania. Wkrótce zaktualizuję ten projekt. Bądźcie czujni!
![Graf zadań w ciągłej integracji w wersji drugiej](ci-v2.png)

</Callout>
Używam konwencji [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) do formatowania wiadomości i GitHub Flow jako strategię rozgałęziania.
Binary file added public/images/portfolio/gorzelinski/ci-v2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d697a8a

Please sign in to comment.