Issue
Suppose an Angular workspace with two libraries inside (e.g. projects/libA
and projects/libB
). In libA
I'm importing code from libB
import { ComponentX } from '@myscope/libB';
ComponentX
is exported in index.ts
located in projects/libB/src
. In tsconfig.json
(in root of worspace I have)
{
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "ES2022",
"module": "es2020",
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"lib": [
"es2018",
"dom"
],
"paths": {
"@myscope/libB": [
"projects/libB/src"
]
},
"useDefineForClassFields": false
}
}
In projects/libA/package.json
I have
{
"name": "@myscope/libA",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^15.0.0",
"@angular/core": "^15.0.0",
"@myscope/libB": "*"
},
"dependencies": {
"tslib": "^2.3.0"
},
"exports": {
".": {
"sass": "./src/styles.scss"
}
}
}
Still while calling ng build libA
I get many errors like
The file <path_to_worspace>/projects/libB/src/.../component-x.ts is outside of the configured 'rootDir'.
How can I fix that?
Solution
I would assume you have the following project structure:
Workspace Root
│
├── tsconfig.json
│
├── projects
│
├── libA
│ ├── package.json
│ └── ...
│
└── libB
├── src
│ ├── index.ts (exports ComponentX)
│ └── component-x.ts (contains ComponentX)
└── ...
In that case, the Angular build system is checking the files being imported against the rootDir
option in the tsconfig.json
file. And since libB
is outside of the rootDir
of libA
,... you get an error.
You can start with adjusting the paths
option in the tsconfig.json
to map @myscope/libB
to projects/libB/src/public-api
. Make sure libB
has a public-api.ts
file in its src
directory that exports ComponentX
.
// tsconfig.json
"paths": {
"@myscope/libB": [
"projects/libB/src/public-api"
]
}
And:
// projects/libB/src/public-api.ts
export * from './component-x/component-x.component';
Then make sure libB
is built before libA
using a script or, if using a compatible TypeScript version, set up project references in the tsconfig.json
.
ng build libB && ng build libA
With:
// tsconfig.json
"references": [
{ "path": "./projects/libB" },
{ "path": "./projects/libA" }
]
If necessary, adjust the rootDir
compiler option to encompass both libA
and libB
.
// tsconfig.json
"compilerOptions": {
"rootDir": "./projects",
...
}
You would have:
Workspace Root
│
├── tsconfig.json (adjusted paths, references, and optionally rootDir)
│
├── projects
│
├── libA
│ ├── package.json
│ └── ... (rest of libA files)
│
└── libB
├── src
│ ├── public-api.ts (exports ComponentX)
│ ├── component-x
│ │ └── component-x.component.ts (contains ComponentX)
│ └── ... (rest of libB files)
└── ...
In tsconfig.json
:
{
"compilerOptions": {
"rootDir": "./projects", // Optional adjustment
...
},
"paths": {
"@myscope/libB": ["projects/libB/src/public-api"]
},
"references": [ // If using project references
{ "path": "./projects/libB" },
{ "path": "./projects/libA" }
]
}
In projects/libB/src/public-api.ts
:
export * from './component-x/component-x.component';
Check then if libA
is able to import ComponentX
from libB
without encountering the 'rootDir'
error, provided the build order is correctly managed (i.e., libB
built before libA
).
Do I understand correctly that is I add
libB
topeerDependencies
oflibA/package.json
,libB
will not get bundled tolibA
?
Yes, that is correct.
When libB
is listed in the peerDependencies
of libA
, it signals that libB
is a requirement for libA
, but libB
will not be bundled with libA
.
Instead, it is expected that whoever is using libA
will also install and provide libB
. That is a common pattern for avoiding duplicate bundling of libraries, especially in scenarios where multiple libraries are expected to interact with a shared instance of another library.
Answered By - VonC
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.