Obszary robocze i mikrousługi NPM

Jak tworzyć MonoRepos za pomocą MicroServices w NPM?

Repozytorium -› https://github.com/RaulGF92/NpmWorkspaceMicroServices

Wstęp

W tych tygodniach w mojej pracy rozmawiamy o MonoRepos i o tym, jak mogłoby to być rozwiązaniem naszych problemów.

Pracujemy z ogromną chmurą MicroService i czasami jakakolwiek zmiana generuje duży wpływ na nasz przepływ deweloperów UpVersion -› PullRequest -› CI/CD, co sprawia, że ​​minimalne zmiany mogą mieć duży wysiłek (a ten wygląd może z czasem zniknąć)

MonoRepo może być rozwiązaniem tego problemu, ponieważ:

  • Wszyscy programiści mogą znać wszystkie mikro
  • Udostępniamy konfiguracje projektów we wszystkich projektach
  • Moglibyśmy dokonać „ogromnych zmian” w wielu projektach

Ale wszystkie mają wady, a dotychczasowe podejście MonoRepo obejmowało wizję projektu monolitycznego zamiast wizji MicroServices, co jest mocno zakorzenione w filozofii mojej firmy, ale czy można zachować obie te rzeczy? Dobro MonoRepos i dobro MicroServices? Odpowiedź brzmi tak,Ale będziesz trochę walczyć, tutaj masz różne rozwiązania programowe:

  • NX.js: najlepiej nadają się do tworzenia monorepo w JS. Zawiera generatory i można je wdrożyć w MicroServices bez większego wysiłku. Problem z tym rozwiązaniem jest zbyt poważny, jeśli nie będziesz go przestrzegać. struktura, której potrzebujesz, aby zacząć budować swoje osobiste generatory i skrypty (przekaż także całą tę wiedzę zespołowi programistów)

Polecam tego bloga, naprawdę przydatnego do wprowadzenia w NX.js z mikro
https://blog.nrwl.io/nx-and-node-microservices-b6df3cd1bad6

  • Lerna.js:Lerna może być dobrym rozwiązaniem, jeśli masz prywatne repozytorium NPM, Lerna prześle każde Micro do NPM i je do okna dokowanego. Musisz zainstalować bibliotekę MS w pliku DockerFile, a następnie uruchomić dla mnie mogłoby być rozwiązaniem, ale bardzo trudnym

Dla mnie ten blog pomaga zrozumieć, jak działa Lerna https://semaphoreci.com/blog/javascript-monorepos-lerna

  • Przestrzeń robocza TurboRepo/NPM:Dla mnie TurboRepo jest najlepszym rozwiązaniem nie dlatego, że jest najlepsze (naprawdę musisz zrozumieć przestrzeń roboczą NPM, aby zrozumieć TurboRepo), ale jest otwarte na Twoją strukturę i wystarczy jej użyć obszar roboczy NPM (nowa wersja Lerny również go używa). TurboRepo zoptymalizuje wykonanie (z różnymi projektami w tym samym obszarze roboczym) i utworzy pamięć podręczną, aby uniknąć ponownego zgłaszania
  • bezużyteczne polecenia.

Rozpocznij pracę z obszarem roboczym NPM

Poniższa dokumentacja NPM może lepiej wyjaśnić ci, jak obszar roboczy NPM działa lepiej niż moja, wyjaśnię aplikację do użycia w MicroServices

https://docs.npmjs.com/cli/v7/using-npm/workspaces

Wszystkie moje struktury i projekty znajdują się w Repo, spójrz, jeśli chcesz, i będzie miało więcej cech.

Stworzymy przestrzeń roboczą zgodną z tą strukturą

MyProject
  package.json
  package-lock.json
  applications
  | (Microservices)
  libs
  | (common projects)

Mamy tylko jedną zasadę! Jedna wyjątkowa zasada! (Zasada ta będzie miała wpływ na przyszłe CI/CD)

Projekty aplikacji NIGDY nie importuj kolejnych projektów z folderu aplikacji, tylko z folderu libs

Zainstaluj mikrousługę

Zamierzamy zainstalować nową MicroService o nazwie User-Service (możesz zobaczyć moją implementację w moim repozytorium)

npm init -w ./applications/user-service

Zamierzamy także stworzyć wspólną bibliotekę

npm init -w ./libs/hello-i18n

Teraz strukturę będziemy widzieć w następujący sposób:

MyProject
  package.json
  package-lock.json
  applications
  | (Microservices)
    user-service
      package.json
  |
  libs
  | (common projects)
    hello-i18n
      package.json
  |

Więcej informacji znajdziesz na dole artykułu, w części „Jak działa przestrzeń robocza NPM”

Teraz zainstalujemy minimalną instalację, która będzie wymagana dla wszystkich projektów, w moim przypadku będą to Express.js, TypeScript (zobacz w repozytorium) i winston.js, w folderze głównym, który wykonaliśmy

npm install --workspaces express winston mocha chai

Spowoduje to zainstalowanie zależności w każdym projekcie i jest to ważny kluczowy punkt, rodzic obszarów roboczych NPM nie udostępnia zależności swoim dzieciom (to nie jest prawdziwy fakt, ale to prawdziwy bałagan i może być świetnie, na razie mówię, że to niemożliwe)

Kiedy tworzyłem tego bloga, zdałem sobie sprawę, że moglibyśmy użyć procesora Gulp lub Grunt, aby dać nam możliwość synchronizacji różnych pakietów, które rodzic ma w każdym pakiecie podrzędnym.

Aby zainstalować określoną zależność w innym projekcie, możesz zainstalować za pomocą polecenia -w:

npm install axios -w user-service

Jak wdrożyć MicroService?

Po to tu jesteśmy i postaramy się na to odpowiedzieć. Pomysł jest taki, aby utworzyć DockerFile dla każdej aplikacji lub folderu mikrousług, w tym DockerFile dodamy cały monolityczny, ale , dodamy aplikację docelową i cały folder lib, jak w tym przykładzie:

Wewnątrz pliku DockerFile instalujemy wszystkie zależności każdego elementu obszaru roboczego i budujemy wszystkie projekty (w przypadku monorepo TypeScriptu), skrypty te są przydzielane w folderze nadrzędnym i będą zawierać flagę o nazwie — jeśli-obecna i dają nam możliwość nieprzydzielania całego obszaru roboczego w każdej replice, to jest niesamowite!

"scripts": {
  "build-all": "npm run build --workspaces --if-present",
  "install-all": "npm install --workspaces  --if-present",
  "lint-all": "npm run lint --workspaces --if-present",
  "lint-fix-all": "npm run lint-fix --workspaces --if-present"
},

W tym momencie rozwiązaliśmy unikalną regułę utworzoną dla tego rozwiązania:

Projekty aplikacji NIGDY nie importuj kolejnych projektów z folderu aplikacji, tylko z folderu libs

Dzieje się tak dlatego, że kiedy tworzymy mikroserwis, projekt aplikacji nie będzie miał dostępu do innej aplikacji, ale tak do folderu lib (to rozwiązanie można zmodyfikować w celu niestandardowej adaptacji)

Teraz, jeśli chcemy to wdrożyć, możemy użyć docker-compose lub Kubernetes. Jest to przykład docker-compose przydzielonego w folderze głównym:

Aby to było głównym celem tego wpisu, muszę porównać ten proces w GitHubie!

Jak działa obszar roboczy NPM?

Jeśli chcesz wiedzieć, jak działa obszar roboczy NPM, musisz wykonać instalację npm w nadrzędnym folderze głównym, tutaj NPM zainstaluje pakiet.json z każdego dziecka i wstrzyknie go do nadrzędnych modułów node_modules.

Jeśli przejdziemy do package.json, zobaczymy obszar roboczy (Tak, używam systemu Windows, ale działa równie w systemie Unix)

"workspaces": [
    "applications\\user-service",
    "libs\\*"
  ]

A jeśli chcemy wydać dowolne polecenie, na przykład przetestować wszystkie nasze projekty, możemy wrzucić rodzica, a rodzic wybierze wszystkie obszary robocze

npm run test --workspaces

lub konkretny projekt:

npm run test --workspace=user-service