Symfony: лучший способ быстрого запуска проектов

Источник: «A better way to quickly start Symfony projects»
При создании новых проектов Symfony вы можете начать с bare-bones skeleton или kitchen sink skeleton. Я никогда не использовал kitchen sink skeleton, так как предпочитаю начинать с минимального количества зависимостей и добавлять пакеты только тогда, когда они мне нужны. Symfony делает это безболезненным, так как в большинстве случаев сообщает, какой пакет добавить, когда вы пытаетесь использовать что-то, что ещё не входит в ваш набор зависимостей.

При использовании Symfony CLI для создания нового проекта по умолчанию используется маленький skeleton (который, так же рекомендуется в Symfony book). Этот скелет по умолчанию также является безопасной отправной точкой, поскольку содержит только Symfony пакеты и не содержит сторонних пакетов:

{
"symfony/console": "*",
"symfony/dotenv": "*",
"symfony/framework-bundle": "*",
"symfony/runtime": "*",
"symfony/yaml": "*"
}

У этих зависимостей есть некоторые транзитивные зависимости, но опять же, только безопасные. Если вы сегодня запустите symfony new test-project, composer show выведет список из 31 пакета: 4 пакета PSR4, 4 пакета контрактов Symfony, 4 пакета Symfony polyfill и 19 обычных пакетов Symfony. В нём до сих пор нет сторонних пакетов.

Но для подавляющего большинства новых веб-проектов Symfony создаваемых ежедневно, можем предположить, что им потребуются инструменты отладки, такие как веб-профилировщик, какой-нибудь пакет ведения логов, способ отправки электронной почты, и возможно, шаблонизатор.

Вот где пригодится website-skeleton. Этот скелет содержит гораздо больше пакетов, в том числе некоторые, которые вам могут никогда не понадобится. Всего в него входя 128 пакетов (кстати, неплохое число), включая множество сторонних пакетов, которые напрямую зависят от Symfony пакета, либо от глубокой зависимости от другой зависимости.

Этот скелет был создан для замены пакета symfony/symfony, который больше никто не должен использовать. Как ни странно, он включает не всё. Список включённых пакетов был определён давно и некоторые очень полезные пакеты, большинство из которых были созданы после этого, до сих пор не включены. Хотя мы добавили компоненты Mailer или Notifier когда они стали доступны, компонент Messenger по некоторым причинам так и не был добавлен (вероятно потому, что использование этого скелета нигде не рекомендовалось).

Несколько месяцев назад обсуждалось добавление компонента Messenger в список зависимостей website-skeleton. Но вместо этого решили заменить скелет паком. Пак — это мета пакет Composer: он не предоставляет никаких полезных функций, а только зависимости.

Познакомьтесь с паком Webapp

Какие преимущества? Основное преимущество заключается в том, что пакет представляет собой обычный пакет Composer, который можно использовать в любом существующем проекте (даже на ранних стадиях разработки). Это позволяет собрать ваше приложение, используя более одного пакета. Что касается кода — композиция пакетов почти всегда лучше наследования. website skeleton основан на наследовании: с философской точки зрения он расширяет базовый скелет. Вам нужно использовать или то или другое. Webapp же может быть включён в любой набор зависимостей, независимо от скелета, который использовался для создания проекта.

Думайте о паке, как об эквиваленте PHP трейтов. С июня 2020 пакеты стали даже лучше, чем PHP трейты, поскольку Flex автоматически распаковывает зависимости для вас, возвращая вам управление. Таким образом, вместо того, чтобы зависеть от webapp пака, ваш composer.json содержит все зависимости перечисленные в паке. Это позволяет удалить не нужные вам зависимости.

Паки Symfony не новы: они были представлены одновременно с Symfony Flex. В настоящее время у нас 12 официальных паков: ORM пак, пак отладки, тестовые пак, и некоторые другие.

Пак webapp — это ещё один пак, который можно использовать при создании традиционного веб-приложения. Он включает в себя некоторые другие паки. Опять же, всё дело в композиции.

Поскольку webapp пак прекрасно заменяет website-skeleton, последний устарел. Это даже лучше: нам всегда нужен только один скелет, базовый. Тот, у которого минимальный набор зависимостей полезных для любого проекта Symfony. Кроме того, смешиваете любой количество паков.

Как вы понимаете, компонент Messenger является частью webapp пака.

Для создания нового проекта с webapp паком, используйте:

symfony new --webapp dirname/

Что с точки зрения Composer, более и менее эквивалентно выполнению следующих команд:

composer create-project symfony/skeleton dirname/
cd dirname
composer require webapp

Но это только половина истории.

Рецепт Webapp

Как вы знаете, Symfony Flex ввёл понятие рецептов, связанных с пакетами Composer. Рецепт — это описание того, как создать разумную конфигурацию по умолчанию для любого пакета Composer (он может создавать файлы, изменять некоторые другие, добавлять переменные среды, задавать некоторые службы Docker и т.д.). Всякий раз, когда вы добавляете пакет в свой проект, если существует связанные рецепт, он будет использоваться для автоматической настройки пакета в вашем проекте.

Поскольку метапакеты являются обычными пакетами Composer, они так же могут иметь связанные рецепты. И в webapp паке есть небольшой рецепт. Он не так много, но в сочетании с другими рецептами меняет правила игры.

Во-первых, он определяет Doctrine как транспорт Messenger по умолчанию:

{
"env": {
"MESSENGER_TRANSPORT_DSN": "doctrine://default?auto_setup=0"
}
}

Doctrine и Messenger часть webapp пака, поэтому имеет смысл использовать Doctrine в качестве транспорта для сообщений по умолчанию. Более того, поскольку рецепт Doctrine использует PostgreSQL по умолчанию, мы так же можем соответствующим образом настроить конфигурацию Messenger.

Конфигурация Messenger, которая поставляется с рецептом, учитывает всё это и делает ещё один шаг вперёд, отправляя электронные письма асинхронно по умолчанию:

framework:
messenger:
failure_transport: failed

transports:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
options:
use_notify: true
check_delayed_interval: 60000
retry_strategy:
max_retries: 3
multiplier: 2
failed: 'doctrine://default?queue_name=failed'
# sync: 'sync://'

routing:
Symfony\Component\Mailer\Messenger\SendEmailMessage: async
Symfony\Component\Notifier\Message\ChatMessage: async
Symfony\Component\Notifier\Message\SmsMessage: async

# Route your messages to the transports
# 'App\Message\YourMessage': async

Почему это так важно? Как однажды сказал мне один из членов команды в Slack Проведите тренинг и попросите участников создать новый Symfony веб-сайт с формой, валидацией и Doctrine. Возможно, вам придёт подождать около часа, прежде чем увидите 200. ok, он тогда был зол :) Но всё равно. В этой истории есть что-то правдивое. Это не потому, что разработчики глупы, а потому, что Symfony может быть слишком сложным, или слишком абстрактным, или недостаточно последовательным, когда вы начинаете с базового скелета.

Использование webapp пака позволяет нам автоматически последовательно всё настраивать, не прося разработчика сделать выбор. Это несколько опционально, но этого достаточно, что бы мы могли помочь вам в настройке и подключении всего вместе.

Что бы лучше понять наш опциональный выбор, который мы сделали, вот основные из них:

Эти опциональные варианты не связаны с webapp паком, поскольку они привязаны с конкретным пакетам, но при использовании webapp пака вы подключаете их все. Кроме того, он открывает возможность создания оптимизированной конфигурации Messenger для PostgreSQL.

Подводя итог, при создании нового Symfony проекта, в котором вы знаете, что будет использовать Doctrine, Messenger, Mailer, Notifier или любую более продвинутую возможность, новый webapp пак поможет вам быстрее начать работу с отличной конфигураций по умолчанию. Symfony Flex сделает это безболезненным.

Наслаждайтесь!

Дополнительные материалы

Предыдущая Статья

Laravel: подключение Tailwind CSS 3

Следующая Статья

Tailwind CSS v3.0: 10 лучших новых возможностей