Statics et Django : quand collectstatic ne suffit plus

Presenter Notes

Histoire d'un petit projet

Presenter Notes

Histoire d'un projet

$ git add autoslave/stations/static/stations/station.png

Presenter Notes

Histoire d'un projet

$ git add autoslave/stations/static/stations/station.png


$ git add autoslave/www/static/www/css/main.css

Presenter Notes

Histoire d'un projet

$ git add autoslave/stations/static/stations/station.png


$ git add autoslave/www/static/www/css/main.css


$ git add autoslave/www/static/www/js/lib/jquery-1.5.2.js

Presenter Notes

Histoire d'un projet

$ git add autoslave/stations/static/stations/station.png


$ git add autoslave/www/static/www/css/main.css


$ git add autoslave/www/static/www/js/lib/jquery-1.5.2.js


$ git add libs/Django-1.9.6-py2.py3-none-any.whl  # ?‽?

Presenter Notes

Reprenons-nous.

Presenter Notes

Un projet, moderne.

$ git add autoslave/stations/static/stations/station.png


$ git add autoslave/www/static/www/css/main.css


$ npm add --save jquery
$ git add package.json

Presenter Notes

Un projet, moderne.

package.json :

{
    "name": "redacted",
    "version": "0.0.1",
    "description": "Stuff",
    "author": "Raphaël Barrois",
    "license": "MIT",
    "dependencies": {
        "bootstrap": "~3.3.5",
        "jquery": "~2.1.4",
        "typeahead": "~0.2.0"
    }
}

Presenter Notes

Un projet, moderne.

$ npm install


$ ls node_modules/jquery/dist
jquery.js  jquery.min.js  jquery.min.map

Presenter Notes

Un projet, moderne.

$ npm install


$ ls node_modules/jquery/dist
jquery.js  jquery.min.js  jquery.min.map

$ ls -la autoslave/www/static/www/js/lib
jquery.js -> ../../../../../node_modules/jquery/dist/jquery.js

Presenter Notes

Un projet, moderne.

$ npm install


$ ls node_modules/jquery/dist
jquery.js  jquery.min.js  jquery.min.map

$ ls -la autoslave/www/static/www/js/lib
jquery.js -> ../../../../../node_modules/jquery/dist/jquery.js


$ django-admin.py collectstatic

$ ls autoslave/assets
jquery.0ad1eb5571fd.js

Presenter Notes

Complications

Presenter Notes

Complications

  • ReactJS
    • et son JSX

Presenter Notes

Complications

  • ReactJS
    • et son JSX
  • ES6
    • Et ses compilateurs / transpilers

Presenter Notes

Complications

  • ReactJS
    • et son JSX
  • ES6
    • Et ses compilateurs / transpilers
  • Sass, less

Presenter Notes

Complications

  • Minification & co
    • Moins de fichiers, plus petits

Presenter Notes

Complications

  • Minification & co
    • Moins de fichiers, plus petits
  • HTTP/2
    • Plus besoin de découper

Presenter Notes

Complications

  • Minification & co
    • Moins de fichiers, plus petits
  • HTTP/2
    • Plus besoin de découper
  • Un CDN
    • Il faut tout déployer avant de mettre à jour le code
    • Ou alors, on charge le JS depuis le CDN — mais uniquement en dév

Presenter Notes

Complications

  • Minification & co
    • Moins de fichiers, plus petits
  • HTTP/2
    • Plus besoin de découper
  • Un CDN
    • Il faut tout déployer avant de mettre à jour le code
    • Ou alors, on charge le JS depuis le CDN — mais uniquement en dév
  • Sentry
    • Avoir des rapports d'erreur sur le JS c'est bien, avec le code non-minifié c'est mieux

Presenter Notes

Vite, une toolchain !

Presenter Notes

Une toolchain ?

  • Gulp

Presenter Notes

Une toolchain ?

  • Gulp
  • Grunt

Presenter Notes

Une toolchain ?

  • Gulp
  • Grunt
  • Webpack

Presenter Notes

Une toolchain ?

  • Gulp
  • Grunt
  • Webpack
  • Browserify

Presenter Notes

Une toolchain ?

  • Gulp
  • Grunt
  • Webpack
  • Browserify
  • systemjs

Presenter Notes

Une toolchain ?

  • Gulp
  • Grunt
  • Webpack
  • Browserify
  • systemjs
  • jspm

Presenter Notes

Une toolchain ?

  • Gulp
  • Grunt
  • Webpack
  • Browserify
  • systemjs
  • jspm
  • npm

Presenter Notes

Une toolchain ?

  • Gulp
  • Grunt
  • Webpack
  • Browserify
  • systemjs
  • jspm
  • npm
  • Broccoli

Presenter Notes

Une toolchain ?

  • Gulp
  • Grunt
  • Webpack
  • Browserify
  • systemjs
  • jspm
  • npm
  • Broccoli
  • Brunch

Presenter Notes

Une toolchain ?

  • Gulp
  • Grunt
  • Webpack
  • Browserify
  • systemjs
  • jspm
  • npm
  • Broccoli
  • Brunch
  • ...

Presenter Notes

Une toolchain ?

Pour faire quoi ?

  • Du Javascript sans variables globales (ou presque)
  • Compilation (ES6, JSX, Sass, Less, ...)
  • Optimisation des images (high DPI, entrelacement, sprites, ...)
  • Concaténation et minification (moins de fichier => moins de requêtes)
  • Tree-shaking (élimination du code non-utilisé)
  • Génération de sourcemaps

Presenter Notes

Et Django ?

Presenter Notes

Et Django ?

collectstatic :

  1. Détecte les fichiers à intégrer
  2. Les enregistre sur le StaticFilesStorage
  3. Calcule les hash, intelligemment
  4. Enregistre les fichiers hashés sur le StaticFilesStorage

Presenter Notes

Et Django ?

collectstatic :

  1. Calcule les hash, intelligemment

app.jslib.jslib.csslogo.png

=> Autant le faire quand on compile / concatène / minifie tous les fichiers

Presenter Notes

Et Django ?

collectstatic :

  1. Les enregistre sur le StaticFilesStorage
  1. Enregistre les fichiers hashés sur le StaticFilesStorage
  • On n'a besoin que du fichier hashé, pas du fichier d'origine
  • Coût double

Presenter Notes

Quelles pistes ?

Presenter Notes

Pistes

  • Le ManifestStaticFilesStorage utilise un manifest.json
    • Indique, pour chaque fichier source, le nom du fichier hashé
    • Calculé au collectstatic, prêt à déployer sans recalcul
  • Rails, webpack, grunt, broccoli, gulp, ... génèrent un manifest.json comparable
    • main.js → main.0ad1eb5571fd.js
    • Parfois les détails des sources utilisées

Presenter Notes

Pistes

  • Standardiser un format de manifest.json compatible avec d'autres écosystèmes
  • Refondre la chaîne du collectstatic
    1. Scan des fichiers (sauf ceux pré-calculés par un autre pipeline)
    2. Traitement des fichiers (hash, copie locale, etc.)
    3. Écriture d'un manifest.json intégrant tous les fichiers du projet (admin compris)
    4. Écrire ces fichiers à un emplacement défini (local, CDN, etc.)
  • Sujet évoqué à Django Under the Hood et à la DjangoConEU

Presenter Notes

Questions ?

Presenter Notes

Merci !

Message subliminal: On recrute ;)

Presenter Notes