Maison >interface Web >js tutoriel >Une exploration approfondie des méthodes de modularisation et de chargement de seajs_Seajs

Une exploration approfondie des méthodes de modularisation et de chargement de seajs_Seajs

WBOY
WBOYoriginal
2016-05-16 16:04:21927parcourir

Depuis que je l'utilise, j'ai découvert le code source de seajs. Voici ma compréhension des questions suivantes :

1. Comment la méthode require(XXX) de Seajs implémente-t-elle le chargement du module ?

2. Pourquoi avez-vous besoin de précharger ?

3. Pourquoi avez-vous besoin d'outils de création ?

4. Quelles sont les différences entre le code avant et après la construction, et pourquoi faites-vous cela ?

Question 1 : Comment la méthode require(XXX) de seajs implémente-t-elle le chargement du module ?

La logique du code est plutôt alambiquée. La compréhension du code source est placée à la fin de l'article. Nous passons ici brièvement en revue la logique de chargement du module :

1. Depuis l'entrée de la méthode seajs.use, commencez à charger le module utilisé.

2. Le module utilisé ne doit pas exister dans le cache du mod pour le moment. Seajs crée un nouveau mod et lui donne un statut initial.

3. Exécutez la méthode mod.load

4. Après un peu de logique, accédez à la méthode seajs.request et demandez le fichier du module. Une fois le module chargé, la méthode de définition est exécutée.

5. La méthode de définition analyse et extrait les modules dépendants du module et les enregistre. La fabrique est mise en cache mais pas exécutée.

6. Les modules dépendants du module sont à nouveau chargés. S'il reste des modules dépendants, le chargement continue. Jusqu'à ce que tous les modules dépendants soient chargés.

7. Une fois tous les modules chargés, exécutez le rappel de la méthode use.

8. La logique interne du module est exécutée à partir du rappel. La méthode require n'est exécutée que pendant ce processus.

Question 2 : Pourquoi le préchargement est-il nécessaire ?

Nous voyons que la méthode seajs.use exécute réellement le rappel une fois que tous les modules dépendants ont été chargés. On peut comprendre qu'avant l'exécution du code de logique métier, tous les codes de modules dépendants doivent être préchargés. Alors pourquoi y a-t-il une telle logique qui doit être préchargée en premier ?

La réponse réside dans la méthode d'exécution de la méthode require qui fait référence à d'autres méthodes de module dans le code logique :

var mod = require(id);

Cette syntaxe détermine que l'acquisition du mod est un processus d'exécution synchrone. Si le code du module n'a pas été préchargé auparavant, il ne peut être implémenté qu'en utilisant la méthode de rappel de chargement asynchrone, alors toute la logique d'exécution de Seajs sera complètement C'est autre chose. En raison de l'asynchronie, vous ne comprendrez pas l'ordre d'exécution des modules et la logique deviendra difficile à contrôler.

Question 3 : Pourquoi avez-vous besoin d'outils de build ?

Vous pouvez voir que chaque module dépendant est chargé séparément avant la construction. Cela générera trop de requêtes de modules, ce qui nuira aux performances de chargement des pages. Les outils de construction sont essentiellement conçus pour résoudre le problème du chargement combiné des modules.

Question 4 : Quelles sont les différences entre le code avant et après la construction, et pourquoi faisons-nous cela ?

Que fait exactement l'outil de construction ? Nous disons qu'il s'agit essentiellement de résoudre le problème du chargement par fusion de code, donc ce qu'il fait est simplement de fusionner divers fichiers de module en un seul fichier ?

Bien sûr que non. Testez-le. Si vous fusionnez simplement plusieurs fichiers de module en un seul fichier, vous constaterez que ce fichier ne peut pas être exécuté normalement.

La raison réside dans la mise en œuvre de la méthode de définition.

Seajs recommande de transmettre uniquement le paramètre factory dans la méthode de définition lors de la définition d'un module. En repensant à la méthode de définition, lorsqu'aucun identifiant (temporairement équivalent à l'url du module) n'est transmis, la méthode getCurrentScript() sera utilisée pour obtenir le chemin url du fichier du module en cours d'exécution, puis ce chemin sera être utilisé comme valeur clé avec le module lui-même CachedMods. Le point clé ici est que le mécanisme de mise en cache des modules dans l'ensemble du Seaj s'appuie en fait sur l'URL de chaque module comme clé de cache. La méthode require(id) passe finalement par la valeur de la clé URL. La méthode require(id) utilise finalement la valeur de la clé URL pour trouver le module correspondant dans cachedMods. Cette valeur clé ne peut pas être répétée et ne peut pas commettre d'erreurs, sinon la relation correspondante entre les modules sera confuse. Si plusieurs fichiers de module a, b et c sont simplement fusionnés dans un fichier cible x, getCurrentScript() ne peut obtenir que le chemin de x, et les valeurs clés des trois modules ne peuvent pas être distinguées, et l'exécution se poursuivra définitivement faux.

Donc, si vous souhaitez fusionner plusieurs fichiers de modules ensemble, vous devez spécifier l'URI de chaque module. Autrement dit, la méthode de définition doit transmettre le paramètre id. Lorsque l'identifiant est transmis, seajs convertira l'identifiant en URL et l'utilisera comme clé de cache.

Si seuls id et factory sont passés, c'est-à-dire definition(id, factory), alors deps = undefined, la méthode de définition exécutera la méthode parseDependencies(factory.toString()) pour extraire les modules dépendants dans l'usine, puis il ira analyser le chemin du module et charger la logique de chaque module séparément en ligne. À ce stade, le sens du chargement combiné est perdu.

Donc, pour le chargement par fusion, la méthode de définition doit transmettre correctement les trois paramètres id, deps et factory pour s'exécuter correctement.

La méthode dite de définition du module CMD de Seajs encourage tout le monde à transmettre un seul paramètre, l'usine, pendant la phase d'écriture du module, et les deux autres paramètres sont générés lors de la phase ultérieure de construction du code. Ce qui précède explique pourquoi ces deux paramètres sont nécessaires après la construction.

Quant à la raison pour laquelle il est préconisé de passer uniquement par l'usine lors de la définition d'un module, je pense que c'est principalement parce que les paramètres id et deps transmis manuellement sont extrêmement sujets aux erreurs et peu pratiques à maintenir. Les outils peuvent améliorer l’efficacité et garantir des paramètres corrects.

Pièce jointe : Compréhension de la logique principale du code de seajs.

Remarque : la version du code source est Sea.js 2.3.0

1. Voyons d'abord ce que fait la méthode de définition

Module.define = fonction (id, deps, usine)

La méthode de définition prend en charge trois paramètres. Parmi eux, l'identifiant et les dépôts sont facultatifs. requis en usine. Le code est contrôlé par la logique suivante :

Mais deps est en fait nécessaire, car seajs doit savoir de quels modules dépend chaque module, sinon il ne peut pas être chargé.

Ainsi, lorsque l'usine est une fonction et que deps n'est pas activement transmis, vous devez utiliser la méthode parseDependencies pour analyser les modules dépendants dans l'usine.

La principale chose que fait la méthode parseDependencies est d'utiliser une expression régulière pour extraire le XXX dans tous les require(XXX) du corps de la fonction. Il s'agit de tous les modules dont dépend cette fonction.

La méthode en elle-même n'est pas compliquée, mais cette expression régulière n'est pas simple :

Après avoir analysé les deps, stockez la définition du module dans le cache :

Notez que nous constaterons que la méthode de définition analyse uniquement les modules et stocke les modules, et n'exécute pas les modules.

2. L'exécution réelle du module se fait dans la méthode require. Examinons ensuite require.

En bref, la méthode require consiste à trouver le module correspondant dans le cache du module où la définition de définition est stockée en fonction de l'identifiant, et à l'exécuter pour obtenir la méthode renvoyée par la définition du module :

Dans toute cette grande étape, il y a une étape très critique qui doit être expliquée en détail :

Module.get(require.resolve(id)).

Lorsque vous avez besoin d'un module, vous devez d'abord trouver le module. La méthode Module.get joue ce rôle.

S'il n'y a pas de cachedMods, créez un nouveau module et mettez-le en cache dans cachedMods :

Les méthodes de définition et de rquire ne semblent pas compliquées. La raison principale de Seajs est que la logique de chargement du module est un peu compliquée.

3. Le véritable point d'entrée pour l'exécution de Seajs est la méthode d'utilisation :

Grâce à la méthode use, le chargement et l'exécution du module sont déclenchés à partir des identifiants ici.

Vous pouvez voir que le point clé du chargement est dans la méthode mod.load.

Le code de la méthode de chargement est un peu long. La logique principale est de déterminer si l'état actuel du mod est chargé ou en cours de chargement.

Dans la fonction confort du Module, nous pouvons voir que la valeur par défaut du statut est 0.

Les nouveaux modules qui n'ont pas été chargés sont donc ici : mod.status = STATUS.LOADING L'état est défini sur chargement et la logique de chargement ultérieure est exécutée.

L'étape suivante consiste à obtenir les URL des dépendances du module

Méthode mod.resolve :

La méthode Module.resolve convertit essentiellement les chemins relatifs, les chemins configurés, les alias, etc. en un chemin absolu. Plus de code posté.

Mettre à jour l'état de chargement du module.

Logique de chargement des modules :

Principalement la méthode m.fetch, les autres logiques sont ignorées ici.

Vous pouvez voir que seajs.request finira par charger le fichier du module :

Une fois tous les modules dépendants chargés, exécutez la méthode onload du mod

Voici la méthode mod.onload()

À ce stade, vous avez presque vu la logique fondamentale de Seajs. Pour référence, s'il y a une compréhension peu claire ou une expression inexacte, n'hésitez pas à en discuter ensemble.

Ce qui précède représente l’intégralité du contenu de cet article, j’espère que vous l’aimerez tous.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn