- Published on
- Updated on
Выбор технического стека для моего личного блога разработчиков в 2020 году
- Authors
Эта публикация - перевод статьи. Ее автор - Colin McDonnell. Оригинал доступен по ссылке ниже:
Недавно я решил создать свой личный сайт - тот, который вы сейчас читаете, как это бывает!
Удивительно, но собрать "стек технологий", соответствующий моим критериям, оказалось гораздо сложнее, чем ожидалось. Мои критерии довольно просты; я бы ожидал, что большинство разработчиков React имеют аналогичный список. Тем не менее, было удивительно трудно собрать все эти части вместе.
Учитывая отсутствие приличного готового решения, я беспокоюсь, что многие разработчики довольствуются статическими генераторами сайтов, которые накладывают ограничения на интерактивность и гибкость вашего сайта. Мы можем сделать лучше.
tl; dr: Клонируйте репозиторий, чтобы начать работу с этой настройкой: https://github.com/vriad/devii.
Давайте быстро пробежимся по моему списку целей дизайна:
React (+ TypeScript)
Я хочу построить сайт на React и TypeScript. Я люблю их от всего сердца, я использую их для своей повседневной работы, и они будут рядом еще долгое время. Плюс написание непечатного JS заставляет меня чувствовать себя грязным.
Мне не нужны ограничения на то, каким может быть/быть мой личный сайт. Конечно, в настоящее время мой сайт состоит из двух простых, статических постов в блоге. Но в дальнейшем, возможно, я захочу построить страницу, которая содержит интерактивную визуализацию, фильтруемую таблицу, или демо-версию компонента React, который я открыт для просмотра. Даже что-то простое (например, форма подписки на электронную рассылку внизу этой страницы) было гораздо приятнее для реализации в React; как мы использовали, чтобы построить формы заново?
Плюс: я хочу получить доступ к экосистеме npm и всем моим любимым библиотекам пользовательского интерфейса, анимации и стилей. Я искренне надеюсь, что никогда больше не напишу еще одну строку необработанного CSS; CSS-in-JS 4 lyfe baby. Если вы хотите начать со мной вражду в Twitter по этому поводу, во что бы то ни стало на меня.
Хороший авторский опыт
Если это неприятно - писать новые посты в блоге, я не буду этого делать. Это прискорбный закон вселенной. Даже написание постов в блоге с простым HTML - просто набор <p>
тегов в div - просто раздражает достаточно, чтобы доставить мне неприятности. Ответ: уценка конечно!
Статические генераторы сайта (ПНГ) , как Гюго и Джекила обеспечивают неоспоримо замечательный опыт разработки. Все, что вам нужно сделать, touch
это новый файл .md в нужном каталоге и приступить к записи. К сожалению, все известные мне SSG на основе Markdown слишком строгие. Смешивать React и Markdown на одной странице невозможно или сложно. Если это возможно, вероятно, потребуется какой-нибудь плагин / модуль / расширение, файл конфигурации, блоб шаблона или вопиющий взлом. Извините, Хьюго, я не собираюсь переписывать свой код React, React.createElement
как будто это 2015 год.
Ну, это не работает для меня. Я хочу, чтобы мой сайт был первым в React, с добавлением Markdown, когда это облегчает мою жизнь.
Статическая генерация
Как бы я ни любил Jamstack, он не ограничивает его с точки зрения SEO. Многим блогам, работающим на «безголовой CMS», требуется два обхода перед отображением содержимого блога (один для извлечения статического пакета JS, а другой для извлечения содержимого блога из CMS). Это снижает скорость загрузки страницы и удобство работы с пользователем, что соответственно снижает ваш рейтинг в Google.
Вместо этого я хочу, чтобы каждая страница моего сайта была предварительно обработана для набора полностью статических ресурсов, чтобы я мог развернуть их в CDN и получить быструю загрузку страниц везде. Вы можете получить те же преимущества при рендеринге на стороне сервера, но для этого требуется фактическая балансировка нагрузки на сервере и во всем мире для достижения сопоставимой скорости загрузки страниц. Я люблю такие вещи как следующий парень, даже если у меня есть линия. 😅
Мое решение
Я опишу мой окончательный дизайн архитектуры ниже, вместе с моим обоснованием для каждого выбора. Я перенес эту настройку в стартовый / шаблонный сайт, доступный здесь: https://github.com/vriad/devii. Ниже я ссылаюсь на определенные файлы / функции, которые я реализовал; чтобы увидеть их исходный код, просто клонируйте репозиторий git clone [email protected]:vriad/devii.git
Next.js
Я решил создать свой сайт с помощью Next.js. Это не будет неожиданным решением для тех, кто играл в React со статической или серверной визуализацией в последние годы. Next.js быстро обедает на этом рынке, особенно GatsbyJS (извините, фанаты GatsbyJS).
Next.js - безусловно, самый элегантный (на данный момент) способ создания статической генерации или рендеринга на стороне сервера с помощью React. Они только что выпустили свой генератор статических сайтов следующего поколения (игра слов) в версии 9.3 еще в марте. Таким образом, в духе использования технологий весной их жизни Next.js не представляет никакой сложности.
Вот быстрая разбивка структуры проекта. Не нужно понимать каждую его часть; но может быть полезно сослаться на всю оставшуюся часть этого поста.
├── README.md
├── public // all static files (images, etc) go here
├── pages // every .tsx component in this dir becomes a page of the final site
| ├── index.tsx // the home page (which has access to the list of all blog posts)
| ├── blog
| ├── [blog].md // a template component that renders the blog posts under `/md/blog`
├── md
| ├── blog
| ├── devii.md // this page!
├── whatever.md // every MD file in this directory becomes a blog post
├── components
| ├── Code.tsx
| ├── Markdown.tsx
| ├── <various others>
├── loader.ts // contains utility functions for loading/parsing Markdown
├── node_modules
├── tsconfig.json
├── package.json
├── next.config.js
├── next-env.d.ts
├── .gitignore
TypeScript + React
И React, и TypeScript встроены в ДНК Next.js, так что вы получаете их бесплатно, когда настраиваете проект Next.js.
Gatsby, с другой стороны, имеет специальный плагин для поддержки TypeScript, но он официально не поддерживается и, похоже, находится в низком списке их приоритетов. Кроме того, после того, как я возился с ним в течение часа, я не мог заставить его играть хорошо с горячей перезагрузкой.
Разметка авторинга
Используя специальный getStaticProps
хук Next и великолепный динамический импорт, он тривиален для файла Markdown и передает его содержимое в компоненты React в качестве реквизита. Это позволяет получить священный Грааль, который я искал: способность легко смешивать React и Markdown.
Поддержка Frontmatter
Каждый файл Markdown может включать в себя «блок frontmatter», содержащий метаданные. Я реализовал простую служебную функцию (loadPost
), которая загружает файл Markdown, анализирует его содержимое и возвращает объект TypeScript со следующей подписью:
type PostData = {
path: string; // the relative URL to this page, can be used as an href
content: string; // the body of the MD file
title?: string;
subtitle?: string;
date?: number;
author?: string;
author_image?: string;
tags?: string[];
cover_image?: string;
thumb_image?: string;
};
Я реализовал отдельную функцию, loadPosts
которая загружает все файлы Markdown /md/blog
и возвращает их в виде массива ( PostData[]
). Я использую loadPosts
на главной странице этого сайта для отображения списка всех сообщений, которые я написал.
Вдохновленный дизайн
Я использовал замечательный react-markdown
пакет для рендеринга Markdown как компонента React. Компонент My Markdown Rendered ( /components/Markdown.tsx
) предоставляет некоторые стили по умолчанию, вдохновленные дизайном Medium. Просто измените style
плюсы, Markdown.tsx
чтобы настроить дизайн по своему вкусу.
Блоки кода в стиле GitHub
Вы можете легко вставлять блоки кода в сообщения блога, используя синтаксис с тройным обратным тэгом. Укажите язык программирования с помощью «языкового тега», как GitHub!
Чтобы добиться этого, я реализовал пользовательский code
renderer ( /components/Code.tsx
), для react-markdown
которого используется response-syntax-highlighter для обработки выделения. Итак, это:
\`\`\`ts // pretty neat huh? const test = (arg: string) => { return arg.length > 5; }; \`\`\`
превращается в это:
// pretty neat huh?
const test = (arg: string) => {
return arg.length > 5;
};
Генерация RSS
RSS-канал генерируется автоматически из вашего блога. Этот канал генерируется с помощью rss
модуля (для преобразования JSON в формат RSS) и showdown
для преобразования файлов уценки в формат HTML, совместимый с RSS. Фид генерируется на этапе сборки и записывается в виде статического файла /rss.xml
в папку статических ресурсов. Это очень просто. Это радость от возможности легко писать собственные сценарии сборки поверх хуков Next.js getStaticProps
!
SEO
Каждая страница блога автоматически заполняет метатеги на основе метаданных поста. Сюда входят title
тег, meta
теги, og:
теги, метаданные Twitter и link
тег, содержащий канонический URL. Вы можете изменить / дополнить это в PostMeta.ts
компоненте.
Статическая генерация
Вы можете создать полностью статическую версию вашего сайта, используя yarn build && yarn export
. Этот шаг полностью поддерживается Next.js. Статический сайт экспортируется в out
каталог.
После его создания используйте выбранный вами статический хостинг файлов (Firebase Hosting, Vercel, Netlify) для развертывания вашего сайта.
Безумно настраиваемый
Здесь нет ничего "под капотом". Вы можете просматривать и изменять все файлы, которые предоставляют функции, описанные выше. Devii просто предоставляет среду проекта, некоторые утилиты загрузки Markdown-загрузки (in loader.ts
) и некоторые разумные настройки стиля по умолчанию (особенно in Markdown.tsx
).
Чтобы начать настройку, измените index.tsx
(домашняя страница), BlogPost.tsx
(шаблон сообщения блога) и Markdown.tsx
(средство визуализации Markdown).
Начать
Отправляйтесь в репозиторий GitHub, чтобы начать работу: https://github.com/vriad/devii. Если вам нравится этот проект, оставьте «звезду», чтобы помочь большему количеству людей найти Devii! 😎
Чтобы сразу перейти к коду, клонируйте репозиторий и запустите сервер разработки следующим образом:
git clone [email protected]:vriad/devii.git mysite
cd mysite
yarn
yarn dev