mirror of
				https://github.com/ae-utbm/sith.git
				synced 2025-11-04 02:53:06 +00:00 
			
		
		
		
	Go for a more generic js bundling architecture
* Don't tie the output name to webpack itself * Don't call js bundling webpack in python code * Make the doc more generic about js bundling
This commit is contained in:
		@@ -4,7 +4,7 @@ from accounting.models import ClubAccount, Company
 | 
			
		||||
from accounting.schemas import ClubAccountSchema, CompanySchema
 | 
			
		||||
from core.views.widgets.select import AutoCompleteSelect, AutoCompleteSelectMultiple
 | 
			
		||||
 | 
			
		||||
_js = ["webpack/accounting/components/ajax-select-index.ts"]
 | 
			
		||||
_js = ["bundled/accounting/components/ajax-select-index.ts"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AutoCompleteSelectClubAccount(AutoCompleteSelect):
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ from club.models import Club
 | 
			
		||||
from club.schemas import ClubSchema
 | 
			
		||||
from core.views.widgets.select import AutoCompleteSelect, AutoCompleteSelectMultiple
 | 
			
		||||
 | 
			
		||||
_js = ["webpack/club/components/ajax-select-index.ts"]
 | 
			
		||||
_js = ["bundled/club/components/ajax-select-index.ts"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AutoCompleteSelectClub(AutoCompleteSelect):
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
  <head>
 | 
			
		||||
    <title>{% trans %}Slideshow{% endtrans %}</title>
 | 
			
		||||
    <link href="{{ static('css/slideshow.scss') }}" rel="stylesheet" type="text/css" />
 | 
			
		||||
    <script src="{{ static('webpack/jquery-index.js') }}"></script>
 | 
			
		||||
    <script src="{{ static('bundled/jquery-index.js') }}"></script>
 | 
			
		||||
    <script src="{{ static('com/js/slideshow.js') }}"></script>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
{% extends "core/base.jinja" %}
 | 
			
		||||
{% block additional_js %}
 | 
			
		||||
  {% if settings.SENTRY_DSN %}
 | 
			
		||||
    <script src="{{ static('webpack/sentry-popup-index.ts') }}" defer ></script>
 | 
			
		||||
    <script src="{{ static('bundled/sentry-popup-index.ts') }}" defer ></script>
 | 
			
		||||
  {% endif %}
 | 
			
		||||
{% endblock additional_js %}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,17 +14,17 @@
 | 
			
		||||
 | 
			
		||||
      {% block jquery_css %}
 | 
			
		||||
        {# Thile file is quite heavy (around 250kb), so declaring it in a block allows easy removal #}
 | 
			
		||||
        <link rel="stylesheet" href="{{ static('webpack/jquery-index.css') }}">
 | 
			
		||||
        <link rel="stylesheet" href="{{ static('bundled/jquery-index.css') }}">
 | 
			
		||||
      {% endblock %}
 | 
			
		||||
      <link rel="preload" as="style" href="{{ static('webpack/fontawesome-index.css') }}" onload="this.onload=null;this.rel='stylesheet'">
 | 
			
		||||
      <noscript><link rel="stylesheet" href="{{ static('webpack/fontawesome-index.css') }}"></noscript>
 | 
			
		||||
      <link rel="preload" as="style" href="{{ static('bundled/fontawesome-index.css') }}" onload="this.onload=null;this.rel='stylesheet'">
 | 
			
		||||
      <noscript><link rel="stylesheet" href="{{ static('bundled/fontawesome-index.css') }}"></noscript>
 | 
			
		||||
 | 
			
		||||
      <script src="{{ url('javascript-catalog') }}"></script>
 | 
			
		||||
      <script src={{ static("webpack/core/components/include-index.ts") }}></script>
 | 
			
		||||
      <script src="{{ static('webpack/alpine-index.js') }}" defer></script>
 | 
			
		||||
      <script src="{{ static('webpack/htmx-index.js') }}" defer></script>
 | 
			
		||||
      <script src={{ static("bundled/core/components/include-index.ts") }}></script>
 | 
			
		||||
      <script src="{{ static('bundled/alpine-index.js') }}" defer></script>
 | 
			
		||||
      <script src="{{ static('bundled/htmx-index.js') }}" defer></script>
 | 
			
		||||
            <!-- Jquery declared here to be accessible in every django widgets -->
 | 
			
		||||
      <script src="{{ static('webpack/jquery-index.js') }}"></script>
 | 
			
		||||
      <script src="{{ static('bundled/jquery-index.js') }}"></script>
 | 
			
		||||
            <!-- Put here to always have access to those functions on django widgets -->
 | 
			
		||||
      <script src="{{ static('core/js/script.js') }}"></script>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
{%- endblock -%}
 | 
			
		||||
 | 
			
		||||
{% block additional_js %}
 | 
			
		||||
  <script src="{{ static("webpack/user/family-graph-index.js") }}" defer></script>
 | 
			
		||||
  <script src="{{ static("bundled/user/family-graph-index.js") }}" defer></script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
{%- endblock -%}
 | 
			
		||||
 | 
			
		||||
{% block additional_js %}
 | 
			
		||||
  <script src="{{ static('webpack/user/pictures-index.js') }}" defer></script>
 | 
			
		||||
  <script src="{{ static('bundled/user/pictures-index.js') }}" defer></script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,7 @@ class NFCTextInput(TextInput):
 | 
			
		||||
    def get_context(self, name, value, attrs):
 | 
			
		||||
        context = super().get_context(name, value, attrs)
 | 
			
		||||
        context["statics"] = {
 | 
			
		||||
            "js": staticfiles_storage.url("webpack/core/components/nfc-input-index.ts"),
 | 
			
		||||
            "js": staticfiles_storage.url("bundled/core/components/nfc-input-index.ts"),
 | 
			
		||||
            "css": staticfiles_storage.url("core/components/nfc-input.scss"),
 | 
			
		||||
        }
 | 
			
		||||
        return context
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ class MarkdownInput(Textarea):
 | 
			
		||||
        context = super().get_context(name, value, attrs)
 | 
			
		||||
 | 
			
		||||
        context["statics"] = {
 | 
			
		||||
            "js": staticfiles_storage.url("webpack/core/components/easymde-index.ts"),
 | 
			
		||||
            "css": staticfiles_storage.url("webpack/core/components/easymde-index.css"),
 | 
			
		||||
            "js": staticfiles_storage.url("bundled/core/components/easymde-index.ts"),
 | 
			
		||||
            "css": staticfiles_storage.url("bundled/core/components/easymde-index.css"),
 | 
			
		||||
        }
 | 
			
		||||
        return context
 | 
			
		||||
 
 | 
			
		||||
@@ -19,10 +19,10 @@ class AutoCompleteSelectMixin:
 | 
			
		||||
    pk = "id"
 | 
			
		||||
 | 
			
		||||
    js = [
 | 
			
		||||
        "webpack/core/components/ajax-select-index.ts",
 | 
			
		||||
        "bundled/core/components/ajax-select-index.ts",
 | 
			
		||||
    ]
 | 
			
		||||
    css = [
 | 
			
		||||
        "webpack/core/components/ajax-select-index.css",
 | 
			
		||||
        "bundled/core/components/ajax-select-index.css",
 | 
			
		||||
        "core/components/ajax-select.scss",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ from core.views.widgets.select import AutoCompleteSelect, AutoCompleteSelectMult
 | 
			
		||||
from counter.models import Counter, Product
 | 
			
		||||
from counter.schemas import ProductSchema, SimplifiedCounterSchema
 | 
			
		||||
 | 
			
		||||
_js = ["webpack/counter/components/ajax-select-index.ts"]
 | 
			
		||||
_js = ["bundled/counter/components/ajax-select-index.ts"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AutoCompleteSelectCounter(AutoCompleteSelect):
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
Vous avez ajouté une application et vous voulez y mettre du javascript ?
 | 
			
		||||
 | 
			
		||||
Vous voulez importer depuis cette nouvelle application dans votre script géré par webpack ?
 | 
			
		||||
Vous voulez importer depuis cette nouvelle application dans votre script géré par le bundler ?
 | 
			
		||||
 | 
			
		||||
Eh bien il faut manuellement enregistrer dans node où les trouver et c'est très simple.
 | 
			
		||||
 | 
			
		||||
@@ -11,7 +11,7 @@ D'abord, il faut ajouter dans node via `package.json`:
 | 
			
		||||
    // ...
 | 
			
		||||
    "imports": {
 | 
			
		||||
        // ...
 | 
			
		||||
        "#mon_app:*": "./mon_app/static/webpack/*"
 | 
			
		||||
        "#mon_app:*": "./mon_app/static/bundled/*"
 | 
			
		||||
    }
 | 
			
		||||
    // ...
 | 
			
		||||
}
 | 
			
		||||
@@ -25,7 +25,7 @@ Ensuite, pour faire fonctionne l'auto-complétion, il faut configurer `tsconfig.
 | 
			
		||||
        // ...
 | 
			
		||||
        "paths": {
 | 
			
		||||
            // ...
 | 
			
		||||
            "#mon_app:*": ["./mon_app/static/webpack/*"]
 | 
			
		||||
            "#mon_app:*": ["./mon_app/static/bundled/*"]
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,28 +27,28 @@ le système se débrouille automatiquement pour les transformer en `.css`
 | 
			
		||||
    <link rel="stylesheet" href="{{ static('core/style.scss') }}">
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## L'intégration webpack
 | 
			
		||||
## L'intégration avec le bundler javascript
 | 
			
		||||
 | 
			
		||||
Webpack est intégré un peu différement. Le principe est très similaire mais
 | 
			
		||||
les fichiers sont à mettre dans un dossier `static/webpack` de l'application à la place.
 | 
			
		||||
Le bundler javascript est intégré un peu différement. Le principe est très similaire mais
 | 
			
		||||
les fichiers sont à mettre dans un dossier `static/bundled` de l'application à la place.
 | 
			
		||||
 | 
			
		||||
Pour accéder au fichier, il faut utiliser `static` comme pour le reste mais en ajouter `webpack/` comme prefix.
 | 
			
		||||
Pour accéder au fichier, il faut utiliser `static` comme pour le reste mais en ajouter `bundled/` comme prefix.
 | 
			
		||||
 | 
			
		||||
```jinja
 | 
			
		||||
	{# Example pour ajouter sith/core/webpack/alpine-index.js #}
 | 
			
		||||
	<script src="{{ static('webpack/alpine-index.js') }}" defer></script>
 | 
			
		||||
	<script src="{{ static('webpack/other-index.ts') }}" defer></script>
 | 
			
		||||
	{# Example pour ajouter sith/core/bundled/alpine-index.js #}
 | 
			
		||||
	<script src="{{ static('bundled/alpine-index.js') }}" defer></script>
 | 
			
		||||
	<script src="{{ static('bundled/other-index.ts') }}" defer></script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
!!!note
 | 
			
		||||
	
 | 
			
		||||
	Seuls les fichiers se terminant par `index.js` sont exportés par webpack.
 | 
			
		||||
	Seuls les fichiers se terminant par `index.js` sont exportés par le bundler.
 | 
			
		||||
	Les autres fichiers sont disponibles à l'import dans le JavaScript comme
 | 
			
		||||
	si ils étaient tous au même niveau.
 | 
			
		||||
 | 
			
		||||
### Les imports au sein des fichiers de webpack
 | 
			
		||||
### Les imports au sein des fichiers des fichiers javascript bundlés
 | 
			
		||||
 | 
			
		||||
Pour importer au sein de webpack, il faut préfixer ses imports de `#app:`.
 | 
			
		||||
Pour importer au sein d'un fichier js bundlé, il faut préfixer ses imports de `#app:`.
 | 
			
		||||
 | 
			
		||||
Exemple:
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -116,7 +116,7 @@ sith/
 | 
			
		||||
21. Outil pour faciliter la fabrication des trombinoscopes de promo. 
 | 
			
		||||
22. Fonctionnalités pour gérer le spam. 
 | 
			
		||||
23. Gestion des statics du site. Override le système de statics de Django.
 | 
			
		||||
    Ajoute l'intégration du scss et de webpack
 | 
			
		||||
    Ajoute l'intégration du scss et du bundler js
 | 
			
		||||
    de manière transparente pour l'utilisateur. 
 | 
			
		||||
24. Fichier de configuration de coverage. 
 | 
			
		||||
25. Fichier de configuration de direnv. 
 | 
			
		||||
@@ -178,7 +178,7 @@ comme suit :
 | 
			
		||||
├── templates/ (2)
 | 
			
		||||
│   └── ...
 | 
			
		||||
├── static/ (3)
 | 
			
		||||
│   └── webpack/ (4)
 | 
			
		||||
│   └── bundled/ (4)
 | 
			
		||||
│   └── ...
 | 
			
		||||
├── api.py (5)
 | 
			
		||||
├── admin.py (6)
 | 
			
		||||
@@ -196,7 +196,7 @@ comme suit :
 | 
			
		||||
   cf. [Gestion des migrations](../howto/migrations.md)
 | 
			
		||||
2. Dossier contenant les templates jinja utilisés par cette application.
 | 
			
		||||
3. Dossier contenant les fichiers statics (js, css, scss) qui sont récpérée par Django.
 | 
			
		||||
4. Dossier contenant du js qui sera process avec webpack. Le contenu sera automatiquement process et accessible comme si ça avait été placé dans le dossier `static/webpack`.
 | 
			
		||||
4. Dossier contenant du js qui sera process avec le bundler javascript. Le contenu sera automatiquement process et accessible comme si ça avait été placé dans le dossier `static/bundled`.
 | 
			
		||||
5. Fichier contenant les routes d'API liées à cette application
 | 
			
		||||
6. Fichier de configuration de l'interface d'administration.
 | 
			
		||||
   Ce fichier permet de déclarer les modèles de l'application
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
{% block additional_js %}
 | 
			
		||||
    {# This script contains the code to perform requests to manipulate the
 | 
			
		||||
    user basket without having to reload the page #}
 | 
			
		||||
  <script src="{{ static('webpack/eboutic/eboutic-index.ts') }}"></script>
 | 
			
		||||
  <script src="{{ static('bundled/eboutic/eboutic-index.ts') }}"></script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block additional_css %}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block additional_js %}
 | 
			
		||||
  <script src="{{ static('webpack/galaxy/galaxy-index.js') }}" defer></script>
 | 
			
		||||
  <script src="{{ static('bundled/galaxy/galaxy-index.js') }}" defer></script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,8 @@
 | 
			
		||||
  "sideEffects": [".css"],
 | 
			
		||||
  "imports": {
 | 
			
		||||
    "#openapi": "./staticfiles/generated/openapi/index.ts",
 | 
			
		||||
    "#core:*": "./core/static/webpack/*",
 | 
			
		||||
    "#pedagogy:*": "./pedagogy/static/webpack/*"
 | 
			
		||||
    "#core:*": "./core/static/bundled/*",
 | 
			
		||||
    "#pedagogy:*": "./pedagogy/static/bundled/*"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@babel/core": "^7.25.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block additional_js %}
 | 
			
		||||
  <script src="{{ static('webpack/pedagogy/guide-index.js') }}" defer></script>
 | 
			
		||||
  <script src="{{ static('bundled/pedagogy/guide-index.js') }}" defer></script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block head %}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
{%- endblock -%}
 | 
			
		||||
 | 
			
		||||
{%- block additional_js -%}
 | 
			
		||||
  <script src="{{ static('webpack/sas/album-index.js') }}" defer></script>
 | 
			
		||||
  <script src="{{ static('bundled/sas/album-index.js') }}" defer></script>
 | 
			
		||||
{%- endblock -%}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
{% extends "core/base.jinja" %}
 | 
			
		||||
 | 
			
		||||
{%- block additional_css -%}
 | 
			
		||||
  <link defer rel="stylesheet" href="{{ static('webpack/core/components/ajax-select-index.css') }}">
 | 
			
		||||
  <link defer rel="stylesheet" href="{{ static('bundled/core/components/ajax-select-index.css') }}">
 | 
			
		||||
  <link defer rel="stylesheet" href="{{ static('core/components/ajax-select.scss') }}">
 | 
			
		||||
  <link defer rel="stylesheet" href="{{ static('sas/css/picture.scss') }}">
 | 
			
		||||
{%- endblock -%}
 | 
			
		||||
 | 
			
		||||
{%- block additional_js -%}
 | 
			
		||||
  <script defer src="{{ static('webpack/core/components/ajax-select-index.ts') }}"></script>
 | 
			
		||||
  <script defer src="{{ static("webpack/sas/viewer-index.ts") }}"></script>
 | 
			
		||||
  <script defer src="{{ static('bundled/core/components/ajax-select-index.ts') }}"></script>
 | 
			
		||||
  <script defer src="{{ static("bundled/sas/viewer-index.ts") }}"></script>
 | 
			
		||||
{%- endblock -%}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ from core.views.widgets.select import (
 | 
			
		||||
from sas.models import Album
 | 
			
		||||
from sas.schemas import AlbumSchema
 | 
			
		||||
 | 
			
		||||
_js = ["webpack/sas/components/ajax-select-index.ts"]
 | 
			
		||||
_js = ["bundled/sas/components/ajax-select-index.ts"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AutoCompleteSelectAlbum(AutoCompleteSelect):
 | 
			
		||||
 
 | 
			
		||||
@@ -3,13 +3,13 @@ from pathlib import Path
 | 
			
		||||
from django.contrib.staticfiles.apps import StaticFilesConfig
 | 
			
		||||
 | 
			
		||||
GENERATED_ROOT = Path(__file__).parent.resolve() / "generated"
 | 
			
		||||
IGNORE_PATTERNS_WEBPACK = ["webpack/*"]
 | 
			
		||||
IGNORE_PATTERNS_BUNDLED = ["bundled/*"]
 | 
			
		||||
IGNORE_PATTERNS_SCSS = ["*.scss"]
 | 
			
		||||
IGNORE_PATTERNS_TYPESCRIPT = ["*.ts"]
 | 
			
		||||
IGNORE_PATTERNS = [
 | 
			
		||||
    *StaticFilesConfig.ignore_patterns,
 | 
			
		||||
    *IGNORE_PATTERNS_TYPESCRIPT,
 | 
			
		||||
    *IGNORE_PATTERNS_WEBPACK,
 | 
			
		||||
    *IGNORE_PATTERNS_BUNDLED,
 | 
			
		||||
    *IGNORE_PATTERNS_SCSS,
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@@ -25,7 +25,7 @@ class StaticFilesConfig(StaticFilesConfig):
 | 
			
		||||
    """
 | 
			
		||||
    Application in charge of processing statics files.
 | 
			
		||||
    It replaces the original django staticfiles
 | 
			
		||||
    It integrates scss files and webpack.
 | 
			
		||||
    It integrates scss files and javascript bundling.
 | 
			
		||||
    It makes sure that statics are properly collected and that they are automatically
 | 
			
		||||
        when using the development server.
 | 
			
		||||
    """
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ from django.contrib.staticfiles import utils
 | 
			
		||||
from django.contrib.staticfiles.finders import FileSystemFinder
 | 
			
		||||
from django.core.files.storage import FileSystemStorage
 | 
			
		||||
 | 
			
		||||
from staticfiles.apps import GENERATED_ROOT, IGNORE_PATTERNS_WEBPACK
 | 
			
		||||
from staticfiles.apps import GENERATED_ROOT, IGNORE_PATTERNS_BUNDLED
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GeneratedFilesFinder(FileSystemFinder):
 | 
			
		||||
@@ -27,9 +27,9 @@ class GeneratedFilesFinder(FileSystemFinder):
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            ignored = ignore_patterns
 | 
			
		||||
            # We don't want to ignore webpack files in the generated folder
 | 
			
		||||
            # We don't want to ignore bundled files in the generated folder
 | 
			
		||||
            if root == GENERATED_ROOT:
 | 
			
		||||
                ignored = list(set(ignored) - set(IGNORE_PATTERNS_WEBPACK))
 | 
			
		||||
                ignored = list(set(ignored) - set(IGNORE_PATTERNS_BUNDLED))
 | 
			
		||||
 | 
			
		||||
            storage = self.storages[root]
 | 
			
		||||
            for path in utils.get_files(storage, ignored):
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,11 @@ from django.contrib.staticfiles.management.commands.collectstatic import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from staticfiles.apps import GENERATED_ROOT, IGNORE_PATTERNS_SCSS
 | 
			
		||||
from staticfiles.processors import OpenApi, Scss, Webpack
 | 
			
		||||
from staticfiles.processors import JSBundler, OpenApi, Scss
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Command(CollectStatic):
 | 
			
		||||
    """Integrate webpack and css compilation to collectstatic"""
 | 
			
		||||
    """Integrate js bundling and css compilation to collectstatic"""
 | 
			
		||||
 | 
			
		||||
    def add_arguments(self, parser):
 | 
			
		||||
        super().add_arguments(parser)
 | 
			
		||||
@@ -50,8 +50,8 @@ class Command(CollectStatic):
 | 
			
		||||
            return Path(location)
 | 
			
		||||
 | 
			
		||||
        Scss.compile(self.collect_scss())
 | 
			
		||||
        OpenApi.compile()  # This needs to be prior to webpack
 | 
			
		||||
        Webpack.compile()
 | 
			
		||||
        OpenApi.compile()  # This needs to be prior to javascript bundling
 | 
			
		||||
        JSBundler.compile()
 | 
			
		||||
 | 
			
		||||
        collected = super().collect()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,19 +6,19 @@ from django.contrib.staticfiles.management.commands.runserver import (
 | 
			
		||||
)
 | 
			
		||||
from django.utils.autoreload import DJANGO_AUTORELOAD_ENV
 | 
			
		||||
 | 
			
		||||
from staticfiles.processors import OpenApi, Webpack
 | 
			
		||||
from staticfiles.processors import JSBundler, OpenApi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Command(Runserver):
 | 
			
		||||
    """Light wrapper around default runserver that integrates webpack auto bundling."""
 | 
			
		||||
    """Light wrapper around default runserver that integrates javascirpt auto bundling."""
 | 
			
		||||
 | 
			
		||||
    def run(self, **options):
 | 
			
		||||
        # OpenApi generation needs to be before webpack
 | 
			
		||||
        # OpenApi generation needs to be before the bundler
 | 
			
		||||
        OpenApi.compile()
 | 
			
		||||
        # Only run webpack server when debug is enabled
 | 
			
		||||
        # Only run the bundling server when debug is enabled
 | 
			
		||||
        # Also protects from re-launching the server if django reloads it
 | 
			
		||||
        if os.environ.get(DJANGO_AUTORELOAD_ENV) is None and settings.DEBUG:
 | 
			
		||||
            with Webpack.runserver():
 | 
			
		||||
            with JSBundler.runserver():
 | 
			
		||||
                super().run(**options)
 | 
			
		||||
                return
 | 
			
		||||
        super().run(**options)
 | 
			
		||||
 
 | 
			
		||||
@@ -13,19 +13,19 @@ from sith.urls import api
 | 
			
		||||
from staticfiles.apps import GENERATED_ROOT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Webpack:
 | 
			
		||||
class JSBundler:
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def compile():
 | 
			
		||||
        """Bundle js files with webpack for production."""
 | 
			
		||||
        """Bundle js files with the javascript bundler for production."""
 | 
			
		||||
        process = subprocess.Popen(["npm", "run", "compile"])
 | 
			
		||||
        process.wait()
 | 
			
		||||
        if process.returncode:
 | 
			
		||||
            raise RuntimeError(f"Webpack failed with returncode {process.returncode}")
 | 
			
		||||
            raise RuntimeError(f"Bundler failed with returncode {process.returncode}")
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def runserver() -> subprocess.Popen:
 | 
			
		||||
        """Bundle js files automatically in background when called in debug mode."""
 | 
			
		||||
        logging.getLogger("django").info("Running webpack server")
 | 
			
		||||
        logging.getLogger("django").info("Running javascript bundling server")
 | 
			
		||||
        return subprocess.Popen(["npm", "run", "serve"])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -69,7 +69,7 @@ class JS:
 | 
			
		||||
            p
 | 
			
		||||
            for p in settings.STATIC_ROOT.rglob("*.js")
 | 
			
		||||
            if ".min" not in p.suffixes
 | 
			
		||||
            and (settings.STATIC_ROOT / "webpack") not in p.parents
 | 
			
		||||
            and (settings.STATIC_ROOT / "bundled") not in p.parents
 | 
			
		||||
        ]
 | 
			
		||||
        for path in to_exec:
 | 
			
		||||
            p = path.resolve()
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
 | 
			
		||||
{% block head %}
 | 
			
		||||
  {{ super() }}
 | 
			
		||||
  <script src="{{ static('webpack/subscription/stats-index.ts') }}" defer></script>
 | 
			
		||||
  <script src="{{ static('bundled/subscription/stats-index.ts') }}" defer></script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "outDir": "./staticfiles/generated/webpack/",
 | 
			
		||||
    "outDir": "./staticfiles/generated/bundled/",
 | 
			
		||||
    "sourceMap": true,
 | 
			
		||||
    "noImplicitAny": true,
 | 
			
		||||
    "module": "es6",
 | 
			
		||||
@@ -13,8 +13,8 @@
 | 
			
		||||
    "types": ["jquery", "alpinejs"],
 | 
			
		||||
    "paths": {
 | 
			
		||||
      "#openapi": ["./staticfiles/generated/openapi/index.ts"],
 | 
			
		||||
      "#core:*": ["./core/static/webpack/*"],
 | 
			
		||||
      "#pedagogy:*": ["./pedagogy/static/webpack/*"]
 | 
			
		||||
      "#core:*": ["./core/static/bundled/*"],
 | 
			
		||||
      "#pedagogy:*": ["./pedagogy/static/bundled/*"]
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,13 +7,13 @@ const TerserPlugin = require("terser-webpack-plugin");
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  entry: glob
 | 
			
		||||
    .sync("./!(static)/static/webpack/**/*?(-)index.[j|t]s?(x)")
 | 
			
		||||
    .sync("./!(static)/static/bundled/**/*?(-)index.[j|t]s?(x)")
 | 
			
		||||
    .reduce((obj, el) => {
 | 
			
		||||
      // We include the path inside the webpack folder in the name
 | 
			
		||||
      // We include the path inside the bundled folder in the name
 | 
			
		||||
      let relativePath = [];
 | 
			
		||||
      const fullPath = path.parse(el);
 | 
			
		||||
      for (const dir of fullPath.dir.split("/").reverse()) {
 | 
			
		||||
        if (dir === "webpack") {
 | 
			
		||||
        if (dir === "bundled") {
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
        relativePath.push(dir);
 | 
			
		||||
@@ -29,7 +29,7 @@ module.exports = {
 | 
			
		||||
  },
 | 
			
		||||
  output: {
 | 
			
		||||
    filename: "[name].js",
 | 
			
		||||
    path: path.resolve(__dirname, "./staticfiles/generated/webpack"),
 | 
			
		||||
    path: path.resolve(__dirname, "./staticfiles/generated/bundled"),
 | 
			
		||||
    clean: true,
 | 
			
		||||
  },
 | 
			
		||||
  resolve: {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user