Исходный код django svelte шаблона: https://github.com/ITmind/django-svelte-template
Иногда нужно сделать сайт, интерфейс которого реагирует так же, как интерфейс нативных приложений (т.е. страницы не подгружаются с сервера при различных действиях). Такие web-приложения называют Single Page Application (SPA).
Обеспечить хорошую отзывчивость пользовательского интерфейса можно только с помощью javascript или WebAssembly выполняемых на стороне клиента (в браузере). WebAssembly подходит для масштабных web-приложений и разрабатывать их я думаю нужно на Blazer. Остается javascript. Но писать всю логику UI на чистом javascript (vanila-js) для больших приложений долго, поэтому можно воспользоваться каким нибудь framework-ом. Из самих известных это React и Vue, они работают через Virtual DOM, имеют большое сообщество и много дополнительных библиотек. Но у этих framework есть минусы, и один из них это размер страницы. (а у React я считаю еще перегруженный синтаксис). Когда я делал разработки для embeded систем (arduino), то размер играл там очень важное значение и поэтому я искал другие библиотеки UI. Тогда я наткнулся на Svelte. Её суть в том, что написанный код “компилируется” в vanila-js и не используются никакие Virtual DOM, это обеспечивает отличную скорость работы и очень маленький размер страниц. Так же у Svelte отличный простой синтаксис и на нем очень просто писать. Плюс хорошая документация с примерами и REPL.
Для SPA нужен backend. Как миниму это БД и авторизация/аутентификация. В качестве БД можно использовать SaaS (типа YDB от Yandex.Cloud или аналогичные от AWS / Azure). В качестве middleware использовать Serverless Function (от тех же облачных провайдеров), а аутентификацию сделать через какой нибудь внешний сервис (тот же Google). Но для всего этого нужно изучать множество библиотек и писать много строк инфраструктурного кода, что затягивает сроки разработки. Поэтому хочется взять готовый framework который бы включал в себя все необходимое и одним из лучших таких framework-ов является Django
Но Django это классический SSR и для “отзывчивого” UI нужно писать на javascript в шаблонах Django. Следовательно нужно объединить Django и библиотеки SPA и в данной статье мы рассмотрим вариант SPA написанным с использованием Svelte.
Сначала создаем проект Django. Как это сделать не буду расписывать, т.к. такой информации полно. Например: для visual stuido code. В pychram есть готовые шаблоны проектов.
В папке с проектом Django выполняем:
$: npm create vite@latest myspa --template svelte
Если появится меню, выбираем там svelte и затем javascript. Теперь у нас есть два проекта, необходимо их запустить по отдельности и проверить что они рабочие.
Svelte через vite собирает проект с создает несколько файлов, главным из которых является один файл js (который и является SPA). Нам нужно настроить систему сборки vite и шаблон страницы Django таким образом, что бы максимально просто отобразить SPA.
Для начала настроим в Django директорию для статических файлов:
1. Создаем папку static
2. В settings.py добавляем: STATIC_ROOT = BASE_DIR / "static"
Далее в папке с проектом Svelte редактируем файл vite.config.js следующим образом:
import {defineConfig} from 'vite'
import {svelte} from '@sveltejs/vite-plugin-svelte'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [svelte()],
// параметр base определят директорию прямой ссылки на статические файлы (используется при разыменовывании относительных ссылок в скриптах)
base: "/static/spa",
build: {
//сюда будем выкладывать артефакты
outDir: "../static/spa",
//сюда картинки и прочее midia
assetsDir: './assets',
rollupOptions: {
output: {
//название главного файла javascript
entryFileNames: '[name].js',
//название остальных файлов. Если не прописать, то к имени будет дописывать случайный id
assetFileNames: '[name].[ext]',
},
},
}
})
Теперь при сборе проекта Svelte через “npm build” артефакты сборки будут копировать в папку static проекта Django
Далее создаем шаблон страницы Django следующего вида (все важное указано в комментариях):
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
{# относительный путь к иконке сайта #}
<link rel="icon" type="image/svg+xml" href="{% static 'spa/svelte.svg' %}"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Django + Svelte</title>
{# относительный путь к главному js файлу, содержащему SPA #}
<script type="module" crossorigin src={% static 'spa/index.js' %}></script>
{# относительный путь к стилям SPA #}
<link rel="stylesheet" href={% static 'spa/index.css' %}>
</head>
<body>
{# тег crsf token нужен для того, что бы токен передался в заголовке. Токен нужн для POST запросов из SPA #}
{% csrf_token %}
{# в данном теге отобазиться Svelte #}
<div id="app"></div>
</body>
</html>
В файле views.py добавляем функцию отображения шаблона:
@never_cache
@csrf_protect
def spa(request):
return render(request, 'spa.html')
Отключаем кэш, т.к. иначе во время отладки js будет браться из кэша браузера
В файле urls.py прописываем маршрут к нашему шаблону:
from django.contrib import admin
from django.urls import path
from spa import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.spa),
]
Соберем svelte app и затем запустим django. Это проще всего делать настроив соответствующие конфигурации в IDE. Для PyCharm конфигурации выглядят так:
В браузере должно открыться наше SPA приложение с кнопкой счетчиком (штатный шаблон vite-svelte)