
L'opinion publique a traduit Bootstrap dans la catégorie des frameworks légendaires du passé, mais cela vaut toujours la peine d'être regardé. Bootstrap 4 est un excellent navigateur pour une mise en page sûre et, surtout, un exemple d'approche HTML sur JS pour créer des applications Web, révèle pleinement les capacités existantes de HTML pour la description déclarative de l'interface utilisateur.
Et comment le code du framework JavaScript se développe est également utile pour avoir une idée. L'architecture des plugins jQuery est toujours en cours d'utilisation, mais à partir de la version 4, elle est enveloppée par Rollup dans le package ES6 classes transformé à l' aide de Babel6 . jQuery ne sera probablement pas bientôt du tout - plus à ce sujet plus tard - mais pour l'instant, sur l'exemple de la création de votre propre plugin BsMultiSelect , sur la même pile que Boostrap 4 , les fonctionnalités de développement du framework seront révélées.
Pourquoi " chaque programmeur devrait écrire le sien ... "
" Améliorer le bon seul butin ." Le besoin de comprendre ce que le nouveau Bootstrap a obtenu était le transfert de ses composants vers la nouvelle pile, et combien il est maintenant plus facile de créer des composants de haut niveau. Tout semblait simple: combinez .form-control
, .badge
et .dropdown-menu
et vous pouvez facilement obtenir une multi-sélection ...

Conflit d'architecture depuis la porte
Le plug- in BsMultiSelect résultant n'utilise pas directement le code JS bootstrap.js , mais utilise sa dépendance, popper.js ( framework pop-up vanilla). En effet, le composant déroulant de bootstrap.js doit trouver l'élément dit bascule lors de l'initialisation dans le DOM (dans le cas particulier, c'est un bouton qui ouvre le menu), s'il ne le trouve pas, il se bloque avec une erreur (puisque je crée directement à partir de js, j'ai des "boutons" bien sûr que non). Conclusion: les composants affinés sous "HTML sur JS" ne peuvent pas (ou désavantageusement) être créés directement à partir de JS. Conclusion numéro deux: vous devez programmer des composants personnalisés pour que sous le composant "HTML sur JS", il y ait toujours un composant plus léger de "pure JS". J'ai ce MulitSelect.js complètement effacé non seulement du code mais aussi des styles Bootstrap. MulitSelect.js joue le même rôle pour BsMulitSelect.js, tout comme popper.js pour dropdown.js.
Deux mots sur popper.js
Grande bibliothèque - une fonction. DropDown.js se répète mais fournit une interface complètement limitée (encore une fois, car dans "HTML sur JS", l'API entière n'est pas nécessaire). Popper a un problème plus ouvert que nous ne le souhaiterions. J'ai été déçu que sous IE11, il publie des événements pas comme sous Chrome .
À propos de la transition de l'IFEF aux cours
Le passe-partout standard du plugin jQuery consiste à définir la fonction constructeur dans IIFE . Maintenant, c'est une classe à l'intérieur de IIFE. Ouverture: les anciennes façons fonctionnelles de faire des méthodes privées entrent en conflit avec le lambda ES6, donc elles ont été "abandonnées" dans Bootstrap. Toutes les méthodes sont publiques, tandis que les méthodes pseudo-privées sont préfixées par _ c'est-à-dire undercrore. Je comprends que je me trompe, mais je respecte mes conventions - "méthodes publiques avec une majuscule". Dans tout le reste, BsMultiSelect a créé l'adoption de l'accord du DropDown.js "standard", c'est-à-dire Je voudrais le représenter comme une sorte de passe-partout avec de la viande.
cependant, une autre différence, puisqu'il y a un rollup, j'ai frappé les fichiers .. import $ from 'jquery' import AddToJQueryPrototype from './AddToJQueryPrototype' import MultiSelect from './MultiSelect'
Nouvel accord: le plugin devrait publier le constructeur - afin de ne pas perdre le constructeur dans IIFE. Oui, un IIFE doit rester - personne n'a supprimé la tâche de définir les dépendances de fenêtre, $ et Popper (pour ceux qui "ne peuvent pas entrer dans les modules") de manière standard.
Configurations d'Eslint et Stylelint Linter
Je ne me sentais pas obligé de suivre les règles draconiennes pour styliser le code Bootstrap. Certes, ils écrivent dans un environnement qui les aide à définir des espaces et la rigueur du contrôle des sources est très bonne, mais il est difficile pour moi d'écouter chaque seconde la douleur du linter dans VS Code. Lorsque vous écrivez votre propre plugin, les règles peuvent et doivent être considérablement assouplies.
Eslint, stylelint peut ne pas sortir trop souvent, mais il n'y a aucun désir de regarder les nouvelles règles. À tous égards, cette réalisation m'énerve davantage.
Code d'organisation et cumul
Le code redistribuable ES6 de Bootstrap est empaqueté par cumul en deux versions: bootstrap.js autonome et bundle bootstrap.bundle.js - ce dernier inclut popper.js.
L'auteur de rollup.config.js a des instincts étrangers à moi. Toute cette transformation de configuration par push et pop, selon la version requise de autonome ou de bundle, semble élaborée et intimidante, heureusement, pour écrire un plug-in, vous n'avez besoin que d'un seul type de bundle "autonome" et je n'ai pas à prouver que je peux faire mieux.
La version autonome de Bootstrap est également indiquée dans le champ principal du package, c'est-à-dire Les dépendances npm sont résolues dans le même fichier que les utilisateurs chargent via <script>
. Ce n'est pas une solution sans ambiguïté, mais mon plugin BsMultiSelect a suivi le même chemin. Dans ce cas, les assistants babel peuvent être inclus dans le plugin , malgré le fait qu'ils soient également inclus dans bootsrap.js. La duplication n'est en quelque sorte pas correcte ...
Ce qui est intéressant, c'est que Bootstrap a une configuration parallèle sous jspm - le chargeur de module du navigateur natif ES et son champ principal est déjà du code distant propre, 12 composants qui ne sont pas groupés, mais stockés séparément dans le répertoire js / dist. Ici, chaque fichier inclut des assistants babel. Jspm est maintenant à la croisée des chemins, donc en créant BsMultiselect Ignore it.
Et pourtant, il est intéressant de demander aux connaisseurs, jspm va-t-il lever les 12 aides auxiliaires dupliquées dans le navigateur?
Un gros plus du cumul a été découvert - ses packages sont lisibles, contrairement à webpack.
Bootsrap 4 utilise Babel 6 et le plugin BsMultiSelect Babel 7
BsMultiSelect a facilement migré vers la version bêta de Babel 7 en utilisant le plugin rollup-babel mis à jour (également en version bêta). Cela vaut la peine de passer à Babel 7 maintenant à cause du nouveau @babel/preset-env
(la configuration du transpilateur "sur quels navigateurs le code s'exécutera"). En utilisant Internet seul, il est devenu assez difficile de comprendre le fonctionnement des préréglages ES6, ils ont connu une longue évolution et de nombreuses configurations obsolètes se sont accumulées. Mieux vaut miser Babel 7 + @babel/preset-env
tout de suite
Néanmoins, les erreurs bêta de babel n'ont pas dû attendre longtemps: [... nodeList] a été transpercé dans nodeList.concat (). Je n'ai pas compris pendant longtemps, la traduction du code en appels jquery (c'est toujours nécessaire, mais plus à ce sujet plus tard) a résolu le problème. Demandez: «Pourquoi alors Babel si vous ne traitez pas avec lui?», La réponse: «importations et lambda».
Aspects pratiques
Bootstrap 4 et son plugin (comme tout code js) ont deux options de téléchargement vers le navigateur: via script / style (créer une "page"), et via le nœud d'assemblage / webpack (créer une "application", donc je vais continuer ces deux en principe, des situations très différentes et dénotent: «page» et «application»).
Pour la page et pour l'application, le même "fichier de distribution" Bootstrap sera utilisé. Ce n'est pas une solution évidente et pas la seule (par exemple, un code différent est utilisé pour jspm
et pour les tests jspm
), mais lors de la création de votre propre plugin, il ne reste plus qu'à suivre cette convention, en espérant son optimalité.
Trouver un équilibre entre la satisfaction de deux besoins en utilisant le même code pour deux options de téléchargement différentes: «pages» et «applications» est la principale tâche architecturale du développeur du plug-in.
Après tout, le plugin Bootstrap peut également être créé ad hoc , directement dans votre application. Dans ce cas, vous pouvez écrire le code du plug-in avec tous les plaisirs: les polyphiles et l'accès aux variables SASS du schéma. Cependant, lors de la réutilisation, il sera nécessaire de transférer le plugin vers son propre package npm, les plaisirs ci-dessus entrent dans la catégorie des problèmes: vous perdez l'accès aux variables SASS et vous devez garder à l'esprit les créateurs des «pages» qui connectent le plugin via un script (où sont mes polyfichiers?).
Accès aux variables de style SASS Bootstrap 4
Je voudrais écrire des classes / sélecteurs css Bootstrap pour écrire le plugin. Dans ce cas, lors de la personnalisation du thème Bootstrap, vous pouvez vous attendre à ce que le plugin s'adapte sans effort supplémentaire.
Pour un plugin auto-publié, il n'y a pas d'accès aux variables SASS.
Classes / sélecteurs CSS existants - ne couvrent pas tous les styles nécessaires pour BsMutliSelect, par exemple, vous avez besoin de min-height
pour ul.form-control
, lorsque dans bootstrap.css il n'y a qu'un sélecteur css avec une hauteur pour input.form-control
- vous ne pouvez pas l'appliquer pour ul
. Les autres classes / sélecteurs existants apportent beaucoup de styles superflus: que se passe-t-il si vous souhaitez affecter, par exemple, la couleur de .form-control à un élément sans affecter une classe .form-control
? Cela ne fonctionnera pas car il n'existe pas de classe telle que .input-color
dans laquelle la variable $ input-color serait publiée «séparément» de tout.
De plus, il n'est pas possible de suivre les décisions de l'équipe Bootstrap: ils n'ont pas un tel problème, s'ils en ont besoin - ils créent une classe / sélecteur CSS avec la variable souhaitée et opèrent dessus. Si vous voulez débattre, vous devrez expliquer avec Mark Otto , dans l'équipe BS, il y a un niveau de prise de décision anormalement élevé, même pour des changements cosmétiques dans les sélecteurs CSS, si les demandes entrent dans la catégorie "offre".
Je propose la solution suivante.
Pour une page (création d'un plug-in via un script
), vous devez supporter l'inaccessibilité des variables. Mais il n'est pas nécessaire de proposer de traiter avec CSS - les variables inaccessibles peuvent être proposées pour être personnalisées via les paramètres js, car elles ne sont pas nombreuses (et toutes ne sont pas modifiées par un schéma). Pour BsMultiSelect, les problèmes étaient: couleur désactivée, couleur d'entrée, ombre de contrôle focalisée (etc. seulement 10 styles, la plupart changent rarement de schémas) ...
D'une part, c'est une déclaration de tous les styles dont dépend le plugin ... $("select[multiple='multiple']").bsMultiSelect({ selectedPanelDefMinHeight: 'calc(2.25rem + 2px)',
Mais pour une application utilisant SASS et le collecteur, vous pouvez proposer de copier vous-même BsMultiSelect.scss et d'y corriger le chemin d'accès à votre _variables.scss. Ainsi, le plugin "recevra" les variables variables.
Tout au long de CSS ... $("select[multiple='multiple']").bsMultiSelect({ useCss: true });
Ces deux méthodes sont écrites explicitement dans mon code JS, via deux «adaptateurs». BsMultiSelect est en fait deux plugins en un. L'un qui fonctionne avec des styles via des variables js, l' autre délègue ce travail css.
Dans le même temps, je dois dire directement que travailler avec CSS peut être nécessaire même si le transfert de styles personnalisés via les paramètres JS a été utilisé, simplement parce que les auteurs des schémas font généralement leur travail de manière très approximative. Ou étrange. Par exemple, le schéma Skethy pour une raison quelconque a décidé que le menu n'a pas besoin d'un effet de survol. Les caractéristiques doivent être déposées.
Mais avec l'exemple sommaire, j'espère que vous pouvez voir comment le plug-in s'est adapté au circuit lourd assez facilement (il a fallu surcharger les valeurs de seulement trois styles via les paramètres js).
adaptation au schéma par js $("select[multiple='multiple']").bsMultiSelect({ selectedPanelFocusBoxShadow:"0px 0px 0px 0.2rem rgba(51,51,51,0.25)", selectedPanelFocusBorderColor:"#333", selectedPanelDisabledBackgroundColor: "#f7f7f9" });

C'est le maximum qui peut être atteint en utilisant les classes CSS "standard" .bage
, .form-control
, .close
, etc. Presque tout adapté au schéma, mais pas tout.
C'est dommage, bien sûr, que vous ne puissiez pas vous éloigner de ces trois paramètres, toutes les variables de style de schéma ne sont pas accessibles via les sélecteurs / classes css (je mens, vous pouvez laisser si vous pouvez copier BsMultiSelect.scss pour vous-même et y apporter les variables de circuit, mais cela ne satisfait pas complètement , comme toutes les décisions qui commencent par les mots «copie à vous-même»).
Cliquez ici: https://dashboardcode.imtqy.com/BsMultiSelect/indexsketchy.html
Polyfill's
Dans le scénario «J'écris un plugin ad hoc à l'intérieur de l'application» - vous utiliserez @babel/polyfill
sans aucun problème, et patchez le DOM polyfill.io car à l'intérieur de votre application il est déjà là.
Lorsqu'un plugin est déplacé vers un module npm externe, toute la joie disparaît car les utilisateurs de Bootstrap n'ont pas décidé de satisfaire les longues listes de polyfills requis dans la documentation.
Solution: tout ce que babel ne transposera pas mais laissera aux polyphiles, l'empêchera de le faire, grinçant des dents, pour se convertir en appels jQuery (par exemple, Node.closest dans $ .closest). Cette approche est adoptée dans Bootstrap 4 lui-même et il s'agit évidemment d'une lutte contre le gonflement. Surprise jQuery est un polyfill.
Je suis d'accord que la programmation avec Babel avec un œil sur CanIUse.com et MDN.com n'est pas amusante. Et le code est maladroit (pour moi).
Ici, il est nécessaire de souligner à nouveau la situation d'en haut. Bootstrap utilise deux bibliothèques jQuery et popper.js. Popper.js est un framework double vanilla, il n'a pas de polyfills babel, jQuery ou externes, tout seul. JQuery est emballé par grunt utilisant déjà babel, mais en quelque sorte comme par magie sans ses polyfills et helper's. Un plug-in Bootstrap tiers (comme BsMultiSelct) utilise Babel 7. Votre produit peut encore utiliser autre chose. Il n'y a pas de plate-forme polyphile unique, une duplication de code multiple est attendue, il y a quatre implémentations du même plus proche chargées dans le navigateur. Mais on ne peut rien y faire.
Si vous avez néanmoins utilisé des polyfichiers lors de la création de votre propre plugin, vous devez vous rappeler que si l'application a des scripts en ligne (c'est-à-dire <script>$( function() {/*..*/}) </script>
) alors vous n'aurez qu'à télécharger les polyfichiers de manière synchrone (sinon le code en ligne peut commencer son exécution avant le moment où le plugin est chargé). C'est-à-dire par exemple, webpack-polyfill-injector (l'injecteur de polyphil le plus riche que je connaisse) que je dois contrôler pour qu'il ne décide pas de charger les polyphiles de manière asynchrone (comportement par défaut).
Pas de jQuery
jQuery semble quelque peu toxique, rivalisant avec et obscurcissant Babel / ES6, mais ce n'est pas éternel. Il existe une branche v4-sans-jquery , elle est déjà dans la requête de pool, elle prévoit de sortir la version 4.3 de bootstrap-nojquery
c . Auparavant, l'espace de noms des événements était appelé le plus gros problème de rejet de jquery, bien qu'il soit évident que vous pouvez écrire sans eux (BsMultiSelect l'a fait sans). Apparemment décidé.
Il a également été annoncé qu'à partir de la version 4.3, il sera possible de charger séparément les composants d'origine dans le navigateur (uniquement pour le scénario "application"). Les composants d'origine deviendront-ils alors "comme BsMultiSelect "? Non. Si l'équipe BS a besoin de certaines variables SASS, elle fera des classes / sélecteurs CSS pour elle-même et les opérera à partir de JS ("CSS fonctionnel"). Les créateurs de fonctionnalités personnalisées ne sont pas disponibles.
La transition possible de sass à post-css https://github.com/twbs/bootstrap/projects/11 dans la 5ème version ne change fondamentalement rien. Ou change tout: "JS sur HTML".
Bootstrap 5 devra mettre en place des recommandations sur la façon de s'intégrer dans les polyfichiers Babel, et comment patcher le DOM. Ici, la prévision est plus ou moins claire: des assemblages complètement différents seront proposés aux créateurs de pages et aux créateurs d'applications.
Résumé
Pendant que vous écrivez des composants Bootstrap 4 sur Babel en utilisant la méthode ad hoc sans penser à la réutilisation, ce qui signifie des polyphiles, et où trouver les variables de style, vous ne connaissez pas le chagrin.
Mais si vous faites du plugin un package npm séparé - et avec le désir de prendre une décision dans l'esprit de Bootstrap 4 lui-même, le plaisir devient moins, vous pensez plus souvent et plus longtemps. Vous devez probablement décider immédiatement qui sont vos utilisateurs et proposer différentes versions, l'une pour ceux qui construiront l'application en bundles, l'autre pour l'écriture de pages, c'est-à-dire chargement du script du plugin.