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?
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.
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.
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'], ...
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.
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.
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.