javascript - Hur importerar man ett lokalt monorepo TypeScript-paket i Angular-appar?
Jag försöker integrera ett Angular-projekt i ett PNPM workspace-monorepo som huvudsakligen innehåller en React-app. Här är katalogstrukturen
|-apps
| |-react-app
| | |-package.json
| |
| |-angular-app (new)
| |-package.json
|
|
|-packages
| |-shared
| |-index.ts
| |-package.json
|
|-package.json
|-pnpm-workspace.yaml
Låt oss säga att det delade paketet har namnet @my-app/shared och att det har "main": "index.ts".
I react-app kan jag installera detta lokala paket och använda det direkt i min kod som följande
import { someValue } from '@my-app/shared';
Med viss justering av webpack-konfigurationen kan react-app inkludera den delade modulen i paketet korrekt.
Jag kunde dock inte lista ut hur man gör det i en Angular-app. Paketet kan installeras korrekt och allt, men när jag kör utvecklingsservern verkar det som att det inte inkluderar @my-app/shared i bundlen.
import { value } from '@my-app/shared';
console.log('xxx', value);
När jag inspekterade paketet verkar det som att Angular-kompilatorn inte bundlar modulen. Istället visar den bara platshållaren
Hur importerar man då ett lokalt paket i Angular? Jag tror att det behöver läggas till någon konfiguration i angular.json, men jag kunde inte hitta någon resurs. Alla källor där ute pekar på Angular Library genom ng generate library, vilket inte är vad jag letar efter eftersom @my-app/shared bara är enkla TypeScript-verktygsfunktioner.
Svar #1
Jag hade samma problem, jag undersökte varför, här är vad jag fann ⤵️
Det beror i princip på att TypeScript inte genererar några ts-filer som lagras i node_modules (du kan kolla det här).
När Angular kompilerar din applikation kompilerar det filer med TypeScript-kompilatorn: eftersom TypeScript upptäcker filen som ett externt bibliotek, exkluderas den, så ingenting genereras för denna fil.
Varför det fungerar med din react-app:
Jag antar att du var tvungen att ställa in allowTsInNodeModules till true, eller hur? ts-loader löser detta problem i webpack-pluginen, men @angular/cli implementerar ingen lösning.
Varför det fungerar med paths:
När TypeScript analyserar listan över filer att kompilera, kontrollerar det inte genom att titta på ett specifikt node_modules-mönster i filsökvägen:
- Istället upprätthåller det en
currentNodeModulesDepth-variabel (se här). - När vi använder
pathssescurrentNodeModulesDepthsom lika med noll, eftersom TypeScript hittade en mappning och därför inte började titta pånode_modules. - Så i det här fallet är det korrekt inkluderat i slutresultatet.
Observera att du kan förenkla din lösning med:
"paths": {
"@my-app/*": ["../../packages/*"]
}
Så, du behöver inte lista alla beroenden, du kan använda * som en platshållare.
Svar #2
Jag har stött på samma problem. Tyvärr är det enda sättet jag har kunnat lösa det på genom att använda tsconfig-vägar.
Med antagande om ovanstående struktur:
|-apps
| |-react-app
| | |-package.json
| |
| |-angular-app (new)
| |-package.json
| |-tsconfig.app.json
|
|
|-packages
| |-shared
| |-index.ts
| |-package.json
|
|-package.json
|-pnpm-workspace.yaml
Observera filen på apps/angular-app/tsconfig.app.json
{
"compilerOptions": {
"paths": {
"@my-app/shared": ["../../packages/shared/index.ts"]
},
// ... the rest of your options
}
}
Detta har den olyckliga nackdelen att angular-appen måste kompilera om hela shared-paketet varje gång det sker en förändring. Enligt min åsikt är det bättre än inget. Om det finns ett bättre sätt, skulle jag gärna vilja veta det!

