How can I introduce something like 'my-app-name/services'
to avoid lines like the following import?
import {XyService} from '../../../services/validation/xy.service';
To fix this, all you need is to set a compilerOptions. baseUrl config in your project's tsconfig. json file. So, if we want to make the src folder (which sits at the root of the project) as the base of every import, we can set it like so.
Relative path Relative paths make use of two special symbols, a dot (.) and a double-dot (..), which translate into the current directory and the parent directory. Double dots are used for moving up in the hierarchy. A single dot represents the current directory itself.
The option “Do not import exactly from” allows you to tell the IDE that you don't want any imports that are from the specific path (e.g. @material-ui/core ) or path pattern (e.g. @material-ui/core/** ). The IDE will then use an alternative path if there is one.
Module resolution is the process the compiler uses to figure out what an import refers to. Consider an import statement like import { a } from "moduleA" ; in order to check any use of a , the compiler needs to know exactly what it represents, and will need to check its definition moduleA .
In TypeScript 2.0 you can add a baseUrl
property in tsconfig.json
:
{
"compilerOptions": {
"baseUrl": "."
// etc...
},
// etc...
}
Then you can import everything as if you were in the base directory:
import {XyService} from "services/validation/xy.service";
On top of this, you could add a paths
property, which allows you to match a pattern then map it out. For example:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"services/*": [
"services/validation/*"
]
}
// etc...
},
// etc...
}
Which would allow you to import it from anywhere like so:
import {XyService} from "services/xy.service";
From there, you will need to configure whatever module loader you are using to support these import names as well. Right now the TypeScript compiler doesn't seem to automatically map these out.
You can read more about this in the github issue. There is also a rootDirs
property which is useful when using multiple projects.
I've found it can be made easier by using "barrels".
index.ts
file.Example
In your case, first create a file called my-app-name/services/validation/index.ts
. In this file, have the code:
export * from "./xy.service";
Then create a file called my-app-name/services/index.ts
and have this code:
export * from "./validation";
Now you can use your service like so (index
is implied):
import {XyService} from "../../../services";
And once you have multiple files in there it gets even easier:
import {XyService, MyOtherService, MyOtherSerivce2} from "../../../services";
Having to maintain these extra files is a bit more work upfront (the work can be eliminated using barrel-maintainer), but I've found it pays off in the end with less work. It's much easier to do major directory structure changes and it cuts down on the number of imports you have to do.
Caution
When doing this there's a few things you have to watch for and can't do:
import {XyService} from "../validation";
). I've found this and the first point can lead to errors of imports not being defined.Better to use below configuration in tsconfig.json
{
"compilerOptions": {
"...": "reduced for brevity",
"baseUrl": "src",
"paths": {
"@app/*": ["app/*"]
}
}
}
Traditional way before Angular 6:
`import {XyService} from '../../../services/validation/xy.service';`
should be refactored into these:
import {XyService} from '@app/services/validation/xy.service
Short and sweet!
I just came across this question. I know it's way back now but for anyone coming across it there is a simpler answer.
I came across only because something I had been doing for a long time stopped working and I was wondering if something had changed in Angular 7. No, it was just my own code.
Regardless I have only had to change one line in tsconfig.json
to avoid long import paths.
{
"compilerOptions": {
"...": "simplified for brevity",
"baseUrl": "src"
}
}
Example:
// before:
import {XyService} from '../../../services/validation/xy.service';
// after:
import { XyService } from 'app/services/validation/xy.service';
This has worked for me pretty much ever since Angular-CLI came along.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With