Skip to content

Bad absolute paths in TS auto imports due to new baseUrl #5875

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
cyrilletuzi opened this issue Apr 7, 2017 · 14 comments · Fixed by #6861
Closed

Bad absolute paths in TS auto imports due to new baseUrl #5875

cyrilletuzi opened this issue Apr 7, 2017 · 14 comments · Fixed by #6861
Assignees

Comments

@cyrilletuzi
Copy link
Contributor

cyrilletuzi commented Apr 7, 2017

- [X] bug report

Versions.

cli 1.0.0 (since rc.2)
typescript 2.2.2 (which is installed by default by the cli)

Repro steps.

typescript 2.2 introduced quickfixes for auto importing missing classes (in VS Code, a class not imported will be underlined in red, you can click on it, then on the bulb, and it would add the import).

with angular-cli rc.1, it would generate relative imports (the default behavior) :

import { SomeService } from './some.service';

since angular-cli rc.2, as a "baseUrl": "src" has been introduced in the root tsconfig.json, the auto imports are now generated with absolute paths :

import { SomeService } from 'app/feature/some.service';

And, unless I'm wrong, it's bad practice (in particular for refactoring).

@intellix says in #5353 baseUrl was introduced because :

When you're in VSC and write code like: import { environment } from 'environments/environment', it's flagged as being incorrect because the IDE doesn't know about tsconfig.app.json

But the CLI doesn't generate that, it generates this in main.ts :
import { environment } from './environments/environment';

which is the convention and which works perfectly fine, without baseUrl.

So except I'm missing something, this change should be reversed (I can do the PR if it's OK).

@intellix
Copy link
Contributor

intellix commented Apr 7, 2017

import { environment } from './environments/environment'; is fine from main.ts because it's easy to relatively import that. When you're inside a component that's going to look like:

import { environment } from '../../environments/environment';

and that's bad practise because you're tying yourself to the file system

@cyrilletuzi
Copy link
Contributor Author

To me, the relative import seems totally normal if the file is considered local to the project.

If it's considered as a global ressource and imported in a absolute way, should not it be registered somewhere like Angular modules (like from '@angular/core') ?

@filipesilva
Copy link
Contributor

We've actually had a fair amount of requests for this in the past. As codebases grow bigger, relative imports get more and more inconvenient.

I'll leave the issue open for discussion though.

@cyrilletuzi
Copy link
Contributor Author

Can you explain why relative imports are inconvenient ? Relative imports is the convention I've always seen in TypeScript until now, and if project global directories (like "/app") are renamed, relative imports will still work, while all absolute imports won't.

@filipesilva
Copy link
Contributor

In that specific example if you rename app some imports will still need to change (like the ones in main.ts). And the reverse is also true: if you move other directories around, both relative and absolute paths will have to change.

Here are some issues in the past where the topic was brought up and discussed: #865, #1465, #2747.

@Nehmiabm
Copy link

Nehmiabm commented May 12, 2017

I see that there are multiple discussions related to this issue so I just want to get confirmation. Is absolute paths possible in angular cli just by changing the tsconfig.app.json? I have tried that but still the error 'Module not found: Error: Recursion in resolving' shows up. Since my project files and feature modules are increasing, relative paths are not an option anymore. I would like to be able to use the 'baseUrl' and 'paths' configuration in tsconfig but it turns out this only works for the typescript intellisense.

@filipesilva
Copy link
Contributor

@bwalendz
Copy link

For anyone wanting to get rid of unwieldy long relative paths my solution was to add alias paths in root tsconfig.json

"compilerOptions": {
	"baseUrl": "src",
	"paths": {
		  // prefix with app- to prevent infinite recursion
		  "app-services/*": ["app/services/*"],
		  "app-models/*": ["app/models/*"]
	}
}

then the imports would look like:

import { UserService } from 'app-services/user.service';
import { User } from 'app-models/user';

@intellix
Copy link
Contributor

intellix commented Jul 20, 2017

@filipesilva you were originally against relative paths as you said: As codebases grow bigger, relative imports get more and more inconvenient. but you removed the src baseUrl property. Just wondering what changed your mind as I didn't catch the reasoning/discussion behind the change :)

@filipesilva
Copy link
Contributor

It was mostly this thread and @cyrilletuzi's arguments. It was unintended that the editor auto imports would be absolute. This was also a problem for e2e test auto imports, since they shouldn't be based on src/ but rather e2e/.

#6861 fixed that by moving the baseUrl to each individual tsconfig. That way they can still be used, just aren't forced.

Are you seeing any problems with the change?

@intellix
Copy link
Contributor

intellix commented Jul 20, 2017

I guess with e2e the baseUrl doesn't make sense at all.
Just that it says stuff like import { environment } 'environments/environment'; can't be found. I'm ok to manually enable baseUrl for my project though :)

I wonder if there's a way to tell VSC to use tsconfig.app.json and .spec.json for spec files

I think the actual fix would be for TS to support the ability to match configs based on file paths so you could have a single tsconfig.json for the whole project

@filipesilva
Copy link
Contributor

Ugh, that is a bad side effect indeed... but at least it's a side effect that doesn't happen automatically. Yeah I don't think we currently have a solution that really covers everything.

@seangwright
Copy link
Contributor

seangwright commented Aug 21, 2017

Is there currently a solution for using absolute paths? In version 1.3.1 of the cli the "baseUrl": "src" doesn't work for using absolute paths like import { ThingComponent } from 'app/thing/thing.component', whereas it did work in previous verion(s).

Absolute paths are really nice for refactoring when moving components or services around because the path to a module is the same no matter where in the app it is being used.

I can't tell from this discussion or from the related issues and PRs whether or not there is a way to accomplish this still.

If there isn't and it's not going to be a support feature that's ok, I'd just like to know.

Update--

If you set the root tsconfig.json "baseUrl": "src", and the tsconfig.app.json "baseUrl": ".", then both dev and AoT builds work.

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants