open1024.fr

Libérez vos octets !

Outils pour utilisateurs

Outils du site


developpement:django:django_webpack_setup_project

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

developpement:django:django_webpack_setup_project [2020/05/20 10:18]
developpement:django:django_webpack_setup_project [2021/07/02 10:39] (Version actuelle)
jc_online créée
Ligne 1: Ligne 1:
 +2020-05-10: Création \\
 +2020-05-11: Ajout SASS \\
 +2020-05-12: Ajout  foundation-sites CSS Framework\\
 +2020-05-15: ReactJS 'App.js & class App render' \\
 +2020-05-16: Ajout de Compass SASS Framework \\
 +2020-05-17: Nouvelle structure de dossiers \\
 +2020-05-17: Utilisation \\
  
 +{{:developpement:django:django_logo_256x256px_.png?nolink&110 |}}
 +{{:developpement:django:webpack-logo.jpeg?nolink&80 |}}
 +{{:developpement:django:babel-logo.png?nolink&80 |}}
 +{{:developpement:django:react.js_logo-150-150.png?nolink&80 |}}
 +{{:developpement:django:sass-logo.png?nolink&75 |}}
 +{{:developpement:django:compass.png?nolink|}}
 +====== Django setup avec Webpack ReactJS et SASS======
 +Cette procédure est écrite à l'occasion de la refonte du projet //sport reporting//.\\
 +En plus d'utiliser //pipenv// j'y ajoute //webpack// afin d'intégrer //sass// et //foundation zurb// depuis //yarnpkg// sous //debian 10 bullseye (testing)//.\\
 +
 +Cette méthode est de plusieurs jours de recherche et de test de différentes sources:
 +  * Vidéo [[https://www.youtube.com/watch?v=Mx3ChaYA0Gw]] 
 +  * Vidéo [[https://www.youtube.com/watch?v=k78Oi383DRc]]
 +  * De cette article [[https://pascalw.me/blog/2020/04/19/webpack-django.html]] 
 +  * Mais controversé par celui-ci [[https://www.valentinog.com/blog/webpack-django/]]. \\
 +
 +Donc à utiliser pour les petites applications, ne nécessitant pas un gros fichier JS (>200ko) sinon, il faut utiliser le code spliting [[https://webpack.js.org/plugins/split-chunks-plugin/]]
 +
 +===== Dossier projet =====
 +<file bash>
 +# création du dossier projet:
 +cd ~/dev/
 +mkdir sport
 +cd sport
 +</file>
 +===== Git init =====
 +<file bash>
 +git init
 +touch .gitignore
 +</file>
 +Dans le fichier //.gitignore// mettre les exclusions du standard de //github//:
 +  * Python [[https://github.com/github/gitignore/blob/master/Python.gitignore]]
 +  * NodeJS [[https://github.com/github/gitignore/blob/master/Node.gitignore]]
 +<file bash>
 +git add -A
 +git commit -m "build(init): Main app directory"
 +</file>
 +
 +===== Environnement Python =====
 +Cette commande permet de créer l'environnement virtuel et de lactiver:
 +<file bash>
 +pipenv shell
 +
 +Creating a virtualenv for this project…
 +Pipfile: /home/jc/dev/sport/Pipfile
 +Using /usr/bin/python3 (3.8.2) to create virtualenv…
 +⠴ Creating virtual environment...
 +</file>
 +Installation de django et modules aux. depuis pipenv:
 +<file bash>
 +pipenv install django Pillow django-crispy-forms crispy-forms-foundation
 +ls -lh
 +-rw-r--r-- 1 jc jc  220 mai   10 11:46 Pipfile
 +-rw-r--r-- 1 jc jc 4,3K mai   10 11:47 Pipfile.lock
 +</file>
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(init): Python virtual environnement."
 +</file>
 +===== Création du projet sport =====
 +<file bash>
 +django-admin startproject . config_prj
 +</file>
 +Organisation des dossiers du projet:
 +<file bash>
 +tree
 +.
 +├── config_prj
 +│   ├── asgi.py
 +│   ├── __init__.py
 +│   ├── settings.py
 +│   ├── urls.py
 +│   └── wsgi.py
 +├── manage.py
 +├── Pipfile
 +└── Pipfile.lock
 +</file>
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(django): Django init project."
 +</file>
 +===== Création de l'application reporting =====
 +<file bash>
 +python manage.py startapp reporting
 +</file>
 +**Activation de l'app**
 +<file python reporting/settings.py>
 +ALLOWED_HOSTS = ["127.0.0.1", "192.168.1.2", "192.168.1.3", "192.168.1.4"]
 +INSTALLED_APPS = [
 +    [...]
 +#    'users.apps.UsersConfig',           #user management
 +    'reporting.apps.ReportingConfig',   #main app
 +    'crispy_forms',                     #addon for load django form
 +]
 +
 +TEMPLATES = [
 +    {
 +        'BACKEND': 'django.template.backends.django.DjangoTemplates',
 +        'DIRS': [
 +            os.path.join(BASE_DIR, 'templates'),
 +        ],
 +        [...]
 +
 +LANGUAGE_CODE = 'fr-fr'
 +</file>
 +**Structure des dossiers :**
 +<file bash>
 +.
 +├── config_prj
 +│   ├── asgi.py
 +│   ├── __init__.py
 +│   ├── settings.py
 +│   ├── urls.py
 +│   ├── views.py
 +│   └── wsgi.py
 +├── manage.py
 +├── Pipfile
 +├── Pipfile.lock
 +└── reporting
 +    ├── admin.py
 +    ├── apps.py
 +    ├── __init__.py
 +    ├── migrations
 +    │   └── __init__.py
 +    ├── models.py
 +    ├── tests.py
 +    └── views.py
 +</file>
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(django): Django reporting app."
 +</file>
 +
 +===== Paramétrage Django pour Webpack =====
 +Dans le dossier racine du projet **//config_prj//**, créer le dossier **//template//**:
 +<file bash>
 +mkdir templates
 +</file>
 +Dans le dossier de configuration du projet, créer le fichier **//views.py//**:
 +<file python views.py>
 +from django.shortcuts import render
 +
 +def index(request):
 +    return render(request, "index.html")
 +</file>
 +Dans le dossier **//template//** créer le fichier **//index.html//**
 +<file html template/index.html>
 +<html>
 +    <head>
 +        <title>Demo</title>
 +    </head>
 +    <body>
 +        <h1>Hello World!</h1>
 +    </body>
 +</html>
 +</file>
 +Dans le fichier **//urls.py//**, ajouter la vue:
 +<file python config_prj/urls.py>
 +from django.contrib import admin
 +from django.urls import path
 +from . import views
 +
 +urlpatterns = [
 +    path('', views.index),
 +    path('admin/', admin.site.urls),
 +]
 +</file>
 +Dans le fichier **//settings.py//** ajouter l'accès au dossier **//templates//**:
 +<file python config_prj/settings.py>
 +TEMPLATES = [
 +    {
 +        'BACKEND': 'django.template.backends.django.DjangoTemplates',
 +        'DIRS': [os.path.join(BASE_DIR, 'templates')],
 +[...]
 +</file>
 +A ce stade on peut contrôler l'enchaînement des urls.py/views.py/index.html:
 +<file bash>
 +python manage.py runserver
 +</file>
 +{{:developpement:django:hello-world.png?nolink|}}
 +**Structure :**
 +<file>
 +.
 +├── config_prj
 +│   ├── asgi.py
 +│   ├── __init__.py
 +│   ├── settings.py
 +│   ├── urls.py
 +│   ├── views.py
 +│   └── wsgi.py
 +├── db.sqlite3
 +├── manage.py
 +├── Pipfile
 +├── Pipfile.lock
 +├── reporting
 +│   ├── admin.py
 +│   ├── apps.py
 +│   ├── __init__.py
 +│   ├── migrations
 +│   │   └── __init__.py
 +│   ├── models.py
 +│   ├── tests.py
 +│   └── views.py
 +└── templates
 +    └── index.html
 +</file>
 +**Git**:
 +<file bash>
 +git add -A
 +git commit -m "build(django): Django hello world."
 +</file>
 +===== Ajout static CSS sans SASS =====
 +A la racine du projet, créer les dossiers **static/css** avec **main.css**
 +<file css static/css/main.css>
 +h1 {
 +    color: red;
 +}
 +</file>
 +Dans **template/index.html** ajout en en-tête **load static** et le lien **stylesheet**:
 +<file html template/index.html>
 +{% load static %}
 +<html>
 +    <head>
 +        <title>Demo</title>
 +        <link rel="stylesheet" href="{% static 'css/main.css' %}"/>
 +    </head>
 +    <body>
 +        <h1>Hello World!</h1>
 +    </body>
 +</html>
 +</file>
 +En fin du fichier **settings.py** ajouter :
 +<file python config_prj/settings.py>
 +STATICFILES_DIRS = [
 +    os.path.join(BASE_DIR, 'static')
 +]
 +</file>
 +**Visu** du rendu avec le **css** sans le //transpileur SASS//:
 +{{:developpement:django:hello-world-red.png?nolink|}} \\
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(django): CSS without SASS transpiler."
 +</file>
 +
 +====== Webpack setup ======
 +**Webpack** est utiliser pour générer ou **transpiler** du code dans un autre format de code: \\
 +Exemple, le langage **SASS** vers **CSS** et **JSX** en **JS**. \\
 +
 +===== Init =====
 +
 +Ce placer dans le dossier **static** du projet :
 +<file bash>
 +yarnpkg init
 +
 +yarn init v1.22.4
 +question name (django_static): 
 +question version (1.0.0): 
 +question description ("django with webpack integration in static folder"): django with webpack integration in static folder
 +question entry point (index.js): 
 +question repository url: 
 +question author (JC_onLine): 
 +question license (MIT): 
 +question private: 
 +success Saved package.json
 +</file>
 +
 +===== Installation =====
 +<note>L'option **-D** de **yarnpkg add -D [...]** permet de séparer les modules nécessaires au développement.</note>
 +<file bash>
 +yarnpkg add -D webpack webpack-cli @babel/core @babel/preset-env @babel/preset-react babel-loader style-loader css-loader sass sass-loader node-sass
 +[...]
 +info Direct dependencies
 +├─ @babel/core@7.9.6
 +├─ @babel/preset-env@7.9.6
 +├─ @babel/preset-react@7.9.4
 +├─ babel-loader@8.1.0
 +├─ css-loader@3.5.3
 +├─ node-sass@4.14.1
 +├─ sass-loader@8.0.2
 +├─ sass@1.26.5
 +├─ style-loader@1.2.1
 +├─ webpack-cli@3.3.11
 +└─ webpack@4.43.0
 +[...]
 +</file>
 +Toujours dans le dossier **static** du projet, créer le fichier **webpack.config.js**:
 +<file JavaScript static/webpack.config.js>
 +const path = require('path')
 +
 +module.exports = {
 +    entry: {
 +        app: './src/index.js'
 +    },
 +    watch: true,
 +    devtool: 'source-map',
 +    output: {
 +        filename: '[name].bundle.js',
 +        path: path.resolve(__dirname, 'dist')
 +    },
 +    module: {
 +        rules: [
 +            {
 +                test: /\.js$/,
 +                exclude: /node_modules/,
 +                use: ['babel-loader']
 +            }
 +        ]
 +    },
 +    resolve: {
 +        extensions: [
 +            '.js'
 +        ]
 +    }
 +}
 +</file>
 +Dans le dossier **static**, créer le dossier **src** avec **index.js** dedans:
 +<file JavaScript static/src/js/index.js>
 +const x = "this is a test alert";
 +alert(x);
 +</file>
 +et ajouter le lien js à **index.html**
 +<file html template/index.html>
 +{% load static %}
 +<html>
 +    <head>
 +        <title>Demo</title>
 +        <link rel="stylesheet" href="{% static 'css/main.css' %}"/>
 +    </head>
 +    <body>
 +        <h1>Hello World!</h1>
 +        <script src="{% static 'dist/app.bundle.js' %}"></script>
 +    </body>
 +</html>
 +</file>
 +Paramétrage du fichier **package.json** (en dessous de "main": "index.js"):
 +<file json static/package.json>
 +[...]
 +  "main": "index.js",
 +  "scripts": {
 +      "test": "echo \"Error: no test specified\" && exit 1",
 +      "webpack": "webpack"
 +  },
 +[...]
 +</file>
 +===== 1er test de webpack =====
 +Il faut 2 terminaux: \\
 +  * Un terminal dans le dossier **static**
 +<file bash>
 +yarnpkg run webpack
 +
 +webpack is watching the files…
 +
 +Hash: ed230c0c3f7b8e8a30d0
 +Version: webpack 4.43.0
 +Time: 1795ms
 +Built at: 10/05/2020 18:24:17
 +            Asset       Size  Chunks                   Chunk Names
 +    app.bundle.js  998 bytes        [emitted]        app
 +app.bundle.js.map   4.62 KiB        [emitted] [dev]  app
 +Entrypoint app = app.bundle.js app.bundle.js.map
 +[0] ./src/index.js 43 bytes {0} [built]
 +</file>
 +<note>Pour lancer webpack en mode développement :\\
 +**//yarnpkg run webpack - -mode development//** \\
 +Car par défaut c'est le mode production qui minimifie je code.\\ \\
 +  * Il est possible d'ajouter **- -mode development** dans **//package.json//** objet **//scrips://**.
 +  * 2ème solution, dans **//webpack.config.js//** ajouter la clé **mode: 'development',**.\\
 +J'utilise cette 2ème méthode car je préfère concentrer les modifications dans le fichier **//webpack.config.js//**.
 +</note>
 +**Webpack** a créé le dossier **dist** avec les fichier **app.bundle.js** et **app.bundle.js.map** dedans.
 +  * Un terminal à la racine du projet
 +<file bash>
 +python manage.py runserver
 +</file>
 +**Visu** du résultat: \\
 +{{:developpement:django:hello-world-alert.png?nolink|}} \\
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(webpack): yarnpkg run webpack make js bundle for django."
 +</file>
 +====== ReactJS ======
 +===== Installation =====
 +<file JavaScript>
 +yarnpkg add react react-dom
 +info Direct dependencies
 +├─ react-dom@16.13.1
 +└─ react@16.13.1
 +</file>
 +Mise à jour de **webpack.config.js**:
 +<file JavaScript>
 +const path = require('path')
 +
 +module.exports = {
 +    entry: {
 +        app: './src/index.js'
 +    },
 +    watch: true,
 +    devtool: 'source-map',
 +    output: {
 +        filename: '[name].bundle.js',
 +        path: path.resolve(__dirname, 'dist')
 +    },
 +    module: {
 +        rules: [
 +            {
 +                test: /\.js$/,
 +                exclude: /node_modules/,
 +                use: [
 +                    {
 +                        loader: 'babel-loader',
 +                        options: {
 +                            presets: ['@babel/react']
 +                      }
 +                    }
 +                ],
 +            }
 +        ]
 +    },
 +    resolve: {
 +        extensions: [
 +            '.js'
 +        ]
 +    }
 +}
 +</file>
 +===== Utilisation =====
 +Modifions le fichier **src/index.js** (suppression du test alert):
 +<file JavaScript static/src/js/index.js>
 +import React from 'react';
 +import ReactDOM from 'react-dom';
 +
 +ReactDOM.render(
 +    <div>
 +        <h1>This is JSX !!</h1>
 +    </div>,
 +    document.getElementById("root")
 +)
 +</file>
 +Modifions le fichier **index.html** pour accueilir le **JSX**:
 +<file html template/index.html>
 +{% load static %}
 +<html>
 +    <head>
 +        <title>Demo</title>
 +        <link rel="stylesheet" href="{% static 'css/main.css' %}"/>
 +    </head>
 +    <body>
 +        <div id="root"></div>
 +        <script src="{% static 'dist/app.bundle.js' %}"></script>
 +    </body>
 +</html>
 +</file>
 +**Visu:** \\
 +{{:developpement:django:this-is-jsx-react-red.png?nolink|}} \\
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(react): yarnpkg run webpack make react js bundle for jango."
 +</file>
 +<note>Pour séparer le **JS** du **SASS**,\\
 +on déplace **src/index.js** vers **src/js/index.js**</note>
 +Mise à jour de **webpack.config.js**
 +<file JavaScript static/webpack.config.js>
 +    entry: {
 +        app: './src/js/index.js'
 +    },
 +</file>
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(webpack): Move src/index.js to src/js/index.js."
 +git commit -m "build(webpack): Fix webpack.config.js with src/js/index.js"
 +</file>
 +
 +====== Installation de SASS ======
 +2020-05-11 \\
 +Les modules **SASS** ont été installés au début de cette procédure. Pour rappel :
 +<file bash>
 +yarnpkg add -D style-loader css-loader sass sass-loader node-sass
 +</file>
 +===== Fichier CSS avec mini-css-extract-plugin =====
 +<file bash>
 +yarnpkg add -D mini-css-extract-plugin
 +└─ mini-css-extract-plugin@0.9.0
 +</file>
 +Dans le fichier **webpack.config.js** ajouter la constante **MiniCssExtractPlugin**: et remplacer **'style-loader'**:
 +<file JavaScript static/webpack.config.js>
 +const path = require('path')
 +const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 +
 +module.exports = {
 +    entry: {
 +        app: './src/js/index.js'
 +    },
 +    mode: 'development',
 +    watch: true,
 +    devtool: 'source-map',
 +    output: {
 +        filename: '[name].bundle.js',
 +        path: path.resolve(__dirname, 'dist')
 +    },
 +    module: {
 +        rules: [
 +            {
 +                test: /\.js$/,
 +                exclude: /node_modules/,
 +                use: [
 +                    {
 +                        loader: 'babel-loader',
 +                        options: {
 +                            presets: ['@babel/react']
 +                      }
 +                    }
 +                ],
 +            },
 +            {
 +                test: /\.(scss)$/,
 +                exclude: /node_modules/,
 +                use: [
 +                    MiniCssExtractPlugin.loader,
 +                    'css-loader',
 +                    'sass-loader',
 +                ],
 +            }
 +        ]
 +    },
 +    plugins: [
 +        new MiniCssExtractPlugin({
 +            filename: '../css/index.css',
 +        })
 +    ],
 +    resolve: {
 +        extensions: [
 +            '.js'
 +        ]
 +    }
 +}
 +</file>
 +Créer le dossier **src/scss** avec **index.scss** dedans.
 +<file scss src/scss/index.scss>
 +$h1-color: #3465A4;
 +h1 {
 +    color: $h1-color;
 +}
 +</file>
 +Dans le fichier **index.js** ajouter l'importation de **index.scss**:
 +<file JavaScript static/src/js/index.js>
 +import '../scss/index.scss';
 +import React from 'react';
 +import ReactDOM from 'react-dom';
 +
 +ReactDOM.render(
 +    <div>
 +        <h1>This is JSX with SASS style file!!</h1>
 +    </div>,
 +    document.getElementById("root")
 +)
 +</file>
 +Dans le fichier **index.html** mettre à jour l'appel du  **static/css/index.css**
 +<file html template/index.html>
 +{% load static %}
 +<html>
 +    <head>
 +        <title>Demo</title>
 +        <link rel="stylesheet" href="{% static 'css/index.css' %}"/>
 +    </head>
 +    <body>
 +        <div id="root"></div>
 +        <script src="{% static 'dist/app.bundle.js' %}"></script>
 +    </body>
 +</html>
 +</file>
 +**Visu:** \\
 +{{:developpement:django:this-is-jsx-react-with-sass-style.png?nolink|}} \\
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(webpack): Add SASS transpiler. Tested in Django with JSX and SASS."
 +git commit -m "test(react): This is ReactJS JSX with SASS style file powered by Django!!"
 +</file>
 +
 +====== Foundation Zurb ======
 +2020-05-12 \\
 +Dans le dossier **static** :
 +<file bash>
 +yarnpkg add foundation-sites
 +info Direct dependencies
 +└─ foundation-sites@6.6.3
 +</file>
 +Ajouter les **@import** et **@include** dans le fichier **Sass**:
 +<file scss static/src/scss/index.scss>
 +@import 'foundation-sites/scss/foundation';
 +@include foundation-global-styles;
 +@include foundation-typography;
 +
 +.content {
 +    margin-top: 10px;
 +    margin-left: 20px;
 +}
 +$h1-color: #3465A4;
 +.title {
 +    color: $h1-color;
 +}
 +.mybutton {
 +    @include button();
 +    margin-left: 50px;
 +    // exemple avec customisation des couleurs:
 +    // @include button(false, #3B3933, #2A2926, #EDEDED, "solid");
 +}
 +</file>
 +Détail du fichier **JSX** correspondant:
 +<file JavaScript  >
 +import '../scss/index.scss';
 +import React from 'react';
 +import ReactDOM from 'react-dom';
 +
 +ReactDOM.render(
 +    <div className="content">
 +        <h3 className="title">
 +            This is ReactJS JSX with SASS file and Foundation Zurb style, </h3>
 +        <h2>powered by Django!!</h2>
 +        <a href="about.html" className="mybutton">Learn More</a>
 +
 +    </div>,
 +    document.getElementById("root")
 +)
 +</file>
 +**Rendu:** \\
 +{{:developpement:django:this-is-jsx-react-with-sass-style-_-foundation.png?nolink|}} \\
 +**git:**
 +<file bash>
 +git add -A
 +git commit -m "build(foundation): Add Foundation Zurb CSS framework. Test typo & button better presentation."
 +</file>
 +====== ReactJS & App.js class render component ======
 +2020-05-15 \\
 +Affin d'être conforme à la méthode donnée dans l'outil officiel **//creat-react-app//** voici la mise en place:
 +===== App.js =====
 +C'éer le fichier **App.js** :
 +<note important>La majuscule de **App.js** est importante pour définir un composant React.</note>
 +<file JavaScript static/src/js/App.js>
 +import React, { Component }  from 'react';
 +import ReactDOM from 'react-dom';
 +import '../scss/index.scss';
 +
 +class App extends Component {
 +    render() {
 +        return (
 +            <div className="content">
 +                <h3 className="title">
 +                    This is ReactJS 'App.js & class App render' JSX with SASS file and Foundation Zurb style, </h3>
 +                <h2>powered by Django!!</h2>
 +                <a href="about.html" className="mybutton">Learn More</a>
 +            </div>
 +        );
 +    }
 +}
 +export default App;
 +</file>
 +===== index.js =====
 +Mettre à jour **index.js** permettant l'appel du **component App.js**:
 +<file JavaScript>
 +import React from 'react';
 +import ReactDOM from 'react-dom';
 +import '../scss/index.scss';
 +import App from './App';
 +
 +ReactDOM.render(<App />, document.getElementById("root"));
 +</file>
 +===== index.thml =====
 +La page //HTML// reste inchangée, voici le code pour rappel:
 +<file html template/index.html>
 +{% load static %}
 +<html>
 +    <head>
 +        <title>Demo</title>
 +        <link rel="stylesheet" href="{% static 'css/index.css' %}"/>
 +    </head>
 +    <body>
 +        <div id="root"></div>
 +        <script src="{% static 'dist/app.bundle.js' %}"></script>
 +    </body>
 +</html>
 +</file>
 +===== Rendu =====
 +C'est transparent pour l'utilisateur, seul le texte est changer pour montrer que ça fonctionne: \\
 +{{:developpement:django:this-is-jsx-react-app.js-_-app-render-with-sass-style-_-foundation.png?nolink|}} \\
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(reactJS): Use App.js with App render, main component."
 +</file>
 +====== Compass + mixin ======
 +J'utilise les librairies de **Compass** pour mettre en relief certains composant comme les cadres, boutons et ligne de tableau le survol d'éléments, en utilisant les dégradés.
 +<file bash>
 +yarnpkg add compass compass-mixins
 +info Direct dependencies
 +├─ compass-mixins@0.12.10
 +└─ compass@0.1.1
 +</file>
 +Exemple d'utilisation:
 +<file sass static/src/scss/index.scss>
 +// #### Foundation Zurg ####
 +@import 'foundation-sites/scss/foundation';
 +@include foundation-global-styles;
 +@include foundation-typography;
 +// #### Compass framework lib ####
 +@import "../../node_modules/compass-mixins/lib/compass/css3";
 +
 +// colors definition:
 +$body-color: #2F2F2F;
 +$title-color: #f0f0f0;
 +$power-color: #ff8000;
 +
 +body {
 +    background: $body-color;
 +}
 +.content {
 +    background: #3B3B3B;
 +    margin-top: 10px;
 +    margin-left: 20px;
 +    margin-right: 20px;
 +    padding: 10px;
 +    @include box-shadow(
 +        rgba(255, 255, 255, 0.1) 0 1px 0,
 +        rgba(0, 0, 0, 0.8) 0 2px 5px 2px);
 +}
 +.sub-content {
 +    background: #262626;
 +    padding: 10px;
 +    margin-bottom: 5px;
 +    border-color: #1E1E1E;
 +    border-radius: 4px;
 +    border-style: solid;
 +    border-width: 1px;
 +    @include box-shadow(
 +        rgba(255, 255, 255, 0.1) 0 1px 0,
 +        rgba(0, 0, 0, 0.9) 0 1px 7px 1px inset);
 +}
 +.title {
 +    color: $title-color;
 +}
 +.django-power {
 +    color: $power-color;
 +}
 +.mybutton {
 +    // @include button(false, #3B3933, #2A2926, #EDEDED, "solid");
 +    @include button();
 +    margin-left: 50px;
 +    @include box-shadow($body-color 2px 2px 15px);
 +    @include box-shadow(
 +        rgba(255, 255, 255, 0.1) 0 1px 0,
 +        rgba(0, 0, 0, 0.8) 0 1px 5px 1px inset);
 +}
 +ul {
 +    color: #C6C6C6;
 +}
 +code {
 +    font-family: menlo, monaco, "andale mono", "courier new", fixed;
 +    border-radius: 4px;
 +    background-color: #212121;
 +    @include box-shadow(
 +        rgba(255, 255, 255, 0.1) 0 1px 0,
 +        rgba(0, 0, 0, 0.9) 0 1px 7px 1px inset);
 +    color: #DADBB1;
 +    border-color: black;
 +}
 +</file>
 +<file JavaScript static/src/js/apps.js>
 +import React, { Component }  from 'react';
 +import ReactDOM from 'react-dom';
 +import '../scss/index.scss';
 +
 +class App extends Component {
 +    render() {
 +        return (
 +            <div className="content">
 +                <h3 className="title">Technical stuff inside this page:</h3>
 +                <div className="sub-content">
 +                    <ul>
 +                        <li>Babel JSX bundler</li>
 +                        <li>ReactJS 'App.js & class App render'</li>
 +                        <li>SASS bundler file</li>
 +                        <li>Foundation Zurb Framework style, ex: typo, button</li>
 +                        <li>Compass SASS Framework, ex:<code>box-shadow</code>
 +                            effects (frame & button)</li>
 +                    </ul>
 +                </div>
 +                <h2 className="django-power">Django powered!</h2>
 +                <a href="about.html" className="mybutton">Learn More</a>
 +            </div>
 +        );
 +    }
 +}
 +export default App;
 +</file>
 +**Rendu:** \\
 +{{:developpement:django:this-is-jsx-react-with-sass-foundation-compass.png?nolink|}} \\
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(compass): Add compass 
 +libraries & mixins."
 +git add -A
 +git commit -m "fix(render): Fix page typo."
 +git add -A
 +git commit -m "fix(render): Fix page typo again."
 +</file>
 +====== Webpack en dehors du dossier static ======
 +2020-05-17\\
 +Pour optimiser le traitement de **//collectstatic//** de **Django**, il est préférable de sortie **webpack** et surtout le dossier **node_modules** du dossier **static**.
 +===== Nouvelle structure de dossiers =====
 +  * A la racine du projet, créer un dossier **//frontend//**:
 +  * Déplacer les fichiers et dossiers suivants dans ce dossier **//frontend//**:
 +    * dist
 +    * node_modules
 +    * package.json
 +    * src
 +    * webpack.config.js
 +    * yarn-error.log
 +    * yarn.lock
 +  * Dans **src** créer le dossier **js** et y déplacer **app.bundle.js**
 +  * Renommer le dossier **dist** en **dist_not_used** qui ne sera plus utilisé, car le JS va être directement **//bundle//** dans le dossier **static**. **dist** devient supprimable. 
 +===== JavaScript =====
 +Modifier la sortie de **webpack.config.js**: **//output: {...}//** est actualiser le chemin **//'../static/js'//**:
 +<file JavaScript frontend/webpack.config.js>
 +const path = require('path')
 +const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 +
 +module.exports = {
 +    entry: {
 +        app: './src/js/index.js'
 +    },
 +    mode: 'development',
 +    watch: true,
 +    devtool: 'source-map',
 +    output: {
 +        filename: '[name].bundle.js',
 +        path: path.resolve(__dirname, '../static/js')
 +    },
 +    module: {
 +        rules: [
 +            {
 +                test: /\.js$/,
 +                exclude: /node_modules/,
 +                use: [
 +                    {
 +                        loader: 'babel-loader',
 +                        options: {
 +                            presets: ['@babel/react']
 +                      }
 +                    }
 +                ],
 +            },
 +            {
 +                test: /\.(scss)$/,
 +                exclude: /node_modules/,
 +                use: [
 +                    MiniCssExtractPlugin.loader,
 +                    'css-loader',
 +                    'sass-loader',
 +                ],
 +            }
 +        ]
 +    },
 +    plugins: [
 +        new MiniCssExtractPlugin({
 +            filename: '../css/index.css',
 +        })
 +    ],
 +    resolve: {
 +        extensions: [
 +            '.js'
 +        ]
 +    }
 +}
 +</file>
 +===== html =====
 +Mettre à jour **index.html** avec <code html><script src="{% static 'js/app.bundle.js' %}"></script></code>
 +<file html template/index.html>
 +{% load static %}
 +<html>
 +    <head>
 +        <title>Demo</title>
 +        <link rel="stylesheet" href="{% static 'css/index.css' %}"/>
 +    </head>
 +    <body>
 +        <div id="root"></div>
 +        <script src="{% static 'js/app.bundle.js' %}"></script>
 +    </body>
 +</html>
 +</file>
 +===== Récap dossiers =====
 +<file bash>
 +tree -L 2                                                 
 +.
 +├── config_prj
 +│   ├── asgi.py
 +│   ├── __init__.py
 +│   ├── settings.py
 +│   ├── urls.py
 +│   ├── views.py
 +│   └── wsgi.py
 +├── db.sqlite3
 +├── frontend
 +│   ├── dist_not_used
 +│   ├── node_modules
 +│   ├── package.json
 +│   ├── src
 +│   ├── webpack.config.js
 +│   ├── yarn-error.log
 +│   └── yarn.lock
 +├── manage.py
 +├── Pipfile
 +├── Pipfile.lock
 +├── reporting
 +│   ├── admin.py
 +│   ├── apps.py
 +│   ├── __init__.py
 +│   ├── migrations
 +│   ├── models.py
 +│   ├── tests.py
 +│   └── views.py
 +├── static
 +│   ├── css
 +│   └── js
 +└── templates
 +    └── index.html
 +</file>
 +**Git:**
 +<file bash>
 +git add -A
 +git commit -m "build(frontend): New static structure without Webpack inside."
 +</file>
 +====== Utilisation ======
 +  * Depuis le dossier **//racine://** du projet
 +<file bash>
 +python manage.py runserver
 +</file>
 +  * Depuis je dossier **//frontend//**
 +<file bash>
 +yarnpkg run webpack
 +</file>