When writing django apps it's easy to ignore the organization of your front end code. Often, these backend coders will just write a static js
and css
file, stick it in the static directory, and call it a day.
You can also build them as two completely independent parts. With a complex gulp build routine independent of the django app. But if you don't know gulp, node, or those kinds of systems it can be a daunting process to get started with.
Enter django-compressor-toolkit (the name doesn't quite roll off the tongue).
Using django-compressor and django-compressor-toolkit you can write Javascript ES6 code with all its fancy import/export
logic or style your pages with sass
instead of css
, and leave your deploy routine largely untouched.
The first thing is to make sure you have node
and npm
installed on your computer.
$ sudo apt-get install nodejs npm
In your virtual environment pip install what you need.
$ pip install django-compressor django-compressor-toolkit
Now that that's set up, you'll need to set up node in the root directory of your app.
$ npm init
Follow the instructions and when you're done, there should be a package.json
file in the app directory. Add the following to the json object inside that file.
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babelify": "^7.3.0",
"browserify": "^14.4.0",
"node-sass": "^4.5.3",
"postcss-cli": "^4.1.0"
}
These development dependencies will be used by django-compressor-toolkit
to build your new static files.
Once these devDependencies
are in your package.json
file, install them with npm.
$ npm install
Note: The specifics of why and how this works gets a bit complicated so I'm going to ignore it in this guide. Just make sure to run all npm
commands from your app's route directory and you'll be fine...probably.
In your django settings.py
file you'll need to add the following:
INSTALLED_APPS += (
'compressor',
'compressor_toolkit',
)
STATICFILES_FINDERS += (
'compressor.finders.CompressorFinder',
)
COMPRESS_CSS_FILTERS = [
'compressor.filters.css_default.CssAbsoluteFilter',
'compressor.filters.cssmin.CSSMinFilter',
'compressor.filters.template.TemplateFilter'
]
COMPRESS_JS_FILTERS = [
'compressor.filters.jsmin.JSMinFilter',
]
COMPRESS_PRECOMPILERS = (
('module', 'compressor_toolkit.precompilers.ES6Compiler'),
('css', 'compressor_toolkit.precompilers.SCSSCompiler'),
)
COMPRESS_ENABLED = True
Now you can use the compress template tag in your templates. Notice the type
of the script is module
.
{% compress css inline %}
<link rel="stylesheet" type="text/css" href="{% static 'path/to/style.css' %}">
{% endcompress %}
{% compress js %}
<script type="module" src="{% static 'path/to/script.js' %}"></script>
{% endcompress %}
Now your javascript can be written in ES6!
helloWorld.js
function helloWorld() {
console.log('Hello World');
}
export default helloWorld;
script.js
import helloWorld from './helloWorld';
test(); // 'Hello World'
You can also now use npm packages in your django app. For example, if you wanted to use jQuery simply install it.
$ npm install jquery --save
And import it in your script.js
file.
import $ from 'jquery';
Django will rebuild the files every time the template is loaded by default. This works great in development, but you'll want to make the following changes in production to save on server load.
The first thing you'll want to do is add node_modules
to your .gitignore
file. You don't want to upload all those files to github.
Add the following to you settings.py
file.
COMPRESS_OFFLINE = True
And then add the following management command to your deployment routine.
$ npm install
$ python manage.py compress
Because compressor is plugged into your django static files system, the new built files should be handled for you.
You'll probabaly have to make changes to your chef scripts or whatever you use to set up your deployment server. But that's a guide for another time.
Happy coding!
For those newbies on Django, don't forget to add
{% load compress %}
while setting up your templates, because it won't work otherwise (it'll throw an error of invalid block tag: compress).