Introduction
- L'objectif de cette section est de voir comment architecturer son code.
- Côté front, on verra :
-
Les différentes façons de découper son CSS
-
Comment différents scripts peuvent être intégrés dans une page
-
À quoi ressemblent les architectures classiques côté front
- Côté serveur, on verra :
-
Comment construire une API en fonction des ressources qu'elle cible
-
À quoi peut ressembler un serveur de fichiers
-
Comment intégrer des micro-services
CSS - Concepts de base
-
Il existe de nombreuses stratégies pour écrire du CSS propre (OOCSS, BEM, SMACSS, ITCSS, Atomic, ...)
-
Article présentant
les plus connues
-
Ces différentes stratégies se basent pour la plupart sur les mêmes concepts :
- Ne pas utiliser de sélecteurs trop longs
main section article .content div:nth-child(2) p>a span {}
- Séparer les propriétés qui ne sont pas communes
.button { ... }
.button-primary { ... }
- Appliquer des conventions de nommage
<img class="media__image" src="" alt="" >
- Isoler les composants
CSS - Plusieurs fichiers
- Vous pouvez placer votre CSS dans plusieurs fichiers, toutes les propriétés s'appliqueront quand même
<head>
<link rel="stylesheet" href="style1.css">
<link rel="stylesheet" href="style2.css">
</head>
- Vous pouvez conditionner le chargement de vos CSS
<head>
<link rel="stylesheet" href="style1.css">
<link rel="stylesheet" href="style2.css" media="screen and (max-width: 600px)" >
</head>
- Le découpage peut être technique ou fonctionnel :
- Un fichier par composant
- Un fichier par résolution
- Un fichier pour les règles génériques et plusieurs pour les éléments spécifiques
- ...
JS - Front
-
JS permet de faire de l'orienté objet
-
Toutes les variables chargées par une balise script sont utilisables dans les scripts suivants
<script>let a = 3;</script>
...
<script>console.log(a+5);</script>
-
Il est possible d'utiliser le système d'import-export des
modules :
- Le mot-clé export permet d'exporter vos fonctions, variables (définies avec let, var ou const) et vos classes.
- Le mot-clé import permet de charger un module JS
- Vous pouvez utiliser la déstructuration pour simplifier vos imports
Web Components
- JS inclut nativement une API appelée
Web Components permettant de créer des composants réutilisables
- Cette API se base sur 3 concepts :
- En cumulant ces 3 concepts, on obtient du code isolé et réutilisable.
Créer un Web Component (1/2)
- Créer une balise personnalisée se fait grâce à customElements :
customElements.define("ma-balise", MonComposant);
- La classe chargée doit étendre une classe d'un élément HTML natif :
class MonComposant extends HTMLElement {
constructor() {
super();
...
}
}
- Dans le constructeur, il suffit ensuite de créer un shadow DOM :
let shadowRoot = this.attachShadow({ mode: "open" });
- Et de lui attacher un clone de votre template HTML :
shadowRoot.appendChild(templateContent.cloneNode(true));
Créer un Web Component (2/2)
- Pour créer un template, 2 solutions :
- Directement dans le constructeur de la classe
- Dans un fichier séparé, qu'il faudra fetch
- Dans tous les cas :
- On utilise la balise <template>
- On peut, à l'intérieur, utiliser des balises <slot> pour du contenu enfant
- On transforme le texte en DOM :
let templateContent = new DOMParser().parseFromString(htmlContent, "text/html").querySelector("template").content;
- Et on le clone quand on l'ajoute au Shadow Root:
shadowRoot.appendChild(templateContent.cloneNode(true));
Utiliser un Web Component
- Pour afficher le composant, il suffit d'utiliser la balise créée avec customElements :
<body>
<ma-balise>...</ma-balise>
<script src="link/to/myComponent.js" defer>...</script>
<body>
- On peut lui passer des arguments :
<ma-balise name="foo">...</ma-balise>
- Qu'on récupère dans la classe du composant :
class MonComposant extends HTMLElement {
static get observedAttributes() { return ["name"]; }
attributeChangedCallback(key, oldValue, newValue) { this[key] = newValue; }
}
- Pour remonter une donnée au parent, on peut utiliser des évènements personnalisés :
let event = new CustomEvent("myEventName", JSONContent);
document.dispatchEvent(event);