composer vs npm: développement multi-modules

Au cours des trois ou quatre dernières années, lors de la programmation en PHP, j'ai utilisé composer pour gérer les dépendances des applications. Il est maintenant nécessaire de passer à nodejs et, par conséquent, de configurer un environnement de développement familier. Heureusement, j'utilise l'IDE PhpStorm, qui vous permet de travailler avec PHP et JS. Une caractéristique des projets auxquels je participe est la multi-modularité. La fonctionnalité est répartie entre les modules non pas tant pour la réutilisation que pour réduire la complexité finale de l'application due à la décomposition en composants faiblement couplés. En général, il est normal pour ces projets lorsque, dans le cadre de la résolution d'un problème, des modifications sont apportées à plusieurs modules et validées dans plusieurs référentiels.


image


Lors de la configuration d'un projet nodejs , je suis tombé sur certaines fonctionnalités qui compliquent le développement multi-module. Cette publication est née en train d'essayer de traiter ces caractéristiques. Sous la coupe, PHP envisage de déployer un projet nodejs .


Structure du projet de démonstration


Le projet se compose de 3 modules:


  • application : module de tête reliant les dépendances;
  • module fonctionnel : contient les fonctions appelées depuis le module principal;
  • module de base : contient les fonctions appelées à partir d'un module fonction;

image


Le code de chaque module se trouve sur github:



Les descripteurs de module pour les gestionnaires de dépendances respectifs ( composer.json et package.json ) sont situés dans chaque module, c'est-à-dire que chaque module peut être développé à la fois en tant que module php et en tant que module js. Le code PHP et le code JS dans les modules sont simplement placés côte à côte, sans se croiser.


Exécution de l'application pour exécution:


 $ php index.php $ nodejs index.js 

Le résultat du travail dans les deux cas:


 This is application. This is func module. This is base module. 

Buts


Un projet en milieu de travail doit permettre:


  • suivre les changements IDE dans chaque module impliqué dans le développement;
  • À l'aide de l'EDI, validez les modifications dans différents référentiels en une seule action.
  • utiliser le débogueur pour tracer l'exécution du code des modules;

Déploiement via le composer


Tout est familier ici. Dans le descripteur de déploiement ( composer.json ) de l'application, spécifiez les adresses des référentiels avec modules et prescrivez les branches principales des modules comme dépendances avec la version souhaitée:


 { "require": { "flancer64/habr-cvsn-mod-base": "dev-master as 0.1.0", "flancer64/habr-cvsn-mod-func": "dev-master as 0.1.0" }, "repositories": [ { "type": "vcs", "url": "https://github.com/flancer64/habr-cvsn-mod-base" }, { "type": "vcs", "url": "https://github.com/flancer64/habr-cvsn-mod-func" } ] } 

Après avoir exécuté la commande:


 $ composer install 

./vendor répertoires avec modules apparaissent dans le répertoire ./vendor , qui à son tour contient les répertoires .git :


  • ./vendor/
    • ./flancer64/
      • ./habr-cvsn-mod-base/
        • ./.git/
      • ./habr-cvsn-mod-base/
        • ./.git/

Autrement dit, composer déploie immédiatement les dépendances sous une forme adaptée au développement (contrôle de version). Il ne reste plus qu'à configurer l'IDE PhpStorm (mettre les modules dépendants sous contrôle de version):


image


et vous pouvez suivre les changements dans tous les modules développés:


image


et valider toutes les modifications dans les référentiels locaux en même temps:


image


et poussez vers la télécommande:


image


Le débogage n'est également pas un problème. Nous pouvons définir des points d'arrêt sur n'importe quelle ligne du code du module de base - après le démarrage de l'application sous le débogueur, la coupure se produit si nécessaire:


image


En général, l'environnement habituel, confortable comme des pantoufles.


Déploiement normal via npm


Contrairement à composer npm ne suppose pas que dans le projet, tous les modules du répertoire node_modules peuvent être sous contrôle de version. Nous pouvons spécifier dans le descripteur de déploiement package.json que le module doit être chargé à partir d'un référentiel externe (par exemple, à partir de githib):


 { "dependencies": { "habr-cvsn-mod-base": "github:flancer64/habr-cvsn-mod-base", "habr-cvsn-mod-func": "github:flancer64/habr-cvsn-mod-func" } } 

mais nous n'avons pas la possibilité de demander à npm créer un référentiel local pour le module chargé (sous-répertoire .git ).


Après avoir exécuté la commande:


 $ npm install 

les dépendances sont téléchargées et installées localement sans possibilité d'utiliser le contrôle de version:


image


(sous-répertoire manquant ./.git/ in ./node_modules/habr-cvsn-mod-base/ )


Mais le débogueur s'arrête sans problème dans le module de base:


image


Déployer via npm en utilisant l'option de lien


Pour que les modules de ./node_modules/ puissent être gardés sous contrôle de version, les développeurs de npm suggèrent d'utiliser l'option ' link '. En bref, l'essence de l'approche est que les modules qui doivent être versionnés sont clonés à un endroit arbitraire sur le disque du développeur (par exemple, dans /home/alex/work/habr/ ), puis liés à /usr/lib/node_modules/ en utilisant la commande:


 # npm link 

(J'avais besoin de privilèges root pour exécuter)


Après cela, vous pouvez déjà utiliser les commandes du projet:


 $ npm link habr-cvsn-mod-base $ npm link habr-cvsn-mod-func 

npm trouvera les modules appropriés dans /usr/lib/node_modules/ et leur fermera les sous-répertoires correspondants du projet ./node_modules/ :


 $ ls -lh ./node_modules/ total 0 lrwxrwxrwx 1 alex alex 57 jūl 2 16:18 habr-cvsn-mod-base -> ../../../../../../usr/lib/node_modules/habr-cvsn-mod-base lrwxrwxrwx 1 alex alex 57 jūl 2 16:18 habr-cvsn-mod-func -> ../../../../../../usr/lib/node_modules/habr-cvsn-mod-func 

Les modules dans /usr/lib/node_modules/ eux /usr/lib/node_modules/ mêmes, à leur tour, sont des liens vers l'emplacement d'origine des modules:


 $ ls -lh /usr/lib/node_modules/ ... lrwxrwxrwx 1 root root 39 jūl 2 16:18 habr-cvsn-mod-base -> /home/alex/work/habr/habr-cvsn-mod-base lrwxrwxrwx 1 root root 39 jūl 2 16:18 habr-cvsn-mod-func -> /home/alex/work/habr/habr-cvsn-mod-func ... 

Et à leur place permanente, "registration" contient un référentiel local:


 $ ls -lha /home/alex/work/habr/habr-cvsn-mod-base ... drwxrwxr-x 8 alex alex 4,0K jūl 2 16:18 .git ... 

Ainsi, nous pouvons configurer l'EDI pour contrôler les changements dans les dépendances du projet:


image


Les problèmes commencent lorsque vous essayez d'exécuter l'application:


 $ nodejs index.js internal/modules/cjs/loader.js:670 throw err; ^ Error: Cannot find module 'habr-cvsn-mod-base' at Function.Module._resolveFilename (internal/modules/cjs/loader.js:668:15) at Function.Module._load (internal/modules/cjs/loader.js:591:27) at Module.require (internal/modules/cjs/loader.js:723:19) at require (internal/modules/cjs/helpers.js:14:16) at Object.<anonymous> (/home/alex/work/habr/habr-cvsn-mod-func/src/index.js:3:14) ... 

L'application voit le module fonctionnel lié, mais le module fonctionnel lui-même ne voit pas le module de base lié. Pour quitter la situation, utilisez la clé --preserve-symlinks pour nodejs :


 $ nodejs --preserve-symlinks index.js 

Ajoutez la clé à la commande de lancement de projet dans l'EDI:


image


Maintenant le lancement passe, mais il y a des problèmes avec le débogage - les points d'arrêt dans les dépendances ne fonctionnent pas. Vous pouvez vous arrêter dans le module principal et descendre les étapes vers les sources de dépendance, mais l'IDE PhpStorm ne voit pas le point d'arrêt lui-même lors de l'exécution, bien qu'il affiche:


image


Les développeurs IDE disent que cela devrait fonctionner, mais cela ne fonctionne pas (le cache est vidé, l'IDE redémarré).


En général, le but de cette publication était d'interviewer des collègues js sur la façon dont ils sortent dans une situation similaire, mais au cours de la rédaction de l'article, une autre combinaison a émergé pour le développement du projet:


Placement des codes sources dans les répertoires internes de npm-project


Il s'est avéré que si pour la liaison, vous utilisez des clones de modules de github créés par composer dans le sous-répertoire ./vendor/ , plutôt que d'être liés à des répertoires externes au projet, les scripts js sont exécutés sans la --preserve-symlinks et, plus important pour moi, l'IDE PhpStorm voit des points d'arrêt à l'intérieur des modules. Parce que cela n'a aucun sens d'utiliser composer uniquement pour le clonage de modules de projet, j'ai utilisé le git habituel et cloné le code source des modules dans le sous-répertoire ./own_modules . Puis il a répété les manipulations du paragraphe précédent:


  • lié les modules dans le sous-répertoire ./own_modules/... avec la bibliothèque système /usr/lib/node_modules/ ;
  • modules connectés dans la bibliothèque système avec le projet;
  • Configuré l'IDE PhpStorm pour fonctionner avec les référentiels locaux dans le sous-répertoire ./own_modules/ ;

image


Je ne connais pas la raison, mais lorsque les sources des modules dépendants sont à l'intérieur du projet, le résultat final de l'assemblage est considérablement différent de lorsque les sources des modules dépendants se trouvent dans un répertoire externe au projet.


Résumé


En comparant les deux approches de construction d'applications multi-modules (PHP avec composer et JS avec npm ), je peux conclure que composer plus convivial pour les développeurs que npm . Il est possible que les développeurs de composer (première sortie en 2012) aient pris en compte l'expérience des développeurs de npm (première sortie en 2010). Cependant, avec un effort supplémentaire, npm offre également la possibilité de développer des applications multi-modules dans des conditions assez confortables.


Scripts de commande pour le déploiement de projets dans différents modes:


Source: https://habr.com/ru/post/fr458018/


All Articles