В процессе работы в качестве разработчика UI/UX я ощущал развитие множества современных веб-технологий. React, Vue.js и такие современные CSS-раскладчики, как Flexbox и Grid значительно упростили задачу компоновки экрана по сравнению с прошлым. Однако одно место, область ‘шаблона электронной почты’, стало исключением.
В этом проекте 'Блокнот класса' мне была поручена работа по разметке и компонентам трех видов электронной почты (восстановление идентификатора, сброс пароля, предоставление кода подтверждения), которые будут отправлены пользователям.
Я ожидал, что смогу создавать интерфейс так же удобно, как обычно, но мир шаблонов электронной почты находится под влиянием правил, которые совершенно отличаются от обычной современной веб-фронтенд экосистемы, как будто мы вернулись в прошлое.
В этой статье я проанализирую особенности и ограничения среды рендеринга электронной почты и расскажу о своем практическом опыте преодоления этих проблем с помощью библиотеки React Email и о том, как я успешно сотрудничал с командой бэкенда в окружении моно-репозитория.
Дилемма рендеринга электронной почты: почему мы все еще должны использовать <table>?
Веб-браузеры (Chrome, Safari и др.) следуют общим правилам, известным как 'веб-стандарты', однако почтовые клиенты читают HTML по-разному. Конкретные причины, по которым нельзя разрабатывать шаблоны электронной почты как обычные веб-страницы с помощью <div>, следующие.
Во-первых. Ограничения движка рендеринга Microsoft Outlook
Outlook, наиболее широко используемый в корпоративной среде, начиная с версии 2007 года, стал использовать движок рендеринга документов MS Word, а не движок веб-браузера. Поскольку Word — это редактор документов, а не веб-браузер, он не понимает современные CSS-раскладки, такие как margin, padding, float, flex, и полностью разрушает экран.
Единственный способ предотвратить проблемы с разрывом слоев в Outlook — это использовать старую структуру <table> в качестве каркаса.
Во-вторых. Политика фильтрации безопасности и стилей веб-почтовых сервисов
Сервисы веб-почты, такие как Gmail или Naver Mail, позволяют пользователям проверять почту в веб-браузере.
Если в тексте электронного письма содержится код, подобный <style> body{background : black; }<style>, существует риск того, что фон всего веб-сайта Naver Mail станет черным. Чтобы избежать таких конфликтов стилей и проблем с безопасностью, основные веб-серверы электронной почты произвольно удаляют теги <style> или внешние <link> CSS из кода.
В конечном итоге, чтобы гарантировать, что дизайн будет одинаково выглядеть во всех средах, от последних смартфонов до старого Outlook, вам пришлось использовать способ встраивания стилей (Inline-style), разделяя всю область на <table width=”100%”> теги и внедряя все стили в <td style=”...”>.
Введение спасателя ‘React Email’ и отладка настройки окружения
Хардкодинг чистого HTML и тегов <table> с встраиванием стилей по одному элементу стал худшим опытом с точки зрения разработки и обслуживания. При каждом изменении текста или отступа приходилось отслеживать наложенные теги <tr>,<td>. Чтобы решить эту проблему, мы решили внедрить библиотеку React Email, которая безопасно извлекает HTML для электронной почты, сохраняя при этом существующую экосистему React.
В настоящее время проект построен на окружении моно-репозитория (Monorepo) на базе pnpm. В начале внедрения, когда я выполнил команду для запуска локального сервера предварительного просмотра, я столкнулся с неожиданной ошибкой.
> pnpm -F @vizendjs/episode-banjang email sh: react-email: command not found ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL
-
Я думал, что достаточно установить его в корневом каталоге, однако из-за особенностей моно-репозитория скрипты выполняются внутри определенного пакета (@vizendjs/episode-banjang), что и стало причиной поломки ссылок на выполнение. Чтобы это исправить, я указал соответствующее рабочее пространство и установил библиотеку вручную (pnpm -F @vizendjs/episode-banjang add -D react-email), а затем повторно выполнил pnpm install в корневом каталоге, восстановив ссылки на зависимости, и успешно настроил локальное окружение панели управления.
Начало разработки шаблонов и ключевая отладка
Я запустил локальную панель управления (localhost:3000) и продолжил разработку, рендеря компоненты в реальном времени. В процессе я столкнулся с двумя крупными техническими преградами и их решениями.
1. Отсутствие медиазапросов для мобильной адаптивности (Fluid Table)
В обычной веб-верстке медиазапросы @media используются для переключения на мобильный вид, но, как уже упоминалось, в среде электронной почты медиазапросы часто игнорируются. Поэтому вместо того, чтобы отдельно обрабатывать код для мобильных устройств, мы использовали подход 'гибкой таблицы (Fluid Table)', комбинируя максимальную ширину (max-width) и ширину 100%, чтобы она автоматически сжималась при сужении экрана.
Мы присвоили компоненту <Container>, предоставляемому React Email, стили maxWidth: '600px', width: '100%', margin: '0 auto', чтобы на ПК ширина была зафиксирована на 600px для лучшей читаемости, а на мобильных устройствах с шириной менее 600px — адаптировалась на 100% к экрану.
2. Проблема с рендерингом изображений: роковая ловушка Base64
Обработка путей для логотипа и иллюстраций '반장노트', включаемых в электронное письмо, была самым болезненным вопросом для меня.
Сначала я работал с локальным тестовым путем (http://localhost:3000/images/...), но при отправке настоящего письма пользователь не имеет доступа к этой локальной среде, и изображение отображается как сломанное. Не дожидаясь настройки сервера, я решил попытаться решить эту проблему, преобразовав изображение в чрезвычайно длинную строку.Base64 Мы рассмотрели способ внедрения HTML непосредственно в код. Однако результаты исследования показали, что у этого метода есть два серьезных недостатка в условиях электронной почты.
Обрезка содержания письма (превышение объема)
В случае с Gmail, если объем HTML-кода превышает 102 КБ, нижняя часть письма автоматически обрезается, и отображается ссылка «Показать полностью». При использовании Base64 код значительно увеличивается, и 100% случаев повреждения всего шаблона письма.
Фильтрация безопасности (иконки не отображаются)
В основных веб-почтовых сервисах, таких как Outlook, изображения, вставленные с помощью Base64, блокируются для предотвращения спама и вредоносного ПО.
Таким образом, изображения в шаблонах электронной почты должныбыть обязательно загружены на внешний сервер (CDN, S3 и т.д.) с использованием публичного абсолютного пути (URL).Поскольку на тот момент путь загрузки изображений на бэкенде еще не был определен, мы сначала связали его с локальным путем в коде и зафиксировали макет, после чего перешли к следующему этапу – сотрудничеству с бэкендом.
Управление инлайн-стилями в форме объектов для повышения читаемости
Одной из самых больших проблем шаблона электронной почты является необходимость помещать все CSS прямо внутри тегов в виде 'инлайн-стилей'. В условиях полного HTML, например, <td style="font-size: 16px; color: #000; line-height: 1.6; ..."> длина стилей внутри одного тега значительно ухудшает читаемость кода.
В этой задаче мы использовали преимущества React, чтобы решить эту проблему, используя объекты JavaScript. Сложные свойства стиля были вынесены из разметки и управляются как отдельный константный объект внизу файла.
// 1. Область разметки должна оставаться аккуратной, чтобы можно было четко понять структуру
<Text style={codeText}> {verificationCode} </Text>
<Text style={footerText}> Этот код истечет через 30 минут.<br />Спасибо. </Text>
// 2. Отдельное управление стилевыми объектами внизу файла
const codeText = {
fontSize: '40px',
fontWeight: 'bold',
color: '#5C5CFF',
letterSpacing: '2px',
marginBottom: '40px',
};
const footerText = {
fontSize: '16px',
color: '#000000',
lineHeight: '1.6',
};
-
Таким образом, физически отделив область разметки от области определения стилей, читать код и понимать его структуру стало намного проще. В будущем, когда нужно будет изменить размер шрифта или цвет, не нужно больше блуждать в сложных джунглях тегов, достаточно найти объект стилей внизу и изменить значение, что значительно улучшило опыт разработчика (DX) и удобство обслуживания по сравнению с традиционным способом жесткой кодировки HTML.
Процесс сотрудничества для извлечения выходных данных и интеграции с бэкендом (сервером)
Компонент React (.tsx), написанный на фронтенд-части, не может работать на почтовом сервере сам по себе, поэтому его необходимо было извлечь (экспортировать) в чистый HTML и передать бэкенд-разработчику.
После извлечения .html файлов, преобразованных с помощью скрипта email:export, настроенного в package.json, я подробно написал в Notion 'Результаты разметки шаблонов писем и руководство по интеграции', чтобы эффективно взаимодействовать с бэкенд-разработчиком. Это было необходимо не просто для передачи файлов, но и для предварительной блокировки возможных ошибок при интеграции с сервером.
Основные моменты руководства для сотрудничества
Предварительно определенный формат замещения динамических данных (переменных):Для упрощения связывания информации о пользователе в бэкенд-шаблонизаторе, мы регулярно вставляли форматы временных переменных внутрь HTML. (Например: имя пользователя {{userName}}, 6-значный код подтверждения {{verificationCode}} и т. д.)
Рекомендации и инструкции по обработке неопределённого пути изображения:Внутренним мессенджером и в руководящем документе было ясно указано: "Изготовление изображения завершено, но абсолютный путь ещё не настроен, поэтому для сохранения макета мы временно установили только область. После завершения настройки сервера, пожалуйста, замените атрибут src на настоящий URL сервера."
Благодаря такому проактивному обмену, специалисты по бэкенду не растерялись и тут же смогли без задержек продолжить свою интеграционную работу (тестирование SMTP и т.д.), сказав: *"Позже просто заменим URL изображения"*.
Ценность документации и совместной работы, преодолевающей технические ограничения
Работа над шаблоном электронной почты для заметок классного руководителя была очень сложной задачей, требующей одновременного учета ограничений устаревших веб-стандартов и фрагментированной клиентской среды. Однако, отказавшись от привычного способа ручного хардкода, которому я следовал на протяжении 8 лет, и смело внедрив современный стек технологий React Email, я смог избавиться от страданий, связанных с техническим обслуживанием, и успешно внедрить преимущества фронтенд-разработки в практику.
Самым важным моментом стало то, что это не просто написание кода и создание красивого интерфейса. Я логически выводил технические альтернативы, такие как отказ от Base64 и построение Fluid Table, и подготовил руководящие документы, чтобы бэкендеры могли продолжать работать без затруднений даже в ситуации с незавершенной инфраструктурой (отсутствие путей к изображению).
Этот опыт показал, что для разработчика 'технические навыки' - это не просто умение работать с новейшими библиотеками, а Способность точно оценивать заданные ограничения и обеспечивать плавное сотрудничество с другими отделами через коммуникацию и документациюЯ еще раз глубоко осознал(а) это. В будущем я продолжу развиваться как издатель, который не довольствуется привычными способами и активно размышляет о том, как повысить производительность всей организации и качество кода.
sangsooni