Quelle est la différence entre utiliser Require.JS et créer simplement un <script>
élément dans le DOM?
Ma compréhension de Require.JS est qu'il offre la possibilité de charger des dépendances, mais cela ne peut-il pas simplement être fait en créant un <script>
élément qui charge le fichier JS externe nécessaire?
Par exemple, supposons que j'ai la fonction doStuff()
, qui nécessite la fonction needMe()
. doStuff()
se trouve dans le fichier externe do_stuff.js
, tandis que needMe()
dans le fichier externe need_me.js
.
En procédant de la manière Require.JS:
define(['need_me'],function(){
function doStuff(){
//do some stuff
needMe();
//do some more stuff
}
});
Pour ce faire, créez simplement un élément de script:
function doStuff(){
var scriptElement = document.createElement('script');
scriptElement.src = 'need_me.js';
scriptElement.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(scriptElement);
//do some stuff
needMe();
//do some more stuff
}
Les deux fonctionnent. Cependant, la deuxième version ne m'oblige pas à charger toute la bibliothèque Require.js. Je ne vois pas vraiment de différence fonctionnelle ...
la source
Réponses:
Voici le bel article sur ajaxian.com expliquant pourquoi l'utiliser:
RequireJS: chargement JavaScript asynchrone
la source
Dans votre exemple, vous créez la balise de script de manière asynchrone, ce qui signifie que votre
needMe()
fonction sera appelée avant que le fichier need_me.js ne termine le chargement. Cela entraîne des exceptions non interceptées où votre fonction n'est pas définie.Au lieu de cela, pour que ce que vous suggérez fonctionne réellement, vous devez faire quelque chose comme ceci:
On peut soutenir qu'il peut être préférable ou non d'utiliser un gestionnaire de packages tel que RequireJS ou d'utiliser une stratégie purement JavaScript comme démontré ci-dessus. Bien que votre application Web puisse se charger plus rapidement, l'appel des fonctionnalités et des fonctionnalités sur le site serait plus lent car cela impliquerait d'attendre le chargement des ressources avant que cette action puisse être effectuée.
Si une application Web est conçue en tant qu'application d'une seule page, sachez que les utilisateurs ne rechargeront pas la page très souvent. Dans ces cas, tout précharger aiderait à rendre l'expérience plus rapide alors qu'en réalité utilisez l'application. Dans ces cas, vous avez raison, on peut simplement charger toutes les ressources simplement en incluant les balises de script dans l'en-tête ou le corps de la page.
Cependant, si vous créez un site Web ou une application Web qui suit le modèle plus traditionnel où l'on passe d'une page à l'autre, provoquant le rechargement des ressources, une approche de chargement différé peut aider à accélérer ces transitions.
la source
Quelques autres raisons très pointues pour lesquelles l'utilisation de RequireJS a du sens:
Tiré des commentaires de rmurphey ici dans ce Gist .
Les couches d'abstraction peuvent être un cauchemar à apprendre et à s'adapter, mais quand cela sert un objectif et le fait bien, cela a du sens.
la source
Voici un exemple plus concret.
Je travaille dans un projet avec 60 fichiers. Nous avons 2 modes de fonctionnement différents.
Chargez une version concaténée, 1 gros fichier. (Production)
Charger les 60 fichiers (développement)
Nous utilisons un chargeur, nous n'avons donc qu'un seul script dans la page Web
Par défaut, le mode n ° 1 (chargement du seul gros fichier concaténé). Pour exécuter le mode # 2 (fichiers séparés), nous définissons un indicateur. Ça pourrait être n'importe quoi. Une clé dans la chaîne de requête. Dans cet exemple, nous faisons simplement ceci
loader.js ressemble à quelque chose comme ça
Le script de construction est juste un fichier .sh qui ressemble à ceci
etc...
Si un nouveau fichier est ajouté, nous utiliserons probablement le mode # 2 puisque nous faisons du développement, nous devons ajouter une
injectScript("somenewfile.js")
ligne à loader.jsEnsuite, pour la production, nous devons également ajouter somenewfile.js à notre script de construction. Une étape que nous oublions souvent et que nous recevons ensuite des messages d'erreur.
En passant à AMD, nous n'avons pas à modifier 2 fichiers. Le problème de la synchronisation de loader.js et du script de construction disparaît. En utilisant
r.js
ouwebpack
il peut simplement lire le code pour construirelarge-concantinated.js
Il peut également gérer les dépendances, par exemple nous avons eu 2 fichiers lib1.js et lib2.js chargés comme ceci
lib2 a besoin de lib1. Il contient du code qui fait quelque chose comme
Mais comme les scripts injectés sont chargés de manière asynchrone, il n'y a aucune garantie qu'ils se chargeront dans le bon ordre. Ces 2 scripts ne sont pas des scripts AMD mais en utilisant require.js nous pouvons lui dire leurs dépendances
I notre module qui utilise lib1 nous faisons ceci
Maintenant, require.js va injecter les scripts pour nous et il n'injectera pas lib2 tant que lib1 n'aura pas été chargé puisque nous lui avons dit que lib2 dépend de lib1. Il ne démarrera pas non plus notre module qui utilise lib1 tant que lib2 et lib1 ne seront pas chargés.
Cela rend le développement agréable (pas d'étape de construction, pas de souci pour l'ordre de chargement) et cela rend la production agréable (pas besoin de mettre à jour un script de construction pour chaque script ajouté).
En prime, nous pouvons utiliser le plugin babel de webpack pour exécuter babel sur le code des anciens navigateurs et encore une fois, nous n'avons pas non plus à maintenir ce script de construction.
Notez que si Chrome (notre navigateur de choix) a commencé à prendre en charge
import
pour de vrai, nous passerions probablement à cela pour le développement, mais cela ne changerait vraiment rien. Nous pourrions toujours utiliser webpack pour créer un fichier concaténé et nous pourrions l'utiliser pour exécuter babel sur le code pour tous les navigateurs.Tout cela est gagné en n'utilisant pas de balises de script et en utilisant AMD
la source