Integrando webpack-dev-server + hot module replacement con Django

Giancarlos Isasi
Crehana
Published in
4 min readApr 23, 2018
Tranquilo, no es tan difícil como parece ( ◠‿◠)

TL;DR: En este post no profundizaré mucho en los conceptos usados pues asumo que el lector tiene cierta experiencia con webpack y Django, aún asi al final del post dejaré algunos links que usted puede usar para profundizar en estos conceptos.

Debo suponer que si llegaste a este post es porque buscas una forma rápida y sencilla de mejorar la experiencia de desarrollo en el lado front-end… y que obviamente ya usas webpack y Django ლ(╹◡╹ლ)

Para dejarlo simple, webpack-dev-server es una herramienta que automáticamente actualiza el navegador cuando haces algún cambio en tu código javascript, para comunicar estos cambios al navegador webpack-dev-server usa un server de express.js configurado con socket.io.

Para tener en cuenta:

Live reload: Comportamiento por default de webpack-dev-server, al hacer un cambio en el código el navegador automáticamente hace un full reload.

Hot Module Replacement (HMR): Usando algunos plugins y una configuración extra podemos hacer que nuestros cambios se vean reflejados en el navegador sin necesidad de hacer un full reload.

Vamos directamente a ello…

Configurando webpack:

Primero instala el paquete:

npm install --save-dev webpack-dev-server

Luego cambiemos la configuración de nuestro webpack:

Como viste no es nada complicado, solo configuramos el devServer y agregamos un par de plugins para obtener el HMR, ahora solo necesitamos agregar un nuevo script en nuestro package.json para correr el webpack-dev-server:

"client:hmr": "webpack-dev-server --colors --progress"

Ejecutamos el comando en una consola y listo, ya tenemos el 70% del trabajo hecho

npm run client:hmr

Configurando Django:

Lo que normalmente tenemos en nuestros templates de Django es algo como (suponiendo que tus archivos estáticos pueden ser accedidos vía http:localhost:8000/static/**/*):

<script src="{% static 'js/app.min.js' %}"></script>

Pero ahora que ya tenemos webpack-dev-server corriendo en el puerto 9000, todos nuestros scripts deben apuntar a ese puerto, asi que cambiemos el script por:

<script src="http://localhost:9000/static/js/app.min.js"></script>

Si, http://localhost:9000/static/js es el valor que colocamos en output.publicPath y devServer.publicPath. Y si, puedes ponerle cualquier ruta que quieras (╯°□°)╯ pero por seguir el estándar con el que nuestra app de Django sirve los estáticos opté por configurarlo de esa forma.

Hasta este punto si entras a la url del template configurado podrás ver en la consola del navegador los siguientes logs:

Lo hemos logrado…

…pero está imperfecto ( ゚,_ゝ゚) . No tratamos de ser perfectos pero si hacerlo lo mejor posible, verdad? ┌( ಠ_ಠ )┘

El principal problema es que para llevarlo a production tendremos que ‘manualmente’ cambiar la url de los scripts y luego para regresar a modo development tendremos que volverlo a cambiar.

La solución:
Crear un template tag que nos permita hacer el cambio entre modo production/development.

Para ello recomiendo crear variables en nuestro settings.py para poder re-usarlas en los lugares que necesitemos.

WEBPACK_DEV_SERVER_URL = ‘http://localhost:9000'
WEBPACK_DEV_SERVER = True

Las usamos en la creación de nuestro webpack template tag:

# ../templatetags/webpack_tags.py# No soy experto en django ya que soy más del lado front-end que    # back-end, pero asi es como yo lo haría (ノ ಥ ウಥ )ノfrom django import template
from django.conf import settings
from django.contrib.staticfiles.templatetags.staticfiles import static
register = template.Library()@register.simple_tag
def webpack(javascript_file, **args):
if settings.DEBUG and settings.WEBPACK_DEV_SERVER:
return '%s/%s' % (settings.WEBPACK_DEV_SERVER_URL, javascript_file)
return static(javascript_file)

Ahora vamos a nuestro template y cambiamos el script:

{% load webpack_tags %}

<script src="{% webpack 'app.min.js' %}"></script>

Actualiza tu navegador y deberías ver los logs del hmr:

Lo logramos (屮◉◞益◟◉)屮

Bien hecho soldado

Obviamente aún falta activar el HMR dentro de tus archivos javascript, pero eso es relativamente fácil asi que no deberías tener problemas haciéndolo por ti mismo -[también querías que te muestre como? lo siento chico, la vida no es tan fácil ლ(ಠ益ಠლ)]-
Aquí te dejo la guía oficial.

--

--

Giancarlos Isasi
Crehana

Javascript Developer | Sr Frontend Developer at @crehanacom | Learning nodejs | Ruby/Python fan