Awesome
We stand with Palestine against the ongoing genocide and brutal occupation.
Django Vite Plugin
Introduction
Vite is a modern frontend build tool that provides an extremely fast development environment and bundles your code for production.
This plugin configures Vite for use with Django backend.
Installation
# Install django app
pip install django_vite_plugin
# Install vite plugin
npm install django-vite-plugin
Feature Highlights
1. Simple And elegant
2. Static file lookup
3. Auto Reload
4. JS Import helpers
5. Js import autocompletions
6. Test for production
Usage
Django
In your project's settings.py
file, add django_vite_plugin
in installed apps list
# Some settings
INSTALLED_APPS = [
# Some apps
'django_vite_plugin',
# Other apps
]
Now use the following code in your template files to load the assets
{% vite '<app_name>/<path>/<to>/<css>/styles.css' %}
If you want to output any additional attributes in your html, do this:
{% vite '---.css' '--.js' crossorigin='anonymus' integrity='some-sha'%}
This will output:
<link rel="stylesheet" type="text/css" crossorigin="anonymus" integrity="some-sha" href="---.css"/>
<script src="---.js" type="module" crossorigin="anonymus" integrity="some-sha"></script>
Notice how <script> tag automatically includes type="module" attribute. You can change this behaviour from settings
Let's say you have two files your home
app
└-- home
└-- static
└-- home
|-- css
| └-- styles.css
|
└-- js
└-- main.js
To include these files your Template file would look like:
{% load vite %}
<!DOCTYPE html>
<html lang="en">
<head>
<!--Other elements-->
<!--Vite dev client for hmr (will not be displayed on production)-->
{% vite %}
{% vite 'home/css/styles.css' 'home/js/main.js' %}
</head>
<body>
<!--Page content-->
</body>
</html>
Notice instead of using
home/static/home/*/*
, we have usedhome/*/*
. By defaultdjango_vite_plugin
addsstatic/<app_name>
after first segment of the path. This behaviour can be changed from settings
Vite
In your vite.config.js
file add django-vite-plugin
//vite.config.js
import { defineConfig } from 'vite'
import { djangoVitePlugin } from 'django-vite-plugin'
export default defineConfig({
plugins: [
djangoVitePlugin([
'home/js/app.js',
'home/css/style.css',
])
],
});
Here, the argument is string
or array of string
that will be passed to build.rollupOptions.input
.
Note: Automatic addition of
static/<app_name>
is also applied here
All of the entry points (used as
{% vite '...' '...' %}
) should be added here
Then run the following commands in two separate terminal
# Start the django development server
python manage.py runserver
# Start the vite dev server
npm run dev
And to build the assets for production, run
npm run build
Configuration
django_vite_plugin
requires zero configuartion
to develop or build your project. However, there are things you can customize
All the customizations are to be done in your settings.py
file
The default configurations are:
DJANGO_VITE_PLUGIN = {
'WS_CLIENT': '@vite/client',
'DEV_MODE': getattr(settings, 'DEBUG', True),
'BUILD_DIR': getattr(settings, 'STATIC_ROOT') or 'static',
'MANIFEST': '<BUILD_DIR>/.vite/manifest.json',
'BUILD_URL_PREFIX': getattr(settings, 'STATIC_URL'),
'JS_ATTRS': {
'type': 'module'
},
# 'JS_ATTRS_BUILD': Not present,
'CSS_ATTRS': {
'rel': 'stylesheet',
'type': 'text/css'
},
'STATIC_LOOKUP': True
}
-
WS_CLIENT
: This is the vite client script relative to the dev server url. In most of the case you don't need to change this option.(default:@vite/client
) -
DEV_MODE
: If setTrue
, vite dev server will be used to link assets, otherwise build files. (default:settings.DEBUG
) -
BUILD_DIR
: The directory where vite should output the build assets. If you serve the assets from a different server (i.e. cdn), keep the directory structure as is.(default:settings.STATIC_ROOT
or'static'
) -
MANIFEST
: The path of themanifest.json
file. The default is<BUILD_DIR>/.vite/manifest.json
as perVite v5
. Even if you serve the assets from a different server, the manifest must stay in the specified location. -
BUILD_URL_PREFIX
: The url prefix for production. IfDEV_MODE
isFalse
then all the assets from<BUILD_DIR>/manifest.json
would be prefixed with this value. If you serve the production build from a separate server, provide the server address here. (default:settings.STATIC_URL
) -
STATIC_LOOKUP
: Whether to addstatic/<app_name>
after first segment of assets.<app_name>/file
will become<app_name>/static/<app_name>/file
(default:True
) -
JS_ATTRS
: Default attributes to output in all<script>
tags (default:{'type': 'module'}
) -
JS_ATTRS_BUILD
: If you want your javascript attributes for production files to be different (i.e. adddefer
ortype='text/javascript'
) then add these attributes here as:DJANGO_VITE_PLUGIN = { ... 'JS_ATTRS_BUILD': { 'type': 'text/javascript', 'defer': True }, ... }
-
CSS_ATTRS
: Default attributes to output in allstylesheet
tags. Default:{ 'rel': 'stylesheet', 'type': 'text/css' }
Javascript
The available js configuration options are:
{
input: string | string[],
root?: string,
addAliases?: boolean,
pyPath?: string,
pyArgs?: string[],
reloader?: boolean | (file: string) => boolean,
watch?: string[],
delay?: number,
}
-
input
: The js/css entry points. All of the used js/css files as{% vite '...' '...' %}
should be added here -
root
: The relative path from yourvite.config.js
to your project's root directory. If they are the same (which is recommended) skip it. -
addAliases
: Whether to add the@s:<app>
&@t:<app>
aliases in thejsconfig.json
file. If settrue
then will create ajsconfig.json
if not exists. Default is it will add aliases ifjsconfig.json
file exists -
pyPath
: The path to your python executable. (Default:python
) -
pyArgs
: Any additional arguments to pass inmanage.py
commands -
reloader
: Whether to reload browser on html & py file changes. You may pass a function to reload after checking which file has changed. By default it checks for html & py extensions. -
watch
: A list of additional files to watch for browser reload. By default it smartly detects the python files in your installed apps and triggers the browser reload. -
delay
: Delay to reload after file change in milliseconds.
Let's assume your vite.config.js
file is in frontend
directory
|-- home
| └-- static
| └-- home
| |-- css
| | └-- styles.css
| |
| └-- js
| └-- main.js
└-- frontend
└-- vite.config.js
In this case your vite.config.js
should look like this:
//vite.config.js
import { defineConfig } from 'vite'
import { djangoVitePlugin } from 'django-vite-plugin'
export default defineConfig({
plugins: [
djangoVitePlugin({
input: [
// Your inputs
],
root: '..' // the parent directory
})
],
});
Features
1. Simple And elegant
You don't need a whole different set of setup to start using vite. All you need to do is install the packages and add them. And you are ready to go.
2. Static file lookup
As per Django's recommendation, static
files and templates
should be inside app_name/static/app_name
and app_name/templates/app_name
.
When STATIC_LOOKUP
is enabled in settings, static/app_name
can be skipped from the import paths.
So, instead of writing
{% vite 'app_name/static/app_name/path/to/asset' %}
You can write
{% vite 'app_name/path/to/asset' %}
The behaviours of this setting are:
vite argument | Include asset path |
---|---|
app_name/script.js | app_name/static/app_name/script.js |
app_name/static/script.js | app_name/static/script.js |
static/script.js | static/script.js |
To disable this behaviour set {
STATIC_LOOKUP
:False
}
Note: This uses Django's built-in staticfinder under the hood
3. Auto Reload
This plugin reloads your browser window whenever a relavent file is changed!
4. JS Import helpers
Just like STATIC_LOOKUP, helpers are available in js too. It uses vite's alias under the hood.
The default aliases are:
Alias | Points to |
---|---|
@ | <root of the project> |
@s:<app_name> | <app_path>/static/<app_name> |
@t:<app_name> | <app_path>/templates/<app_name> |
Why alias for
templates
? Do you keep your*.vue
files instatic
directory?
import whatevs from '@/path/to/whatever'
// Output: import whatevs from '<project_root>/path/to/whatever'
import customAlert from '@s:ui/components/alert'
// Output: import customAlert from '<path_to_ui_app>/static/ui/components/alert'
import vueCounter from '@t:ui/vue/counter.vue'
// Output: import vueCounter from '<path_to_ui_app>/templates/ui/vue/counter.vue'
Setting { STATIC_LOOKUP
: False
} will result in
Alias | Points to |
---|---|
@ | <root of the project> |
@s:<app_name> | <app_path>/static |
@t:<app_name> | <app_path>/templates |
5. Js import autocompletions
You can get autocompletions for these import aliases in the IDEs that support jsconfig.json
To enable this feature, add a jsconfig.json
file in your projects root directory or in the same directory as vite.config.js
Note: If you are using typescript then it will automatically add the paths there while running dev command
6. Test for production
Do this to test if your build files works as expected before shipping it to the production
-
In your projects urls.py add
urlpatterns = [ # some urls path('', include('django_vite_plugin.urls')), # other urls ]
-
In
settings.py
set... STATICFILES_DIRS = [ BASE_DIR / 'build' ] ... DJANGO_VITE_PLUGIN = { # other options 'DEV_MODE' : False, 'BUILD_DIR': 'build' }
Replace
build
with your build directory and make sure it's different fromSTATIC_ROOT
if it's set -
If your
BUILD_URL_PREFIX
containshttp://
orhttps://
comment that out. -
Run
npm run build
to build your assets and enjoy!