web-dev-qa-db-fra.com

Objet non défini transmis via Requirejs

J'utilise Requirejs pour charger le JavaScript dans notre application Web. Le problème est que je reçois un objet undefined passé à un module qui, lorsqu'il est utilisé dans d'autres modules, est instancié parfaitement bien.

OK, voici la configuration. Ma main.js fichier qui nécessite js s'exécute au démarrage:

require.config({
    baseUrl: "/scripts",
    paths: {
        demographics: "Demographics/demographics",
        complaints: "Complaints/complaints",
    }
});

require(["templates", "demographics", "complaints", "crossDomain"], function (templates, demographics, complaints) {
    "use strict";

    console.log("0");
    console.log(demographics === undefined);

    demographics.View.display();
});

Une grande partie de la configuration a été supprimée uniquement pour les fichiers de base dans ce problème.

Voici Demographics.js:

define(["ko", "templates", "complaints", "globals", "underscore"], function (ko, templates, complaints, globals) {

    // Stuff removed.
    return {
        View: view
    };
});

et Complaints.js

define([
    "demographics",
    "ko",
    "templates",
    "complaints",
    "visualeffects",
    "globals",
    "webservice",
    "underscore",
    "typewatcher",
    "imagesloaded"],
    function (demographics, ko, templates, complaints, visualeffects, globals, webservice) {
        "use strict";


        console.log("1");
        console.log(demographics === undefined);
    return {
        View: view
    };
});

Le problème est le suivant: dans Complaints.js le paramètre demographics transmis via la configuration define est undefined. La déconnexion de la console me dit que "démographie === indéfini" est true.

Cependant, lorsque le fichier main.js s'exécute, le paramètre démographique qui lui est transmis n'est pas indéfini, il s'agit, comme prévu, d'un objet instancié.

Maintenant, je suis coincé car je ne vois pas pourquoi dans complaints.js cette variable démographique n'est pas définie. Quelqu'un peut-il repérer ce qui me manque, s'il vous plaît?

41
Jason Evans

Vous avez une dépendance circulaire. Le module demographics dépend de complaints et complaints dépend de demographics. Selon le documentation :

Si vous définissez une dépendance circulaire (a a besoin de b et b a besoin de a), alors dans ce cas, lorsque la fonction de module de b est appelée, elle obtiendra une valeur non définie pour a.

La solution, si vous ne pouvez pas supprimer la dépendance circulaire, est d'exiger de manière asynchrone l'un des deux modules dans l'autre à la demande (par exemple, lorsque la vue est instanciée plutôt que lorsque le module qui définit la vue est exécuté). Encore une fois, les docs couvrent assez bien ce sujet.

59
rharper

Un autre cas est lorsque vous tapez accidentellement require au lieu de define lors de la définition d'un module, il m'a fallu un certain temps pour le remarquer.

28
Misha Reyzlin

J'avais un problème similaire. Dans mon cas, lors de la définition d'un module, j'avais écrit:

define('some_dependency', ...

au lieu de

define(['some_dependency'], ...
11
Joel

Une autre raison possible est l'implémentation de l'interface du module (AMD, CommonJS), mais en oubliant de retourner quoi que ce soit. Je viens de faire ça.

4
LeeGee

Je viens de rencontrer une autre raison:

define(function () {
    return {};
}()); // <-- notice the '()' typo.

Cette "faute de frappe" ne provoque aucune erreur JS pour celle-ci et peut rendre la compréhension particulièrement difficile dans une application compliquée avec de nombreuses dépendances circulaires potentielles.

La raison, bien sûr, est que la "faute de frappe" est un JS valide qui appelle simplement la fonction que vous définissez, transmettant ainsi son résultat à define() plutôt qu'à la fonction comme prévu.

1
Brad Allred

Une autre raison possible qui peut sembler évidente avec le recul est une erreur dans le code de votre module. Dans mon cas, j'essayais d'obtenir un attribut à partir d'une variable non définie. L'erreur est enregistrée dans la console, mais pour une raison quelconque, je ne la voyais pas/ne la confondais pas avec l'erreur de module non définie.

0
Sofia Paixão