The goal of this workflow is to couple vue-cli to Django, in a transparent way in dev and in prod. The hot-reload is active in the backend as well as in the frontend, and the frontend is accessed through Django, from the index page ;)
Note: We also use the router's historical mode, for a more professional integration.
Note²: Do not forget to build the vue-cli project for production!
python3 -m venv .venv
. .venv/bin/activate
pip install black flake8 pylint pydocstyle mypy # best linters/formatter
pip install django djangorestframework
pip freeze > requirments.txt
django-admin startproject back .
mkdir back/apps && touch back/apps/__init__.py
mkdir back/assets && touch back/assets/README.md # be sure to be tracked by git
(install vue-cli as global dependency)
vue create front # use vue-cli 3
cd front && touch vue.config.js # create the conf file
npm i -D clean-webpack-plugin vue-router@next # get the router
/*eslint-disable */
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
publicPath: "static/",
configureWebpack: {
devServer: {
writeToDisk: true, // used to link the webpack server to Django
},
plugins: [new CleanWebpackPlugin()],
},
};
NOTE: the following is based on this tutorial to implement vue-router to vue-cli 3.
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')
import { createWebHistory, createRouter } from "vue-router";
import Home from "@/views/Home.vue";
import About from "@/views/About.vue";
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/about",
name: "About",
component: About,
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
<template>
<div>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view />
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
<template>
<h1>Home Page</h1>
</template>
<template>
<h1>About Page</h1>
</template>
# ...
VUE_DIST = BASE_DIR / "front" / "dist"
ASSETS_DIR = BASE_DIR / "back" / "assets"
# ...
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [VUE_DIST], # get "index.html" in vue-cli dist
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
# ...
STATIC_URL = "/static/" # check the default value
STATICFILES_DIRS = [VUE_DIST, ASSETS_DIR] # link to the vue-cli dist folder
STATIC_ROOT = BASE_DIR / "staticfiles" # check the default value
# ...
# ...
from django.contrib import admin
from django.urls import path, include, re_path
from django.views.generic import TemplateView
urlpatterns = [
path("admin/", admin.site.urls),
# vuejs
re_path(r"^.*", TemplateView.as_view(template_name="index.html")),
]
the coupling is complete; you should be able to connect to the Django server, and access the VueJS application :)
yep thx I ll add it ;)