Integrando webpack-dev-server + hot module replacement con Django
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 staticregister = 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 (屮◉◞益◟◉)屮
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.
Y eso fue todo! ( ̯͡◕ ▽ ̯͡◕ )
Muchas gracias por leer el post, si lo encontraste útil dale un buen 👏 y compártelo con tus amigos, estaré muy agradecido si lo haces (•̪◡•̪)
Cualquier feedback, corrección o mejora es bienvenido!!!
Links de ayuda: