I am trying to build an Angular mono repo. However, when I try to run lerna run start --scope=@demo/core-app
I get the following error:
[error] TypeError: Cannot read property 'pos' of undefined
at createFileDiagnosticAtReference (E:\Temp\node_modules\typescript\lib\typescript.js:107529:68)
at addProgramDiagnosticAtRefPath (E:\Temp\node_modules\typescript\lib\typescript.js:107547:93)
at checkSourceFilesBelongToPath (E:\Temp\node_modules\typescript\lib\typescript.js:107208:25)
at Object.getCommonSourceDirectory (E:\Temp\node_modules\typescript\lib\typescript.js:105619:21)
at Object.getDeclarationEmitOutputFilePath (E:\Temp\node_modules\typescript\lib\typescript.js:17179:125)
at getOutputPathsFor (E:\Temp\node_modules\typescript\lib\typescript.js:99488:112)
at forEachEmittedFile (E:\Temp\node_modules\typescript\lib\typescript.js:99425:41)
at Object.emitFiles (E:\Temp\node_modules\typescript\lib\typescript.js:99654:9)
at emitWorker (E:\Temp\node_modules\typescript\lib\typescript.js:106125:33)
at E:\Temp\node_modules\typescript\lib\typescript.js:106102:72
at runWithCancellationToken (E:\Temp\node_modules\typescript\lib\typescript.js:106205:24)
at Object.emit (E:\Temp\node_modules\typescript\lib\typescript.js:106102:26)
at getFileEmitOutput (E:\Temp\node_modules\typescript\lib\typescript.js:108003:26)
at updateShapeSignature (E:\Temp\node_modules\typescript\lib\typescript.js:108239:36)
at getFilesAffectedByUpdatedShapeWhenModuleEmit (E:\Temp\node_modules\typescript\lib\typescript.js:108442:46)
at Object.getFilesAffectedBy (E:\Temp\node_modules\typescript\lib\typescript.js:108194:144)
Here's how the folder is structured with Lerna: (Example github repo - Link)
-- packages
-- core-app (Angular project)
-- shared (Shared project from where the angular project would utilize some types)
Root Level tsconfig.json
{
"compilerOptions": {
"baseUrl": "./", /* Enable incremental compilation */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015',
"strict": false, /* Enable all strict type-checking options. */
// "esModuleInterop": true,
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
},
"references": [
{ "path": "packages/shared" },
{ "path": "packages/core-app" }
]
}
Shared project tsconfig.json
{
"extends": "../../tsconfig.json",
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "lib",
"sourceMap": true,
"downlevelIteration": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"module": "es2020",
"moduleResolution": "node",
"importHelpers": true,
"declaration": true,
"declarationMap": true,
"lib": [
"es2018",
"dom"
],
"composite": true,
"paths": {
"@demo/core-app/*": ["../core-app/src/*"],
"@demo/shared/*": ["./src/*"]
}
},
"references": [
{ "path": "../core-app" }
]
}
Core-app (Angular) tsconfig.json
{
"extends": "../../tsconfig.json",
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": true,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"module": "es2020",
"lib": [
"es2018",
"dom"
],
"composite": true,
"paths": {
"@demo/core-app/*": ["src/*"],
"@demo/shared/*": ["../shared/src/*"]
}
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
},
"references": [
{ "path": "../shared" }
]
}
I think you don't need to add references and paths in tsconfig.json
on both side, lerna should be able to do it for you after bootstrapping.
1. remove references
, paths
and composite
in tsconfig.json
After you remove references and paths, you should be able to see a different error indicating the missing @demo/shared/models/ExampleModel
module.
2. move the models
folder in shared module
To have the exact path of @demo/shared/models/ExampleModel, move the models
folder to the root level of shared module and remove src
folder.
3. use interface or type for type definition. Otherwise, you will hit "Strict Class Initialization" error
shared/models/ExampleModel.ts
export interface ExampleModel{
Id: number;
Name: string;
}
4. add index.ts to export type for future expandability
shared/models/index.ts
export * from './ExampleModel'
5. expose a entry point in shared module
In package.json
, add main entry point
shared/package.json
6. add dev and peer dependencies of @demo/shared
packages in core-app
core-app/package.json
"peerDependencies": {
"@demo/shared": "^0.0.1"
},
"devDependencies": {
...
@demo/shared": "^0.0.1",
...
"typescript": "~4.1.5"
}
typescript should be below 4.2.0 for angular 11
7. fixing typo in app.component.html
should be examples instead of exmaples*
<div *ngFor="let example of examples">
{{example.Name}}
</div>
8. boostraping
npx lerna bootstrap --hoist
9. run the app
npx lerna run start --scope=@demo/core-app
Here is the working repo for your reference. You can read the last commmit for details, it is concluded in the above steps.