54 votes

Explication de la définition de la bibliothèque RequireJS

J'ai commencé à lire plusieurs tutoriels sur RequireJS. Aucun d'entre eux n'a expliqué de manière satisfaisante le mot-clé "define" pour moi. Est-ce que quelqu'un pourrait m'aider avec ce qui suit :

define(
  ["Models/Person", "Utils/random", "jquery"], 
  function (Person, randomUtility, $) {..}
)  

Qu'est-ce que "define" ? Est-ce que define est une fonction avec un tableau et une fonction anonyme à l'intérieur ? Ou est-ce autre chose ? Est-ce que quelqu'un pourrait me donner plus d'informations sur ce type de définitions ?

Ajout : Merci nnnnnn et pradeek pour vos réponses. Ici en Europe, il était 2h30 du matin quand j'ai posté la question. Peut-être que c'est pour cela que je n'ai pas réalisé que c'était un simple appel de fonction.

63voto

Drew Points 2534

define n'est pas spécifique à RequireJS, il fait partie de la spécification AMD. Burke notera que RequireJS n'implémente pas exactement comme AMD le spécifie, car AMD n'a pas vraiment pris en compte les navigateurs.

define n'a pas de fonction anonyme en elle. define est une méthode mise à disposition des fichiers JavaScript basés sur AMD pour charger leurs données. Des bibliothèques comme RequireJS mettent cela à votre disposition. La mise en œuvre spécifique n'est probablement pas précieuse pour vous. Alors je vais passer en revue celle que vous avez fournie car c'est la façon la plus courante de déclarer un module.

define( [array], object );

Array est une liste de modules sur lesquels ce module dépend. Il y a une relation 1 à 1 entre les modules et les fichiers. Vous ne pouvez pas avoir plusieurs modules dans un fichier ni plusieurs fichiers pour un module.

Object est le module que vous définissez. Cela peut être n'importe quoi, une structure ou une fonction renvoyant une structure. Lisez la documentation sur RequireJS pour plus de détails.

Si object est une fonction, les arguments passés à la fonction sont les modules listés comme dépendances dans le premier argument de définition. Il est également important de noter que lorsque vous passez une fonction comme object, elle ne s'exécutera qu'une seule fois. Les méthodes ou propriétés créées lors de cette unique instantiation peuvent être accédées à tout moment et donc être accédées par d'autres modules qui répertorient ce module comme une dépendance.

Bonne chance, je vous recommande d'expérimenter avec cela et de lire la documentation lorsque les choses ne semblent pas claires. Les docs RequireJS sont très utiles pour comprendre rapidement comment fonctionnent les modules AMD.

5voto

BlueMonkMN Points 10838

J'ai trouvé définir défini vers le bas de require.js (je me demandais aussi quel genre de chose ce mot définir est, et voici la réponse que je cherchais):

/**
 * La fonction qui gère les définitions de modules. Diffère de
 * require() en ce qu'une chaîne pour le module devrait être le premier argument,
 * et la fonction à exécuter après le chargement des dépendances devrait
 * retourner une valeur pour définir le module correspondant au premier argument du
 * nom.
 */
define = function (nom, deps, rappel) {
    var node, context;

    //Permettre des modules anonymes
    if (typeof nom !== 'string') {
        //Ajuster les arguments correctement
        rappel = deps;
        deps = nom;
        nom = null;
    }

    //Ce module peut ne pas avoir de dépendances
    if (!isArray(deps)) {
        rappel = deps;
        deps = null;
    }

    //Si aucun nom et que le rappel est une fonction, alors déterminez s'il s'agit
    //d'une chose CommonJS avec des dépendances.
    if (!deps && isFunction(rappel)) {
        deps = [];
        //Supprimer les commentaires de la chaîne de rappel,
        //rechercher les appels à require, et les mettre dans les dépendances,
        //mais seulement s'il y a des arguments de fonction.
        if (rappel.length) {
            rappel
                .toString()
                .replace(commentRegExp, '')
                .replace(cjsRequireRegExp, function (match, dep) {
                    deps.push(dep);
                });

            //Peut être une chose CommonJS même sans appels à require, mais encore
            //pourrait utiliser exports et module. Évitez de faire des exports et du travail de module
            //cependant si cela nécessite juste require.
            //REQUIERT que la fonction s'attende aux variables CommonJS dans l'ordre indiqué ci-dessous.
            deps = (rappel.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
        }
    }

    //Si dans IE 6-8 et atteindre un appel define() anonyme, effectuez le travail interactif.
    if (useInteractive) {
        node = currentlyAddingScript || getInteractiveScript();
        if (node) {
            if (!nom) {
                nom = node.getAttribute('data-requiremodule');
            }
            context = contexts[node.getAttribute('data-requirecontext')];
        }
    }

    //Sauvegarder toujours l'évaluation de l'appel de déf jusqu'au gestionnaire onload du script.
    //Cela permet à plusieurs modules d'être dans un fichier sans suivre prématurément
    //les dépendances, et permet la prise en charge des modules anonymes,
    //où le nom du module n'est pas connu avant que l'événement onload du script
    //se produise. Si aucun contexte, utilisez la file d'attente globale, et faites-la traiter
    //dans le rappel de chargement du script.
    (context ? context.defQueue : globalDefQueue).push([nom, deps, rappel]);
};

1voto

vine'th Points 2279

J'ai trouvé cette page Pourquoi AMD? très utile. Pour résumer cette page, la spécification AMD est utile pour surmonter le problème de "l'écriture d'un tas de balises de script avec des dépendances implicites que vous devez commander manuellement". Cela permet de charger les dépendances avant d'exécuter les fonctions requises, similaire à import dans d'autres langages de programmation comme python. AMD empêche également le problème de pollution de l'espace de noms global. Consultez la section "C'est une amélioration par rapport aux actuels "globals et balises de script" du web car".

0voto

Je pense que la spécification de l'API RequireJs le résume assez bien :

Si le module a des dépendances, le premier argument doit être un tableau de noms de dépendances, et le deuxième argument doit être une fonction de définition. La fonction sera appelée pour définir le module une fois que toutes les dépendances auront été chargées. La fonction doit renvoyer un objet qui définit le module.

Ils énumèrent des exemples de toutes les formes syntaxiques de définition.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X