Skip to content
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

Feature request: import relative to project root #9289

Closed
DartBot opened this issue Mar 19, 2013 · 17 comments
Closed

Feature request: import relative to project root #9289

DartBot opened this issue Mar 19, 2013 · 17 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-not-planned Closed as we don't intend to take action on the reported issue P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@DartBot
Copy link

DartBot commented Mar 19, 2013

This issue was originally filed by misja.alm...@gmail.com


Right now import are relative to location of the file they are in. This has two disadvantages:

  • import statements can become hard to read and error prone when source files are organized in a folder tree, e.g.:

import '../../../common/listutils.dart';
import '../../canvasutils.dart';

  • when a source file is moved to another folder, not only do import statements referring to the file have to be adjusted, but also the import statements in the file itself.

I propose to have import statements which are relative to the root directory of their project or basedir, like for instance Java has.
So the import statements above would become something like:

import 'common/listutils.dart';
import 'mypackage/canvasutils.dart';

@DartBot
Copy link
Author

DartBot commented Mar 19, 2013

This comment was originally written by @seaneagan


You can do this with:

import 'package:current_package_name/foo.dart';

see http://pub.dartlang.org/doc/#importing-code-from-a-dependency

It might be nice to be able to reference the current package name via "this" or "self" though:

import 'package:this/foo.dart';

@DartBot
Copy link
Author

DartBot commented Mar 20, 2013

This comment was originally written by misja...@gmail.com


But that works only when the referenced file is within an external package.
It doesn't work when you have multiple files in separate folders within the source tree of your own module.

@DartBot
Copy link
Author

DartBot commented Mar 20, 2013

This comment was originally written by misja.a...@gmail.com


I agree that something like a 'this' package would be a good solution.

@madsager
Copy link
Contributor

Added Area-Language, Triaged labels.

@DartBot
Copy link
Author

DartBot commented Apr 22, 2013

This comment was originally written by @marcojakob


The problem is mainly for files inside the 'web' folder. See http://stackoverflow.com/questions/16147520/how-to-organize-dart-code-inside-web-folder

As I'm using many web components, I can't put them into the same library and omit the import statments since every Web Component must have its own library.

@DartBot DartBot added Type-Defect area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Apr 22, 2013
@kevmoo kevmoo added P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) and removed triaged labels Feb 29, 2016
@munificent
Copy link
Member

I propose to have import statements which are relative to the root directory of their project or basedir, like for instance Java has.

Dart doesn't have any concept of a "project" or "basedir", so I'm not sure how we could actually support this proposal. What it does have is a package root, and package: imports seem to work find for that.

For other imports, I think relative ones with ../ work out OK.

@munificent munificent added the closed-not-planned Closed as we don't intend to take action on the reported issue label Dec 19, 2016
@hmayer00
Copy link

I know this was closed a couple of years ago, but I was wondering if this was actually hard or problematic for some reason? I'd love to have something like import '/foos/bar.dart just import from the current package's lib folder.

I'm not in love with either of the current options:

  • Using relative paths:
    • I dislike that moving a file means changing the imports, since actually the contents of the file aren't/shouldn't be changing. So ideally in commit history you should show a file moved, but not that same file edited, in principle.
    • It's also just a pain to manage, and confusing to read - when looking at an import, I shouldn't have to first figure out where the current file is to figure out what files it's depending on.
  • Using package: imports:
    • If you change the name of your package, you have to change every file in your codebase. That just seems wrong, again in principle (the only thing you're changing is the name).
    • dartfmt and Effective Dart have a conflict (shocking, I know) with respect to package imports. The styleguide suggests grouping your package's own imports separately and after external package imports, which I think is good. However dartfmt puts all package: imports together alphabetically (which makes sense, since it doesn't know which is your package). But changing it to be import '/...' would allow dartfmt to treat it the way it treats relative imports (and fundamentally, it should be treated the way relative imports are, since they're all 'local' imports).

I don't know enough about how dart is compiled to know whether this is just impossible or awful for some reason. But if it isn't it feels like this would be a really nice addition to the language.

@munificent
Copy link
Member

I dislike that moving a file means changing the imports, since actually the contents of the file aren't/shouldn't be changing.

True. On the other hand, if you move an entire directory, then all of the relative imports in files within that directory that don't reach outside stay valid.

If you change the name of your package, you have to change every file in your codebase. That just seems wrong, again in principle (the only thing you're changing is the name).

Also fair, though in practice I think this is a fairly rare operation and a very easily automated one. A global find/replace of "package:old_name/" to "package:new_name/" should get this done in a second.

However dartfmt puts all package: imports together alphabetically (which makes sense, since it doesn't know which is your package).

Dartfmt doesn't do any import reordering. That's a different tool, either part of your IDE or part of the Dart analyzer plug-in.

I don't know enough about how dart is compiled to know whether this is just impossible or awful for some reason.

It's not impossible, but I'm not sure it carries its weight. We already support two ways to import files in packages: relative and "package:". Adding yet another way is more for users to learn, more for tools to support, more for people to argue about in code reviews, etc.

@hmayer00
Copy link

@munificent, thanks much for the responses. My bad on the dartfmt question, you are absolutely right that my IDE was doing that - still learning my way around the toolchain. And of course you're also right about the package-name change being rare (it was on my mind since my project has a working name that I know I'm changing later, but that's my problem not anyone else's, and this is ultimately a vanishingly small part of the problem that's gonna cause down the road).

One point on the "more for users to learn" question - I think a lot of people come to dart with a certain amount of web familiarity, and it's actually a bit confusing to not have the lib-relative option. Imports on the web would map relatively well (package: is like full url, ../ is unchanged, and / would be relative to the current package, like it's relative to the current host on the web). So I'm not sure how much the learning curve would be a factor, though of course plenty of people also approach it without a web background. Also my first reaction is "who would argue with that in a code-review?", but of course the answer is, as always, everyone.

The tool support comment is definitely legit and I have no response.

Anyway, sounds like you've done some thinking on this, so I'll stop being a pain. Thanks again for your quick and thorough reply.

@lrhn
Copy link
Member

lrhn commented Sep 17, 2019

It should be possible to change the relative reference resolution rules for package: URIs to keep the package name no matter what.
Then resolving ../../foo.dart against package:baz/baz.dart would resolve to package:baz/foo.dart, and more interestingly, so would resolving /foo.dart against the same base URI. (Basically, it treats package:foo/... as if it was package://foo/... wrt. relative URI resolution, which is how package URIs should perhaps have been designed to begin with).

The changes to the Uri implementations to do this are not big. It is one more special case to what are already some of the largest classes of the SDK.
(See https://dart-review.googlesource.com/c/sdk/+/117542).

@IvanDembicki
Copy link

How about this way?

path "package:myProject" as root;
path "$root/models" as models;
path "$root/views" as views;

import "$models/my_model.dart";
import "$views/my_view.dart";

@radeksvarz
Copy link

+1 on either
import '/bar/baz/file.dart';

or

import 'package:/bar/baz/file.dart';

or ideally both

@JasCodes
Copy link

JasCodes commented Nov 5, 2020

I copy projects as templates often and have search and replace everytime. Just give us name independant way to self import. Not asking something extraordinary

@lrhn
Copy link
Member

lrhn commented Nov 5, 2020

You can always use relative paths from inside the same package, so from package:foo/bar/baz.dart, you can import package:foo/qux/qix.dart as import "../qux/qix.dart";.
The only thing a /-rooted path will do is allow a shorter import of import "/qux/qix.dart";. It won't allow you to do anything you can't do today.

@JasCodes
Copy link

JasCodes commented Nov 5, 2020

Last thing I like seeing is ../../../../.....
😂😂😂

@radeksvarz
Copy link

You can always use relative paths from inside the same package, so from package:foo/bar/baz.dart, you can import package:foo/qux/qix.dart as import "../qux/qix.dart";.
The only thing a /-rooted path will do is allow a shorter import of import "/qux/qix.dart";. It won't allow you to do anything you can't do today.

The added value of the proposal is readability (visual hierarchy) and reusability (copy / paste / templates) simultaneously without the mental overhead of doing search / replace.

@adriank
Copy link

adriank commented Sep 2, 2022

Does anyone know if this is addressed? Import "/a.dart" works on all platforms but windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-not-planned Closed as we don't intend to take action on the reported issue P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

10 participants