Aujourd'hui, j'ai adopté Browserify pour mon projet AngularJS, mais il y a quelque chose qui n'est pas très clair pour moi. Dans tous les exemples et articles de blog, j'ai vu des trucs comme ça:
require('./messages');
angular.module('sling', ['sling.messages']);
exports = angular.module('sling.messages', [])
.controller('MessagesListCtrl', require('./MessagesListCtrl'));
module.exports = function() {
// ...
});
Bien sûr, cela fonctionne, mais pourquoi faire cela? Je l'ai implémenté comme ça et cela fonctionne très bien aussi et semble plus normal pour un projet AngularJS:
require('./messages');
angular.module('sling', ['sling.messages']);
angular.module('sling.messages', []);
require('./MessagesListCtrl');
angular.module('sling.messages').controller('MessagesListCtrl', function() {
// ...
});
En d'autres termes, je saute complètement les exports/module.exports, en utilisant uniquement require
pour inclure essentiellement les fichiers avec les contrôleurs, les services, le filtre, etc.
Suis-je en train de faire ça? Je veux dire que tout fonctionne, mais vais-je avoir des ennuis plus tard?
La raison principale (et honnêtement seulement) d'utiliser Browserify est si vous voulez avoir des modules CommonJS (c'est-à-dire des modules NodeJS) dans le navigateur. Un module CommonJS reste hors de la portée globale en ayant une portée "module" implicite. Vous choisissez les éléments à exposer à partir de la portée du module (généralement le point d'entrée ou la fonction principale de votre module) en augmentant l'objet "exports" de chaque module.
Ainsi, un "vrai" module CommonJS ressemble à ceci.
Déposer un:
// a.js
function doSomething() {
console.log("I am doing something");
}
module.exports = doSomething
Fichier B:
// b.js
doSomething();
// Exception - attempt to call a non-existent function
Fichier C:
// c.js
var doSomething = require('a');
doSomething();
// logs "I am doing something"
Dans le navigateur qui n'a pas de portée de module, a.js
augmenterait la portée globale avec la fonction doSomething, car elle est déclarée comme globale. Browserify contourne ce problème en encapsulant chaque module intégré dans un encapsuleur de fonction et en fournissant un objet "exports" aux modules inclus comme argument à cet encapsuleur.
Entrez AngularJS. Vous avez deux approches que vous pouvez utiliser ici, dont je suppose du fait que vous n'utilisez pas require ('angular') est la première:
J'ai tendance à préférer la deuxième approche, car il est assez étrange d'utiliser Browserify pour vous donner la portée du module, puis faire de la dépendance principale de votre projet une fenêtre globale.
Cependant, AngularJS possède déjà son propre système de modules pilotés par injection de dépendance. Lorsque vous déclarez des composants angularJS, vous les attachez à des objets de module qui eux-mêmes ont été attachés à l'objet angular
. Cela signifie que l'objet exports
pour vos fichiers de module angularJS est essentiellement redondant dans le cas d'Angular, car tant que le fichier s'exécute, l'objet angular
sera augmenté avec votre module et vos composants.
Vous devez toujours "exiger" les fichiers car sinon Browserify ne les regroupera pas, ils ne s'exécuteront jamais et ils n'augmenteront jamais l'objet angular
avec vos modules. Mais vous n'avez pas besoin d'ajouter quoi que ce soit aux exportations pour Angular, puisque l'objet angular
est vos exportations.
Alors pourquoi ai-je passé tout ce temps à expliquer le fonctionnement des modules CommonJS et des exportations? Parce que nous espérons que l'autre raison pour laquelle vous utilisez Browserify est de vous permettre d'utiliser des modules hébergés sur NPM dans votre application de navigateur. La plupart de ces modules sont des modules commonJS non angulaires, ce qui signifie que leurs fonctionnalités sont exposées via une exportation. Dans ce cas, il est important de capturer leurs exportations dans une variable lorsque vous en avez besoin, comme je le fais dans c.js
au dessus. De même, si vous écrivez des modules et les libérez dans NPM, vos utilisateurs s'attendent à ce que vous ajoutiez le point d'entrée à votre module à l'objet exports
du fichier déclaré comme principal dans votre package.json
.