Cel
Mam więc projekt o tej strukturze:
- aplikacja jonowa
- funkcje bazy ogniowej
- udostępnione
Celem jest zdefiniowanie wspólnych interfejsów i klas w shared
module.
Ograniczenia
Nie chcę przesyłać mojego kodu do npm, aby używać go lokalnie i w ogóle nie planuję przesyłać kodu. Powinien w 100% działać w trybie offline.
Podczas gdy proces rozwoju powinien pracować w trybie offline, ionic-app
a firebase-functions
moduły zostaną wdrożone do Firebase (hosting i funkcje). Dlatego kod z shared
modułu powinien być tam dostępny.
Co próbowałem do tej pory
- Próbowałem używać referencji projektu w maszynopisie, ale nie zbliżyłem się do niego
- Próbowałem go, instalując go jako moduł npm, jak w drugiej odpowiedzi na to pytanie
- Początkowo wydaje się, że działa dobrze, ale podczas kompilacji pojawia się taki błąd podczas uruchamiania
firebase deploy
:
- Początkowo wydaje się, że działa dobrze, ale podczas kompilacji pojawia się taki błąd podczas uruchamiania
Function failed on loading user code. Error message: Code in file lib/index.js can't be loaded.
Did you list all required modules in the package.json dependencies?
Detailed stack trace: Error: Cannot find module 'shared'
at Function.Module._resolveFilename (module.js:548:15)
at Function.Module._load (module.js:475:25)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/srv/lib/index.js:5:18)
Pytanie
Czy masz rozwiązanie do tworzenia modułu współdzielonego przy użyciu konfiguracji maszynopisu lub NPM?
Nie zaznaczaj tego jako duplikatu → Wypróbowałem każde rozwiązanie, które znalazłem na StackOverflow.
Dodatkowe informacje
Konfiguracja dla udostępnionego:
// package.json
{
"name": "shared",
"version": "1.0.0",
"description": "",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"files": [
"dist/src/**/*"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"publishConfig": {
"access": "private"
}
}
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"rootDir": ".",
"sourceRoot": "src",
"outDir": "dist",
"sourceMap": true,
"declaration": true,
"target": "es2017"
}
}
Konfiguracja funkcji:
// package.json
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^8.0.0",
"firebase-functions": "^3.1.0",
"shared": "file:../../shared"
},
"devDependencies": {
"@types/braintree": "^2.20.0",
"tslint": "^5.12.0",
"typescript": "^3.2.2"
},
"private": true
}
// tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"module": "commonjs",
"noImplicitReturns": true,
"noUnusedLocals": false,
"rootDir": "src",
"outDir": "lib",
"sourceMap": true,
"strict": true,
"target": "es2017"
}
}
Aktualne południe
Dodałem skrypt npm do współdzielonego modułu, który kopiuje wszystkie pliki (bez index.js) do innych modułów. Problem polega na tym, że sprawdzam zduplikowany kod w SCM i muszę uruchamiać to polecenie przy każdej zmianie. Ponadto IDE traktuje to jak różne pliki.
źródło
Innym możliwym rozwiązaniem jest użycie git do zarządzania kodem
git submodule
. Korzystając z niego,git submodule
możesz dołączyć do swojego projektu kolejne repozytorium git.Dotyczy twojego przypadku użycia:
git submodule add <shared-git-repository-link>
wewnątrz głównego projektu (projektów), aby połączyć repozytorium wspólne.Oto link do dokumentacji: https://git-scm.com/docs/git-submodule
źródło
Jeśli dobrze rozumiem twój problem, rozwiązanie jest bardziej złożone niż pojedyncza odpowiedź i częściowo zależy od twoich preferencji.
Podejście 1: Lokalne kopie
Możesz użyć Gulp do zautomatyzowania działającego rozwiązania, które już opisałeś, ale IMO nie jest bardzo łatwe w utrzymaniu i drastycznie zwiększa złożoność, jeśli w pewnym momencie pojawi się inny programista.
Podejście 2: Monorepo
Możesz utworzyć pojedyncze repozytorium, które zawiera wszystkie trzy foldery i połączyć je tak, aby zachowywały się jak jeden projekt. Jak już wspomniano powyżej, możesz użyć Lerny . Wymaga to trochę konfiguracji, ale kiedy to zrobisz, te foldery będą zachowywać się jak pojedynczy projekt.
Podejście 3: Komponenty
Traktuj każdy z tych folderów jako samodzielny komponent. Spójrz na Bit . Pozwoli ci to skonfigurować foldery jako mniejsze części większego projektu i możesz utworzyć konto prywatne, które będzie obejmowało tylko te elementy. Po wstępnej konfiguracji pozwoli ci nawet zastosować aktualizacje do oddzielnych folderów, a nadrzędny, który ich używa, automatycznie pobierze aktualizacje.
Podejście 4: Pakiety
W szczególności powiedziałeś, że nie chcesz używać npm, ale chcę się nim podzielić, ponieważ obecnie pracuję z zestawem, jak opisano poniżej i wykonuję dla mnie idealną robotę:
npm
lub,yarn
aby utworzyć pakiet dla każdego folderu (możesz utworzyć pakiety o określonym zakresie dla obu z nich, aby kod był dostępny tylko dla ciebie, jeśli jest to twoja sprawa).Działa jak urok, a kiedy pakiety są dowiązane do lokalnego rozwoju, działa całkowicie offline i z mojego doświadczenia - każdy folder jest skalowalny osobno i bardzo łatwy w utrzymaniu.
Uwaga
Pakiety „potomne” są już w moim przypadku wstępnie skompilowane, ponieważ są dość duże i stworzyłem osobne tsconfig dla każdego pakietu, ale piękną rzeczą jest to, że można to łatwo zmienić. W przeszłości używałem zarówno maszynopisu w module, jak i plików skompilowanych, a także nieprzetworzonych plików js, więc całość jest bardzo, bardzo wszechstronna.
Mam nadzieję że to pomoże
***** AKTUALIZACJA **** Aby kontynuować w punkcie 4: przepraszam, mój zły. Może pomyliłem się, ponieważ o ile mi wiadomo, nie można dowiązać modułu do modułu, jeśli nie został przesłany. Niemniej jednak oto:
firebase-functions
do tego. Kompilujesz go lub używasz surowych ts, w zależności od twoich preferencji.firebase-functions
jako zależność.tsconfig.json
dodaj"paths": {"firebase-functions: ['node_modules/firebase-functions']"}
resolve: {extensions: ['ts', 'js'], alias: 'firebase-functions': }
W ten sposób odwołujesz się do wszystkich eksportowanych funkcji z
firebase-functions
modułu po prostu za pomocąimport { Something } from 'firebase-functions'
. Webpack i TypeScript połączą go z folderem modułów węzłów. W tej konfiguracji projekt nadrzędny nie będzie dbał o to, czyfirebase-functions
moduł zostanie napisany w języku JavaScript lub javascript.Po skonfigurowaniu będzie działał idealnie do produkcji. Następnie, aby połączyć i pracować w trybie offline:
firebase-functions
projektu i napisznpm link
. Stworzy dowiązanie symboliczne, lokalne dla twojego komputera i zamapuje łącze na nazwę, którą ustawiłeś w package.json.npm link firebase-functions
, który utworzy dowiązanie symboliczne i zamapuje zależność funkcji firebase od folderu, w którym go utworzyłeś.źródło
Wszystkie moduły npm są instalowane lokalnie i zawsze działają w trybie offline, ale jeśli nie chcesz publikować swoich pakietów publicznie, aby ludzie mogli je zobaczyć, możesz zainstalować prywatny rejestr npm.
ProGet to serwer prywatnego repozytorium NuGet / Npm dostępny dla systemu Windows, którego można używać w prywatnym środowisku programistycznym / produkcyjnym do hostowania, uzyskiwania dostępu i publikowania prywatnych pakietów. Chociaż jest w systemie Windows, ale jestem pewien, że istnieją różne alternatywy dostępne dla systemu Linux.
Oto nasz scenariusz kompilacji / wdrożenia.
.npmrc
co zawieraregistry=https://private-npm-repository
.bundled dependencies
który zawiera wszystkie pakiety wewnątrz,node_modules
a serwer produkcyjny nigdy nie musi uzyskiwać dostępu do NPM ani prywatnych pakietów NPM, ponieważ wszystkie niezbędne pakiety są już zawarte w pakiecie.Korzystanie z prywatnego repozytorium npm ma różne zalety,
źródło
Narzędzie, którego szukasz, to
npm link
.npm link
dostarcza dowiązania symboliczne do lokalnego pakietu npm. W ten sposób możesz połączyć pakiet i używać go w głównym projekcie bez publikowania go w bibliotece pakietów npm.Dotyczy twojego przypadku użycia:
npm link
wshared
pakiecie. Ustawi to miejsce docelowe dowiązania symbolicznego dla przyszłych instalacji.functions
pakietu i użyj go,npm link shared
aby połączyć udostępniony pakiet i dodać go donode_modules
katalogu.Oto link do dokumentacji: https://docs.npmjs.com/cli/link.html
źródło