Avoiding relative paths in Angular CLI
Solution 1:
Per this comment, you can add your application source via paths
in tsconfig.json
:
{
"compilerOptions": {
...,
"baseUrl": ".",
"paths": {
...,
"@app/*": ["app/*"],
"@components/*": ["components/*"]
}
}
}
Then you can import absolutely from app/
or components/
instead of relative to the current file:
import {TextInputConfiguration} from "@components/configurations";
Note: baseUrl
must be specified if paths
is.
See also
- https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
Solution 2:
Thanks to jonrsharpe's answer for pointing me in right direction. Although, after adding the paths
, as defined in answer, I was still not able to make it work. For anyone else facing same problem as me in future, here's what I did to fix the issues.
I have a shared module and its services are being used in multiple components, so...
tsconfig.json:
{
"compilerOptions": {
...
"baseUrl": ".", //had to add this too
"paths": {
"@shared/*": ["src/app/modules/shared/*"]
}
}
}
After this, VS Code was able to resolve the import
but I still got following error from webpack
while compilation.
Module not found: Error: Can't resolve
To fix this I had to add
-
baseUrl of tsconfig
inwebpack's resolve.modules
-
paths of tsconfig
inwebpack's resolve.alias
webpack.config.js:
resolve: {
extensions: ['*', '.js', '.ts'],
modules: [
rootDir,
path.join(rootDir, 'node_modules')
],
alias: {
'@shared': 'src/app/modules/shared'
}
},
component.ts:
import { FooService } from '@shared/services/foo.service'
import { BarService } from '@shared/services/bar.service'
import { BazService } from '@shared/services/baz.service'
To make it even more cleaner, I added an index.d.ts
inside services folder and exported all my services from there, like this:
index.d.ts:
export * from './foo.service';
export * from './bar.service';
export * from './baz.service';
and now inside any component:
import { FooService, BarService, BazService } from '@shared/services';
Solution 3:
Above all answer correct, but after struggling by searching over internet n trying to understand what exactly problem and trying different troubleshooting option, I came to know baseUrl and Path how works toghether
If you use baseUrl:"." like below it works in VScode but not while compiling
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"baseUrl": ".",
"paths": {
"@myproject/*": ["src/app/*"]
}
}
As per my understanding and my working app and checked in angular aio code, I suggest use as baseUrl:"src" like below
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"baseUrl": "src",
"paths": {
"@myproject/*": ["app/*"],
"testing/*": ["testing/*"]
}
}
By having base url as source(src directory), compiler properly resolves modules.
I hope this helps to people resolve this kind of issue.
Solution 4:
Not sure why but when I tried the other answers in VS2017, I was able to compile Angular without errors but I was still seeing errors in VS "Cannot find Module ...". When I set the baseUrl to "src"
from "."
everyone was happy.
tsconfig.json
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"typeRoots": [
"node_modules/@types"
],
"baseUrl": "src", // Main source directory same level as tsconfig
"paths": {
"app/*": [ "app/*" ], // src/app
"ui/*": [ "ui/*" ], // src/ui
"services/*": [ "services/*" ], // src/services
"assests/*": [ "assests/*" ], // src/assests
"models/*": [ "models/*" ] // src/models
},
"lib": [
"es2017",
"dom"
]
}
}
Then to import:
import { AppMenuComponent } from 'ui/app-menu/app-menu.component';
Note: If Visual Studio is still throwing errors try either closing and reopening the file or restarting Visual Studio to get it to recognize the new paths.