Y a-t-il des bibliothèques pour JavaScript dans le navigateur qui offrent la même flexibilité/modularité/facilité d'utilisation que le require
de Node?
Pour donner plus de détails : la raison pour laquelle require
est si bon, c'est qu'il :
- Permet de charger dynamiquement du code depuis d'autres emplacements (ce qui est stylistiquement mieux, à mon avis, que de lier tout votre code dans le HTML)
- Fournit une interface cohérente pour construire des modules
- Il est facile pour les modules de dépendre d'autres modules (je pourrais écrire, par exemple, une API qui nécessite jQuery afin de pouvoir utiliser
jQuery.ajax()
) - Le javascript chargé est isolé, ce qui signifie que je pourrais charger avec
var dsp = require("dsp.js");
et je pourrais accéder àdsp.FFT
, ce qui n'interférerait pas avec ma variable localevar FFT
Je n'ai pas encore trouvé de bibliothèque qui le fait efficacement. Les contournements que j'ai tendance à utiliser sont les suivants :
-
coffeescript-concat -- il est assez facile de requérir d'autres js, mais vous devez le compiler, ce qui signifie qu'il est moins adapté pour un développement rapide (par exemple, la construction d'API en mode test)
-
RequireJS -- C'est populaire, simple et résout 1-3, mais le manque de portée est un vrai casse-tête (je pense que head.js est similaire en ce sens qu'il manque de portée, bien que je n'ai jamais eu l'occasion de l'utiliser. De même, LABjs peut charger et
.wait()
atténue les problèmes de dépendance, mais il ne gère toujours pas la portée)
De ce que je peux dire, il semble qu'il y ait de nombreuses solutions pour le chargement dynamique et/ou asynchrone de javascript, mais elles tendent à avoir les mêmes problèmes de portée que le simple chargement de js à partir du HTML. Plus que tout, j'aimerais trouver un moyen de charger du javascript qui ne pollue pas du tout l'espace de noms global, mais qui me permet quand même de charger et utiliser des bibliothèques (comme le fait le require
de Node).
MISE À JOUR 2020: Les modules sont désormais standard en ES6, et à partir de mi-2020, ils sont nativement pris en charge par la plupart des navigateurs. Les modules prennent en charge le chargement synchrone et asynchrone (en utilisant les promesses). Ma recommandation actuelle est que la plupart des nouveaux projets devraient utiliser des modules ES6 et utiliser un transpileur pour revenir à un seul fichier JS pour les navigateurs obsolètes.
En tant que principe général, la bande passante est aujourd'hui généralement beaucoup plus large que lorsque j'ai posé cette question à l'origine. Ainsi, en pratique, vous pouvez raisonnablement choisir d'utiliser toujours un transpileur avec des modules ES6 et de vous concentrer sur l'efficacité du code plutôt que sur le réseau.
ÉDITION PRÉCÉDENTE (ou si vous n'aimez pas les modules ES6): Depuis que j'ai écrit ceci, j'ai largement utilisé RequireJS (qui a maintenant une documentation beaucoup plus claire). RequireJS était vraiment le bon choix à mon avis. J'aimerais clarifier comment fonctionne le système pour les personnes aussi perdues que je l'étais:
Vous pouvez utiliser require
dans le développement quotidien. Un module peut être n'importe quoi retourné par une fonction (typiquement un objet ou une fonction) et est isolé en tant que paramètre. Vous pouvez également compiler votre projet dans un seul fichier pour le déploiement en utilisant r.js
(en pratique, c'est presque toujours plus rapide, même si require
peut charger des scripts en parallèle).
La principale différence entre RequireJS et le require
de style node comme browserify (un projet cool suggéré par tjameson) est la manière dont les modules sont conçus et requis:
- RequireJS utilise AMD (Async Module Definition). En AMD,
require
prend une liste de modules (fichiers javascript) à charger et une fonction de rappel. Lorsqu'il a chargé chacun des modules, il appelle le rappel avec chaque module en tant que paramètre du rappel. Ainsi, c'est vraiment asynchrone et donc bien adapté au web. - Node utilise CommonJS. En CommonJS,
require
est un appel bloquant qui charge un module et le renvoie comme un objet. Cela fonctionne bien pour Node car les fichiers sont lus à partir du système de fichiers, ce qui est assez rapide, mais cela fonctionne mal sur le web car le chargement synchrone de fichiers peut prendre beaucoup plus de temps.
En pratique, de nombreux développeurs ont utilisé Node (et donc CommonJS) avant même de voir AMD. De plus, de nombreuses bibliothèques/modules sont écrites pour CommonJS (en ajoutant des choses à un objet exports
) plutôt que pour AMD (en retournant le module de la fonction define
). Par conséquent, de nombreux développeurs issus de Node veulent utiliser des bibliothèques CommonJS sur le web. C'est possible, car le chargement à partir d'une balise </code> est bloquant. Des solutions comme browserify prennent des modules CommonJS (Node) et les enveloppent pour que vous puissiez les inclure avec des balises de script.</p> <p>Par conséquent, si vous développez votre propre projet multi-fichiers pour le web, je recommande fortement RequireJS, car c'est vraiment un système de module pour le web (bien que, pour être honnête, je trouve AMD beaucoup plus naturel que CommonJS). Récemment, la distinction est devenue moins importante, car RequireJS permet désormais essentiellement d'utiliser la syntaxe CommonJS. De plus, RequireJS peut être utilisé pour charger des modules AMD dans Node (bien que je préfère <a href="https://github.com/ajaxorg/node-amd-loader" rel="noreferrer">node-amd-loader</a>).</p></x-turndown>