За последние несколько месяцев вы могли заметить множество коммитов, связанных с загрузкой файлов в ядре Discourse. Это было частью общих усилий по замене использования jQuery file upload в нашей кодовой базе, что, в свою очередь, является частью ещё более масштабной задачи по отказу от использования самого jQuery. jQuery file upload — очень старый проект, который присутствовал в ядре Discourse почти с самого начала. Я думаю, что использовал его на протяжении всей своей карьеры и в других проектах. Но пришло время отправить «Старого Надёжного» на покой:
Мы заменили jQuery file upload (а вскоре также заменим ещё одну библиотеку — resumable.js) на библиотеку под названием Uppy. Это гораздо более современная библиотека для загрузки, которая легко расширяется с помощью плагинов и способна обрабатывать все различные сценарии, которые мы ей предъявляем. Важно то, что это позволяет нам выполнять прямую многокомпонентную загрузку в S3 прямо с клиента Discourse, вместо того чтобы передавать большие файлы через наш API.
Композер теперь использует Uppy для всех загрузок, и во многих других местах приложения (загрузка аватара, загрузка фона профиля и т. д.) также применяется эта библиотека. Последние оставшиеся элементы будут удалены в ближайшие несколько недель. Для большинства пользователей это изменение должно остаться практически незаметным, но авторам плагинов и тематических компонентов потребуется внести некоторые изменения.
API плагинов
Препроцессоры
Все препроцессоры загрузки теперь должны быть написаны как плагины Uppy. Эти плагины довольно просты в написании и используют простой рабочий процесс на основе промисов. Препроцессор загрузки может изменить файл или добавить к нему метаданные перед тем, как Uppy загрузит его в S3 или в эндпоинт /uploads.json. В ядре уже есть несколько препроцессоров, которые вы можете использовать в качестве примера при написании собственных:
- discourse/app/assets/javascripts/discourse/app/lib/uppy-checksum-plugin.js at 6662101208089def86ed18a81ac90d1c52670569 · discourse/discourse · GitHub
- discourse/app/assets/javascripts/discourse/app/lib/uppy-media-optimization-plugin.js at 6662101208089def86ed18a81ac90d1c52670569 · discourse/discourse · GitHub
Препроцессоры загрузки для композера регистрируются через api.addComposerUploadPreProcessor с использованием API плагинов:
Обработчики загрузки
Обработчики загрузки не пишутся как плагины Uppy; они работают как и прежде, с незначительным изменением. Теперь, когда файл соответствует расширению, зарегистрированному для обработчика загрузки, все соответствующие файлы будут переданы сразу. Ранее в обработчик загрузки передавался только один файл за раз, а теперь передаётся массив:
Файлы, обработанные обработчиком загрузки, не будут дополнительно обрабатываться в конвейере загрузки Uppy. Препроцессоры выполняются до вызова обработчиков загрузки.
Прямая многокомпонентная загрузка в S3
Ранее я упоминал, что использование Uppy также позволяет нам выполнять прямую многокомпонентную загрузку в S3 прямо из интерфейса. Чтобы включить эту функцию, необходимо установить параметр сайта enable_direct_s3_uploads в значение true.
Если вы используете хостинг от нас, соответствующие права доступа S3 уже применены к вашему бакету. Однако, если вы размещаете систему самостоятельно, для работы этой функции необходимо настроить несколько прав доступа и правил CORS в вашем бакете.
Для настройки правил CORS достаточно выполнить задачу rake s3:ensure_cors_rules с помощью команды rake s3:ensure_cors_rules. Она добавит следующие правила в ваш бакет, при условии, что у вас включены права S3:GetBucketCors и S3:PutBucketCors для ключа доступа и секретного ключа, которые вы настроили для учётных данных S3 на вашем экземпляре Discourse.
{
"AllowedHeaders": [
"Authorization",
"Content-Disposition",
"Content-Type"
],
"AllowedMethods": [
"GET",
"HEAD",
"PUT"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"ETag"
],
"MaxAgeSeconds": 3000
}
Что касается прав доступа, вам необходимо включить следующие права для ключа доступа и секретного ключа, которые вы настроили для учётных данных S3 на вашем экземпляре Discourse.
{
"Sid": "YourSid",
"Effect": "Allow",
"Action": [
"s3:PutObjectVersionAcl",
"s3:PutObjectAcl",
"s3:PutObject",
"s3:GetObjectAcl",
"s3:GetObject",
"s3:DeleteObject",
"s3:CreateMultipartUpload",
"s3:CompleteMultipartUpload",
"s3:AbortMultipartUpload"
],
"Resource": [
"YOUR_RESOURCE"
]
}
Этот процесс занял несколько долгих месяцев, и мы ещё не закончили! Я опубликую сообщение в этой теме, когда мы окончательно удалим jQuery file upload и resumable.js из ядра Discourse. Если у вас есть вопросы по тому, что я написал здесь, дайте мне знать!

