Супербыстрый веб-фреймворк Astro: подробный обзор

Astro  —  универсальный веб-фреймворк, разработанный для создания быстрых сайтов с большим количеством контента. К ним относятся большинство маркетинговых и издательских сайтов, сайты документации, блоги, портфолио и ряд сайтов электронной коммерции. 

При этом Astro не вполне подходит для создания некоторых сложных приложений, например информационных панелей администратора, электронных почтовых ящиков, социальных сетей, планировщиков и т.д. 

Astro использует рендеринг на стороне сервера и является фреймворком для разработки многостраничных приложений (аббр. MPA). Сайт MPA состоит из нескольких HTML-страниц, написанных с помощью HTML, CSS и JavaScript (или TypeScript). MPA отличаются от одностраничных приложений (аббр. SPA), которые задействуют рендеринг на стороне клиента и динамически отрисовывают каждый маршрут непосредственно в браузере. 

Astro превосходит SPA по скорости начальной загрузки и краткому времени до интерактивности (аббр. TTI). TTI измеряет время, требуемое странице для достижения полной интерактивности. 

Astro не зависит от UI. Официально поддерживает React, Preact, Solid, Svelte, Vue и Lit. На одной странице может мирно сосуществовать код, написанный разными фреймворками. 

Не веб-фреймворк, а просто чудо какое-то! 

Посмотрим, как он работает. 

Установка и запуск Astro

Astro требует версии ^14.18.0 || >=16.12.0 Node.js. Для установки выполняем следующую команду:

% yarn create astro
yarn create v1.22.10
[1/4] 🔍  Resolving packages...(Разрешение зависимостей)
[2/4] 🚚  Fetching packages...(Получение зависимостей) 
[3/4] 🔗  Linking dependencies...(Связывание зависимостей) 
[4/4] 🔨  Building fresh packages...(Сборка новых пакетов) 
success Installed "[email protected]" with binaries:
      - create-astro
[##################################################################################################################] 114/114
Welcome to Astro! (Добро пожаловать в Astro) (create-astro v1.1.0)
Lets walk through setting up your new Astro project.(Займемся настройкой нового проекта Astro)

✔ Where would you like to create your new project? … ./my-astro-site (Где вы намерены создать новый проект?… ./my-astro-site)
✔ Which template would you like to use? (Какой шаблон планируете применить?)
❯   Just the basics (recommended) (Базовый — рекомендовано)
    Blog (Блог) 
    Portfolio (Портфолио)
    Documentation Site (Сайт документации) 
    Empty project (Пустой проект) 
✔ Template copied! (Шаблон скопирован!)
✔ Would you like to install yarn dependencies? (recommended) … yes (Намерены установить зависимости yarn? — рекомендовано — … да)
✔ Packages installed! (Пакеты установлены!)
✔ Would you like to initialize a new git repository? (optional) … no (Хотите создать новый git-репозиторий? — по выбору — … нет)
ℹ Sounds good! You can come back and run git init later. (Отличная идея! Вы можете вернуться и выполнить команду git init позже) 
✔ How would you like to setup TypeScript? (Какие настройки TypeScript намерены применить?) 
    Relaxed (Нестрогие) 
❯   Strict (recommended) (Строгие — рекомендовано)
    Strictest (Максимально строгие) 
    I prefer not to use TypeScript (Не использовать TypeScript) 
✔ TypeScript settings applied!(Настройки TypeScript применены!)
✔ Setup complete. (Настройка завершена)
✔ Ready for liftoff! (К запуску готов!)

Next steps (Следующие шаги) 

You can now cd into the my-astro-site project directory. (Через cd переходим в каталог проекта my-astro-site)
Run yarn dev to start the Astro dev server. CTRL-C to close. (Командой yarn dev запускаем сервер разработки Astro, а командой CTRL-C останавливаем его работу)
Add frameworks like react and tailwind to your project using astro add (Командой astro add добавляем в проект фреймворки, например React и Tailwind)

Stuck? Come join us at https://astro.build/chat (Столкнулись с проблемами? Здесь https://astro.build/chat вам помогут) 
Good luck out there, astronaut. (В добрый путь, космонавт)

✨  Done in 88.00s. (Выполнено за 88 сек)

Проект создается в папке my-astro-site. package.json находится в корневом каталоге: 

{
"name": "@example/basics",
"type": "module",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"astro": "^1.5.0"
}
}

package.json включает 2 типа зависимостей: dependencies и devDependencies. В Astro они преимущественно работают схожим образом, поскольку оба типа востребованы во время сборки. Для запуска проекта рекомендуется разместить все зависимости в dependencies, а devDependencies использовать только для особых потребностей. 

При выборе базового шаблона Just the basics в процессе установки предоставляется только одна зависимость astro (строка 14).

Выполняем команду yarn astro и получаем перечень всех команд Astro: 

% yarn astro  
yarn run v1.22.17
$ astro

astro  v1.5.2 Build faster websites. (Сборка быстрых сайтов) 

astro [command] [...flags]

Commands (Команды)
              add  Add an integration. (Добавить интеграцию)
            build  Build your project and write it to disk. (Создать проект и записать на диск) 
            check  Check your project for errors. (Проверить проект на наличие ошибок) 
              dev  Start the development server. (Запустить сервер разработки) 
             docs  Open documentation in your web browser. (Открыть документацию в веб-браузере)
          preview  Preview your build locally. (Предварительно просмотреть сборку локально)
        telemetry  Configure telemetry settings. (Настроить параметры телеметрии)

Global Flags (Глобальные флаги)
  --config <path>  Specify your config file. (Указать конфигурационный файл)
    --root <path>  Specify your project root folder. (Указать корневой каталог проекта)
        --verbose  Enable verbose logging. (Разрешить подробное логирование) 
         --silent  Disable all logging. (Запретить логирование)
        --version  Show the version number and exit. (Показать номер версии и выйти)
           --help  Show this help message. (Показать справочное сообщение) 

✨  Done in 1.21s. (Выполнено за 1,21 сек)

Запускаем Astro в режиме dev:

% yarn dev
yarn run v1.22.17
$ astro dev
🚀 astro v1.5.0 started in 52ms

┃ Local http://127.0.0.1:3000/
┃ Network use --host to expose

Сайт по умолчанию доступен по адресу http://localhost:3000/:

Для основных IDE существуют плагины Astro. Ниже представлено расширение VS Code для файлов .astro, которое поддерживает синтаксическое и семантическое выделение, диагностические сообщения, быстрые исправления, сортировку импортов, форматирование кода и т.д.

Исходный каталог Astro 

После установки каталог my-astro-site выглядит следующим образом: 

my-astro-site
├── README.md
├── public
│ └── favicon.svg
├── src
│ ├── components
│ ├── layouts
│ ├── pages
│ └── env.d.ts
├── astro.config.mjs
├── package.json
├── tsconfig.json
└── .gitignore
  • my-astro-site  —  каталог, содержащий веб-фреймворк Astro. 
  • README.md описывает структуру проекта и скрипты. 
  • public  —  каталог для статических активов (англ. assets), включая favicon.svg.
  • src/components  —  рекомендуемый каталог для компонентов Astro.
  • src/layouts  —  рекомендуемый каталог для создания переиспользуемых шаблонов страниц. 
  • src/pages обеспечивает маршрутизацию для страниц Astro на основе каталогов. Каждый файл в каталоге src/pages становится конечной точкой сайта. 
  • src/env.d.ts ссылается на объявления типов TypeScript, относящихся к проекту Astro. 
  • astro.config.mjs  —  конфигурационный файл Astro.
  • tsconfig.json  —  конфигурационный файл TypeScript.

Компоненты Astro 

Компоненты  —  основные строительные блоки проекта Astro. Они обрабатывают только HTML-шаблоны без этапа выполнения на стороне клиента. 

Синтаксис компонента Astro представляет собой расширенную версию HTML по аналогии с JSX. Все компоненты имеют расширение файла .astro. Во время сборки они отображаются в HTML. Компонент Astro состоит из 2 основных частей: скрипта и шаблона. 

Скрипт компонента напоминает React, написанный на JavaScript или TypeScript. Он может импортировать другие компоненты Astro, компоненты фреймворка и данные JSON, получать содержимое из API или базы данных, а также создавать переменные с возможностью отсылки к ним в шаблоне компонента. 

Astro задействует разграничительные метки в коде (---) для связывания начала и конца скрипта компонента. 

Шаблон компонента находится под скриптом. Он определяет HTML-вывод компонента. Шаблон поддерживает выражения JavaScript, импорт компонентов и специальные директивы Astro. Данные и значения, определяемые в скрипте, могут использоваться в шаблоне для создания динамически генерируемого HTML.

По умолчанию каталог src/components включает один компонент  —  Card.astro:

components
└── Card.astro

Card  —  это компонент с пропсами (англ. props): href, title и body. При нажатии на компонент заголовка title страница перенаправляется к href:

Ниже представлен компонент src/components/Card.astro:

---
export interface Props {
title: string;
body: string;
href: string;
}

const { href, title, body } = Astro.props;
---

<li class="link-card">
<a href={href}>
<h2>
{title}
<span>&rarr;</span>
</h2>
<p>
{body}
</p>
</a>
</li>
<style>
.link-card {
list-style: none;
display: flex;
padding: 0.15rem;
background-color: white;
background-image: var(--accent-gradient);
background-size: 400%;
border-radius: 0.5rem;
background-position: 100%;
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -2px rgba(0, 0, 0, 0.1);
}

.link-card > a {
width: 100%;
text-decoration: none;
line-height: 1.4;
padding: 1rem 1.3rem;
border-radius: 0.35rem;
color: #111;
background-color: white;
opacity: 0.8;
}
h2 {
margin: 0;
font-size: 1.25rem;
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
p {
margin-top: 0.5rem;
margin-bottom: 0;
color: #444;
}
.link-card:is(:hover, :focus-within) {
background-position: 0;
}
.link-card:is(:hover, :focus-within) h2 {
color: rgb(var(--accent));
}
</style>

Данный компонент, разграниченный метками кода в строках 1 и 9, определяет скрипт.

  • Строки 2–6. Определение интерфейса Props.
  • Строка 8. Деструктуризация из Props 3 переменных const: href, title и body.

В строках 11–63 выполняется определение шаблона компонента.

  • Строки 11–21. Определение шаблона JSX с интерполированными значениями href, title и body.
  • Строки 22–63. Определение стиля шаблона. 
  • Строка 28. Определение background-image как градиентного цвета с помощью переменной CSS. Он выделяет каждую третью карточку из четырех при достаточно широком окне браузера. На следующем изображении примером такого акцента служит красная рамка: 

А красное сердечко ❤️ ️на четвертой карте  —  это просто эмоджи.

Макеты Astro 

Макеты  —  это специальный компонент Astro для создания переиспользуемых шаблонов страниц с общими настройками, такими как верхняя часть страницы (англ. header, “шапка”) и нижняя (англ. footer, “подвал”). Эти общие блоки реализуются как компонент макета, доступный для переиспользования страницами. Как правило, такой компонент получает имя с расширением .astro или  .md.

По умолчанию каталог src/layouts включает один компонент Layout.astro:

layouts
└── Layout.astro

Компонент Layout предоставляет как оболочку страницы (элементы <html>, <head> и <body>), так и <slot />. <slot /> указывает место вставки дочернего компонента на странице макета. 

Ниже представлен компонент src/layouts/Layout.astro:

---
export interface Props {
title: string;
}

const { title } = Astro.props;
---

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<slot />
<style is:global>
:root {
--accent: 124, 58, 237;
--accent-gradient: linear-gradient(
45deg,
rgb(var(--accent)),
#da62c4 30%,
white 60%
);
}
html {
font-family: system-ui, sans-serif;
background-color: #f6f6f6;
}
code {
font-family: Menlo, Monaco, Lucida Console, Liberation Mono,
DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
}
</style>
</body>
</html>

Данный компонент, разграниченный метками кода в строках 1 и 7, определяет скрипт.

  • Строки 2–4. Определение интерфейса Props.
  • Строка 6. Деструктуризация из Props переменной const  —  title.

В строках 9-40 выполняется определение шаблона компонента.

  • Строки 11–17. Определение элемента документа <head>. Для заголовка устанавливается интерполированное значение title (строка 16).
  • Строка 19. <slot /> размещает дочерний компонент. 
  • Строки 20–38. Определение стиля шаблона. 
  • Строка 20. is:global  —  директива Astro, которая задает глобальную область видимости стиля. 

В представленном макете нет видимых компонентов, кроме <slot />. Общие части макета  —  элемент <head> и глобальный стиль. 

Для сайта по умолчанию View Page Source (Просмотр исходного кода страницы) браузер показывает преобразованный контент элемента <head>, в котором для заголовка устанавливается значение Welcome to Astro (строка 6 в нижеследующем коде), а также глобальный стиль (строки 7–19):

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<meta name="generator" content="Astro v1.5.2">
<title>Welcome to Astro.</title>
<style>:root {
--accent: 124, 58, 237;
--accent-gradient: linear-gradient(45deg, rgb(var(--accent)), #da62c4 30%, white 60%);
}
html {
font-family: system-ui, sans-serif;
background-color: #F6F6F6;
}
code {
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Courier New, monospace;
}
</style>
<style>.link-card:where(.astro-CDLE2A7R){list-style:none;display:flex;padding:0.15rem;background-color:white;background-image:var(--accent-gradient);background-size:400%;border-radius:0.5rem;background-position:100%;transition:background-position 0.6s cubic-bezier(0.22,1,0.36,1);box-shadow:0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -2px rgba(0,0,0,0.1)}.link-card:where(.astro-CDLE2A7R)>a:where(.astro-CDLE2A7R){width:100%;text-decoration:none;line-height:1.4;padding:1rem 1.3rem;border-radius:0.35rem;color:#111;background-color:white;opacity:0.8}h2:where(.astro-CDLE2A7R){margin:0;font-size:1.25rem;transition:color 0.6s cubic-bezier(0.22,1,0.36,1)}p:where(.astro-CDLE2A7R){margin-top:0.5rem;margin-bottom:0;color:#444}.link-card:where(.astro-CDLE2A7R):is(:hover,:focus-within){background-position:0}.link-card:where(.astro-CDLE2A7R):is(:hover,:focus-within) h2:where(.astro-CDLE2A7R){color:rgb(var(--accent))}</style>
<style>main:where(.astro-IXC3FSUM){margin:auto;padding:1.5rem;max-width:60ch}h1:where(.astro-IXC3FSUM){font-size:3rem;font-weight:800;margin:0}.text-gradient:where(.astro-IXC3FSUM){background-image:var(--accent-gradient);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-size:400%;background-position:0%}.instructions:where(.astro-IXC3FSUM){line-height:1.6;margin:1rem 0;border:1px solid rgba(var(--accent),25%);background-color:white;padding:1rem;border-radius:0.4rem}.instructions:where(.astro-IXC3FSUM) code:where(.astro-IXC3FSUM){font-size:0.875em;font-weight:bold;background:rgba(var(--accent),12%);color:rgb(var(--accent));border-radius:4px;padding:0.3em 0.45em}.instructions:where(.astro-IXC3FSUM) strong:where(.astro-IXC3FSUM){color:rgb(var(--accent))}.link-card-grid:where(.astro-IXC3FSUM){display:grid;grid-template-columns:repeat(auto-fit,minmax(24ch,1fr));gap:1rem;padding:0}</style>
<script type="module" src="/@vite/client"></script>
<script type="module" src="/@fs/Users/jenniferfu/funStuff/my-astro-site/node_modules/.vite/deps/astro_runtime_client_hmr__js.js?v=d56a8af8"></script>
<script type="module" src="/src/layouts/Layout.astro?astro&type=style&index=0&lang.css"></script>
<script type="module" src="/src/components/Card.astro?astro&type=style&index=0&lang.css"></script>
<script type="module" src="/src/pages/index.astro?astro&type=style&index=0&lang.css"></script>
</head>

Страницы Astro

Страницы представляют собой файлы, размещенные в каталоге src/pages. Они отвечают за маршрутизацию, загрузку данных и общий макет для каждой страницы сайта. Маршрутизация основана на индексном фале или имени каталога индексного файла. Поддерживаются следующие типы файлов: 

  • .astro;
  • .md;
  • .mdx (с установленной интеграцией MDX);
  • .html;
  • [.js/.ts] (как конечные точки). 

По умолчанию каталог src/pages включает один компонент index.astro:

pages
└── index.astro

Когда URL является /, index.astro определяет UI, подлежащий отображению. Ниже представлен src/pages/index.astro:

---
import Layout from '../layouts/Layout.astro';
import Card from '../components/Card.astro';
---

<Layout title="Welcome to Astro.">
<main>
<h1>Welcome to <span class="text-gradient">Astro</span></h1>
<p class="instructions">
To get started, open the directory <code>src/pages</code> in your project.<br
/>
<strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message above.
</p>
<ul role="list" class="link-card-grid">
<Card
href="https://docs.astro.build/"
title="Documentation"
body="Learn how Astro works and explore the official API docs."
/>
<Card
href="https://astro.build/integrations/"
title="Integrations"
body="Supercharge your project with new frameworks and libraries."
/>
<Card
href="https://astro.build/themes/"
title="Themes"
body="Explore a galaxy of community-built starter themes."
/>
<Card
href="https://astro.build/chat/"
title="Community"
body="Come say hi to our amazing Discord community. ❤️"
/>
</ul>
</main>
</Layout>

<style>
main {
margin: auto;
padding: 1.5rem;
max-width: 60ch;
}
h1 {
font-size: 3rem;
font-weight: 800;
margin: 0;
}
.text-gradient {
background-image: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 400%;
background-position: 0%;
}
.instructions {
line-height: 1.6;
margin: 1rem 0;
border: 1px solid rgba(var(--accent), 25%);
background-color: white;
padding: 1rem;
border-radius: 0.4rem;
}
.instructions code {
font-size: 0.875em;
font-weight: bold;
background: rgba(var(--accent), 12%);
color: rgb(var(--accent));
border-radius: 4px;
padding: 0.3em 0.45em;
}
.instructions strong {
color: rgb(var(--accent));
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 1rem;
padding: 0;
}
</style>

Данный компонент, разграниченный метками кода в строках 1 и 4, определяет скрипт.

  • Строка 2. Импорт Layout.
  • Строка 3. Импорт Card.

В строках 6-82 выполняется определение шаблона компонента.

  • Строка 6. Вызов Layout с указанным заголовком и размещение его дочернего компонента (строки 7–36) в <slot /> в Layout.
  • Строка 8. Определение заголовка h1  —  Welcome to Astro.
  • Строки 9–13. Определение параграфа инструкций. 
  • Строки 16–19. Создание Card с названием Documentation.
  • Строки 20–24. Создание Card с названием Integrations.
  • Строки 25–29. Создание Card с названием Themes.
  • Строки 30–34. Создание Card с названием Community. Текст тела карточки включает эмоджи ❤️ (строка 33).
  • Строки 39–82. Определение стиля шаблона.

Директивы шаблона Astro 

Директивы шаблона  —  особый тип HTML-атрибутов, доступных внутри шаблона компонента Astro (файлы .astro), а некоторые из них могут использоваться в файлах .mdx. Они предназначены для управления поведением элемента или компонента, но непосредственно в окончательный HTML-вывод они никогда не включаются.

Директива шаблона содержит двоеточие (:) в своем имени, принимая за основу форму X:Y. Она должна быть видна компилятору, т.е. не скрыта в формате <X {...attr}>.

Большинство директив шаблона не имеют значений, например <X client:load />. Однако есть и такие, которые принимают пользовательские значения, например <X class:list={['some-css-class']} />.

Общие директивы

Общие директивы применяются в компонентах Astro.

  • class:list={...} принимает массив значений класса и преобразует их в строку класса. Список состоит из строк, всех истинных ключей объектов, упрощенных массивов и упрощенных множеств. Повторяющиеся значения удаляются автоматически.
<!-- This -->
<span class:list={[ 'hello goodbye', { hello: true, world: true }, new Set([ 'hello', 'friend' ]) ]} />
<!-- Becomes -->
<span class="hello goodbye world friend"></span>
  • set:html={string} вставляет HTML-строку в элемент по аналогии с установкой el.innerHTML. Astro НЕ выполняет автоматическое экранирование значения.
---
const rawHTMLString = "Hello <strong>World</strong>"
---
<h1>{rawHTMLString}</h1>
<!-- Output: <h1>Hello &lt;strong&gt;World&lt;/strong&gt;</h1> -->
<h1 set:html={rawHTMLString} />
<!-- Output: <h1>Hello <strong>World</strong></h1> -->
  • set:text={string} вставляет текстовую строку в элемент. В отличие от set:html значение string автоматически экранируется Astro.
<!-- This -->
<div set:text={someText}/>
<!-- Is equivalent to -->
<div>{someText}</div>

Клиентские директивы 

Клиентские директивы управляют процессом рендеринга дополнительных компонентов на странице. По умолчанию компоненты не добавляются на стороне клиента. Если директива client:* отсутствует, HTML отображается на странице без JavaScript.

  • client:load загружает и добавляет компонент JavaScript сразу при загрузке страницы:
<BuyButton client:load />
  • client:idle загружает и добавляет компонент JavaScript после завершения начальной загрузки страницы и запуска события requestIdleCallback:
<ShowHideButton client:idle />
  • client:visible загружает и добавляет компонент JavaScript, как только тот попадает в область просмотра пользователя. Для внутреннего отслеживания видимости применяется IntersectionObserver:
<HeavyImageCarousel client:visible />
  • client:media={string} загружает и добавляет компонент JavaScript после выполнения определенного медиа-запроса CSS:
<SidebarToggle client:media="(max-width: 50em)" />
  • client:only={string} пропускает рендеринг HTML на стороне сервера и отрисовывает только на стороне клиента. Действует аналогично client:load, т.е. загружает, отображает и добавляет компонент сразу при загрузке страницы:
<SomeReactComponent client:only="react" />

Директивы скрипта и стиля 

Директивы скрипта и стиля могут использоваться только в HTML-тегах <script> и <style>. Они управляют процессом обработки клиентского JavaScript и CSS на странице.  

  • is:global обеспечивает глобальное применение содержимого тега <style> на странице при включении компонента. Это приводит к отключению системы определения области видимости CSS Astro, которая задает диапазон действия правил CSS <style> для компонента. 
<style>
/* Scoped to this component only */ (/*Находится в области видимости только данного компонента*/)
h1 { color: red; }
</style>

<style is:global>
/* Scoped to the global level */ (/* Находится в глобальной области видимости */)
h1 { color: red; }
</style>

<style>
/* Scoped to this component only */ (/*Находится в области видимости только данного компонента*/)
h1 { color: red; }
/* Mixed: Applies to child h1 elements only */ (/* Смешанный вариант: Применяется только к дочерним элементам h1 */)
article :global(h1) {
color: blue;
}
</style>
<h1>Title</h1> <!-- red -->
<article><slot/></article> <!-- blue -->
  • is:inline указывает Astro оставить тег <script> и <style> в окончательном HTML-выводе так, как есть. В противном случае Astro будет обрабатывать, оптимизировать и связывать любые теги <script> и <style>, которые увидит на странице. is:inline ограничивает некоторые функциональности Astro, такие как импорт пакетов npm и использование языка компиляции в CSS, например SASS:
<style is:inline>
/* inline: relative & npm package imports are not supported. */
@import '/assets/some-public-styles.css';
span { color: green; }
console.log('I am inlined right here in the final output HTML.');
</style>
  • define:vars={...} может передавать переменные сервера из вступительной части компонента в клиентские теги <script> и <style>. Поддерживается любая JSON-сериализуемая переменная вступительной части, в том числе props, передаваемая через Astro.props. Значения сериализуются с помощью JSON.stringify():
---
const foregroundColor = 'yellow';
const backgroundColor = 'blue';
---

<style define:vars={{ textColor: foregroundColor, backgroundColor }}>
h1 {
background-color: var(--backgroundColor);
color: var(--textColor);
}
</style>
<h1>I am h1 text</h1>

Данный фрагмент кода отображает следующий текст: 

Расширенные директивы 

is:raw  —  это расширенная директива. Она предписывает компилятору Astro рассматривать любого потомка элемента как текст. 

---
const title = 'I am title';
---

<div>{title}</div> <!-- Output: I am title -->
<div is:raw>{title}</div> <!-- Output: {title} -->

Островная архитектура Astro

Островная архитектура была разработана фронтенд-архитектором Etsy Кэти Сейлор-Миллер в 2019 году, а в 2020 году создатель Preact Джейсон Миллер внес в нее дополнения.

Astro задействует островную архитектуру, которая стимулирует небольшие организованные зоны интерактивности на веб-страницах с серверным рендерингом. По умолчанию он отправляет клиенту чистый HTML и вставляет плейсхолдеры для интерактивных виджетов. На каждой странице есть островки интерактивности в море статичного контента. Astro до минимума сокращает время загрузки страницы и минимизирует работу, совершаемую на стороне клиента. Кроме того, при возникновении ошибок он применяет принцип “изящной деградации”. 

Astro по умолчанию генерирует каждый сайт без JavaScript на стороне клиента. Он задействует фронтенд UI-компоненты, созданные с помощью React, Preact, Svelte, Vue, SolidJS, AlpineJS, Lit и Astro. Такие компоненты автоматически выполняют предварительный рендеринг HTML и убирают весь JavaScript. Удаление со страницы нерабочего JavaScript по умолчанию ускоряет работу сайта. 

Заключение 

Astro  —  универсальный веб-фреймворк, разработанный для создания быстрых сайтов с большим количеством контента. К ним относятся большинство маркетинговых и издательских сайтов, сайты документации, блоги, портфолио и ряд сайтов электронной коммерции.

Astro использует рендеринг на стороне сервера и является фреймворком MPA. Он обеспечивает быструю начальную загрузку и короткий временной промежуток до интерактивности.

В чем-то Astro похож на фреймворк Qwik. Как мы уже знаем, Astro ориентирован на сайты, основанные на контенте. Поэтому он проще, чем Qwik, начиная со структуры каталога и заканчивая package.json.

Astro задействует островную архитектуру, как и фреймворк Fresh.

Сайты начинались с рендеринга на стороне сервера, затем популярность обрели SPA и рендеринг на стороне клиента. Теперь пора вернуться к MPA. Впереди нас ждет много интересного. 

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Jennifer Fu: Working With Astro — The Super Fast Web Framework

Предыдущая статьяРеализация цифрового конверта в iOS
Следующая статьяПрофессиональная обработка ошибок в TypeScript