dosya97
@dosya97
Fullstack web-developer

Как правильно организовать структуру SPA + Backend?

Приветствую, возник вопрос по поводу красивой и безболезненной разработке. Для frontend-a использую VueJS, а для backend-a Django. Обычно делаю так:
1) Ставлю django
2) Создаю static/js
3) Прикручиваю webpack2 вручную и все остальные зависимости(Тяжко)
4) Генерируется единый bundle.js, который я могу вызвать в пустом шаблоне django(index.html)
Все прекрасно, но хочется использовать vue-cli. Уж больно он удобный и шаблон там замечательный. Но бесит, что там нет единого собранного файла bundle.js, так он еще создает кучи других непонятных файлов, и при режиме разработки запускает ненужный 'hot-load'. Получилось все это призвать в django, но выглядит это конечно убого.

Вот у меня есть два варианта разработки:
1) Как описано выше, вызывать эти файлы в django templates
2) Оставить в покое django под портом :8000, а VueJS под :8080. И в nginx как-то слушать их обоих, раздельно, таким образом четко разделить фронт от бэка. Не будет ли проблем?
Какой вариант лучше? Если второй, то какие конфиги примерно нужно писать? И при обращении через websockets и ajax как учесть порт? Спасибо.
  • Вопрос задан
  • 4471 просмотр
Решения вопроса 2
@wearemieta
BEWARE HIPSTERS
Но бесит, что там нет единого собранного файла bundle.js

В шаблоне webpack-simple все скрипты собираются как раз в один файл build.js. Обратите внимание, он подключается в сгенерированный index.html. vuejs-templates/webpack-simple.

Этот файл недоступен в файловой системе при запуске dev сервера, потому что в режиме разработки он находится исключительно в памяти.

так он еще создает кучи других непонятных файлов и при режиме разработки запускает ненужный 'hot-load'.


Давайте разберемся, для чего нужен сервер в режиме разработки для Vue. При написания SPA приложения вы используете кучу библиотек, файлов в разных форматах и возможно еще обращаетесь к стороннему API(например twitter). Плюсом, вам хотелось бы использовать транспайлер, чтобы в js можно было красиво писать стрелочные функции и использовать другие вкусняшки ES2015. А еще это здорово было бы склеивать файлы одного формата в один большой для разных оптимизаций. Плюс, после того как вы измените что-то в одном файле, не пришлось бы тыкать каждый раз на перезагрузку страницы. Примерно эти вещи делает за вас dev сервер с webpack в режиме разработки.

— с помощью webpack вы можете собирать ваши файлы каким угодно образом и складывать их в любое удобное место в фс.
— вы можете их склеивать, минифицировать и использовать транспайлеры, препроцессоры, постпроцессоры и прочее.
— вы можете обращаться к стороннему API с локалхоста.
— если вам не нужен hot-load — отключите его в конфиге.

Оставить в покое django под портом :8000, а VueJS под :8080. И в nginx как-то слушать их обоих, раздельно, таким образом четко разделить фронт от бэка. Не будет ли проблем?


Проблем с проксированием nginx'ом? Не очень понятно что вы имеете в виду.

Если вам нужен кастомный шаблон vue-cli то вы можете легко его разработать один раз и в дальнейшем использовать: Vue-cli custom templates

Как правильно организовать структуру SPA + Backend

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

Дело в том, что возникновение таких вещей типа SPA напрямую связано с разными парадигмами разработки. Django как фреймворк позволяет вам писать монолитные приложения. Вы пишете одно большое приложение где храните бизнес-логику, фронтенд, функции-хелперы вроде уменьшения размера загруженных картинок, etc. Деплоите монолитное приложение на одном сервере, возможно на отдельный сервер выносите базу данных.

Эта парадигма оправдана в определенных случаях, как и другие парадигмы.

В случае микросервисной парадигмы вы делите ваше приложение на много микро-сервисов. Давайте придумаем кейс, который может возникнуть в реальной жизни.

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

Ваше приложение схематически выглядит так:

Клиент: хочу авторизоваться => Сервер приложения: отправлю бизнес-логике => Бизнес-логика: спросим базу (данные для авторизации) => База данных: можно => Клиент: я авторизован

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

Теперь, в вашем фронтенде на Vue, например, вы можете отображать нужные вам данные (а соотв. делать запросы в основную базу), только если пользователь авторизован.

Теперь ваше приложение выглядит так:

Клиент: хочу авторизоваться => Фронтенд-микросервис: отправляю микросервису авторизации => Микросервис авторизации: можно => Фронтенд-микросервис: я авторизован, хочу данные => Сервер приложения: отправлю бизнес-логике => Бизнес-логика: спросим базу (данные отображения авторизованному клиенту) => База данных: данные => Клиент: я получил данные

Давайте теперь представим, что вам нужно быстро, а лучше сегодня набросать MVP для демонстрации инвестору или для проверки вашей концепции.

Авторизация? — микросервис — auth0.com
SQL База данных? — микросервис — Google CLOUD SQL
Уменьшаем размер картинок? — микросервис — AWS Lambda

Что получается в сухом остатке? Вам требуется лишь написать SPA из которого вы будете обращаться к вашим микросервисам. То есть, вы получаете приложение, которое можно хостить как статический сайт, переложив на микросервисы большинство задач, которые вам требуются в вашем приложении.

Конечно, это решает определенные проблемы, но и создает новые, поэтому, повторюсь, все зависит от ваших задач.

Давайте посмотрим на ваш пример с Django. Если я все правильно понимаю, то вы хотите использовать все плюсы Django, типа ORM, API доступа к БД, etc, заменив лишь систему шаблонов на Vue?

В таком случае, на мой взгляд, вам нужно реализовать на Django классический REST API и из SPA на Vue обращаться к endpoint'ам вашего API.

Ссылки по теме:
Архитектура микросервисов
SPA-архитектура для CRM-систем: часть 1
SPA-архитектура для CRM-систем: часть 2
AWS Lambda и никаких серверов
Ответ написан
Комментировать
kulakoff
@kulakoff
Vue.js developing
Сейчас похожий проект:

бэк - django-rest-framework,
фронт - vue spa, используется vue-cli и webpack шаблон.

django стартует сервер на своем порту, vue использует dev сервер из шаблона. Взаимодействие через rest. Т.е. по сути описанный вами 2ой вариант. В папке проекта две папки: backend и frontend.

Еще делали такую штуку(правда не пользуемся ей для разработки): стартует django сервер, в нем настроены пути, так что если это не обращение к api сервера или к админке, то он отдает статику из папки frontend/dist, т.е. продакшн версию фронта.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@nemoisfree
Просто в вебпак конфиге можете настроить редирект, если на дев сервер запрос будет в /api/, то тогда стучаться на порт 3000.
config.devServer = {
        proxy: [{
            path: '/api/',
            target: 'http://localhost:3000'
        }],
            contentBase: './public',
            hot: true,
            inline: true,
            historyApiFallback: {
            index: 'index.html'
        }
    };


Более популярен react.js stateofjs.com/2016/frontend
во vue.js захотите найти готовый модуль, могут возникнуть проблемы.
Ответ написан
Fragster
@Fragster
помогло? отметь решением!
юзаю по второму варианту, причем бэкэнд сделал отдельным проектом с выносом на отдельный сервер.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы