In my tsconfig.json I have added the following code so that I can import modules using "@orco/.." I am using multiple apps in the same repo. I want to share between apps common modules. The tsconfig below does work properly with ng serve and ng build. It does not work with ng build -prod. Probably it is an AOT problem. I would like to know if there is something else that needs to be done, as I could not find a documented way of doing this. An example of the errors I get: ERROR in C:/Users/nekkon/Desktop/angular/orco-frontend/src/admin/$$_gendir/shared/other/core.root.module.ngfactory.ts (10,21): Cannot find module './core.root.module'.
````{
"compileOnSave": false,
"compilerOptions": {
"paths": {
"@orco/": ["./src/shared/"]
},
"outDir": "./dist/out-tsc",
"baseUrl": ".",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2016",
"dom"
]
}
}
I have a nested tsconfig.app.json which I also added the following code:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"paths": {
"@orco/": ["../shared/"]
},
"outDir": "../out-tsc/app",
"module": "es2015",
"baseUrl": "./",
"types": []
},
"exclude": [
"test.ts",
"*/.spec.ts"
]
}
My angular-cli.json is below:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "orco-frontend"
},
"apps": [
{
"name": "dm",
"root": "src/dm",
"outDir": "dist/dm",
"assets": [
{ "glob": "/", "input": "./assets/", "output": "./assets/" },
{ "glob": "favicon.ico", "input": "./", "output": "./" },
{ "glob": "/", "input": "../shared/assets", "output": "./assets/" }
],
"index": "index.html",
"main": "main.ts",
"polyfills": "../shared/other/polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "dm",
"styles": [
"styles.scss",
"../shared/other/styles.scss"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
},
{
"name": "protocol",
"root": "src/protocol",
"outDir": "dist/protocol",
"assets": [
{ "glob": "/", "input": "./assets/", "output": "./assets/" },
{ "glob": "favicon.ico", "input": "./", "output": "./" },
{ "glob": "/", "input": "../shared/assets", "output": "./assets/" }
],
"index": "index.html",
"main": "main.ts",
"polyfills": "../shared/other/polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "protocol",
"styles": [
"styles.scss",
"../shared/other/styles.scss"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
},
{
"name": "admin",
"root": "src/admin",
"outDir": "dist/admin",
"assets": [
{ "glob": "/", "input": "./assets/", "output": "./assets/" },
{ "glob": "favicon.ico", "input": "./", "output": "./" },
{ "glob": "/", "input": "../shared/assets", "output": "./assets/" }
],
"index": "index.html",
"main": "main.ts",
"polyfills": "../shared/other/polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "admin",
"styles": [
"styles.scss",
"../shared/other/styles.scss"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/admin/tsconfig.app.json"
},
{
"project": "src/dm/tsconfig.app.json"
},
{
"project": "src/protocol/tsconfig.app.json"
},
{
"project": "src/tsconfig.spec.json"
},
{
"project": "e2e/tsconfig.e2e.json"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"component": {}
}
}
P.S. Vscode detects the module and does not show an error. The module is not inside the project's folder.
Don't know if the reason behind my problem is the same with: https://github.com/angular/angular-cli/issues/6632. I don't understand how come ng serve and ng build work fine but ng build --prod doesn't. I think the problem is with AOT.
I am experiencing the same issue. It doesn't even work if you switch from tsconfig path to plain imports like import { DemoComponent } from '../../shared/components/demo'
A bit more detailed about my case: https://stackoverflow.com/questions/45234210/aot-compiler-generates-wrong-import
This problem seems to occur in shared library scenarios. The workaround for me is to use a tsconfig that is in a common root path of all shared libraries. You can still set the root of the app and reference the tsconfig as "../../tsconfig.hacketyhack.json". In the error you'll see $$_gendir is already in the admin app. The virtual file system represented by $$_gendir seems to start from the tsconfig location and can't navigate above itself. An additional AOT problem that resembles the rc.0 -> rc.1 fix occurs (even in rc.1) if the entrypoint ts is not included in the tsconfig (even though ng will include the main automatically). So you need to make a tsconfig for each app in the common root or include paths to all main.ts's for libraries sharing this tsconfig.
An official answer would be much appreciated. I believe that this should be fixed than implementing a workaround. The same code and file structure should be working with AOT from the moment ng serve/build works without it, don't you agree?
Marking as a duplicate of https://github.com/angular/angular-cli/issues/7087 since it's being tracked there already.
@EricABC Could you explain the workaround? I am trying with no success. I need this and from what I see it is not considered urgent by the angular-cli team, so I will have to try your workaround.
I get the following error after altering tsconfig.protocol.json
ERROR in ./src/protocol/main.ts
Module not found: Error: Can't resolve './../$$_gendir/protocol/app/app.module.ngfactory' in 'C:\Users\nekkon\Desktop\angular\orco-frontend\src\protocol'
@ ./src/protocol/main.ts 3:0-86
@ multi ./src/protocol/main.ts
tsconfig.protocol.json:
````{
"extends": "../tsconfig.json",
"compilerOptions": {
"paths": {
"@orco/": ["../shared/"]
},
"outDir": "../out-tsc/app",
"module": "es2015",
"baseUrl": "./protocol",
"types": []
},
"exclude": [
"test.ts",
"/.spec.ts",
"admin/",
"dm/*"
]
}
ng serve and ng build works fine again. ng build --prod (with aot) does not
@nekkon Perhaps the tsconfig needs to go up one more directory. I think paths using a '..' causes typescript to calculate a common root internally (not 100% sure), which is why you would still get an error for 'app' even though its not 'shared'.
My mono-repository looks something like:
I elevate several items to the root of the mono-repo, including tslint, angular-cli config, etc...
Only one node-modules folder at the root to avoid difficult-to-diagnose issues with inconsistent implementations of node resolution between several tools and karma/webpack spec resolution problems.
karma config similarly needs to not use any ..'s, so my tests.ts uses
const context = require.context('./modules', true, /\.spec\.ts$/);
All tsconfigs extend tsconfig.base.json
all have paths "@abcoa/": "./modules/" or "./Typescript/modules/*" for the root tsconfig
The .angular-cli.json has a first app called 'tests' that uses a root of 'Typescript' and './tsconfig.spec.json'. It points to a junk main.ts in Typescript/config because you can't have a tests-only app.
I think the need for a single test app as the first app is fixed after rc.1.
I use 1.3.0-rc.1+
Thanks @EricABC ! I managed to make it work and it builds properly with AOT.
Spent a great deal of time trying to understand this issue as well. It seems that ngc doesn't respect baseUrlor rootDir tsc arguments when generating the import statements within ngfactory modules.
As @EricABC mentioned, it appears the tsconfig file you target with ngc must exist at the most common root shared by all of your project's libraries.
Solution:
-- src/
---- tsconfig-base.json
---- tsconfig-ngc.platform-browser.json
---- app/
---- packages/
---- platform-browser/
------ aot/
-------- generated/
-------- main.ts
-------- tsconfig.json
------ main.ts
------ index.d.ts
---- platform-webworker/
------ aot/
-------- generated/
-------- main.ts
-------- tsconfig.json
------ main.ts
------ index.d.ts
When running ngc, previously I would target a platform config file, which messed up ngfactory import paths (ultimately the bug, because I provided a rootDir and baseUrl of "../../")
ngc -p src/platform-browser/aot/tsconfig.json
The solution is the tsconfig-ngc.platform-browser.json file in the source root:
{
"extends": "./platform-browser/aot/tsconfig.json",
"files": [
"platform-browser/main.ts",
"platform-browser/index.d.ts"
],
"angularCompilerOptions": {
"genDir": "platform-browser/aot/generated",
"skipMetadataEmit": true
}
}
I target that file with ngc and the original ./platform-browser/aot/tsconfig.json file with my build processes.
ngc -p src/tsconfig-ngc.platform-browser.json
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
@nekkon Perhaps the tsconfig needs to go up one more directory. I think paths using a '..' causes typescript to calculate a common root internally (not 100% sure), which is why you would still get an error for 'app' even though its not 'shared'.
My mono-repository looks something like:
I elevate several items to the root of the mono-repo, including tslint, angular-cli config, etc...
Only one node-modules folder at the root to avoid difficult-to-diagnose issues with inconsistent implementations of node resolution between several tools and karma/webpack spec resolution problems.
karma config similarly needs to not use any ..'s, so my tests.ts uses
const context = require.context('./modules', true, /\.spec\.ts$/);All tsconfigs extend tsconfig.base.json
all have paths "@abcoa/": "./modules/" or "./Typescript/modules/*" for the root tsconfig
The .angular-cli.json has a first app called 'tests' that uses a root of 'Typescript' and './tsconfig.spec.json'. It points to a junk main.ts in Typescript/config because you can't have a tests-only app.
I think the need for a single test app as the first app is fixed after rc.1.
I use 1.3.0-rc.1+