_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 '../../../common/listutils.dart';
import '../../canvasutils.dart';
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';
_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';
_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.
_This comment was originally written by misja.a...@gmail.com_
I agree that something like a 'this' package would be a good solution.
_Added Area-Language, Triaged labels._
_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.
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.
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:
package: imports: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.
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.
@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.
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).
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";
+1 on either
import '/bar/baz/file.dart';
or
import 'package:/bar/baz/file.dart';
or ideally both
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
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.
Last thing I like seeing is ../../../../.....
馃槀馃槀馃槀
You can always use relative paths from inside the same package, so from
package:foo/bar/baz.dart, you can importpackage:foo/qux/qix.dartasimport "../qux/qix.dart";.
The only thing a/-rooted path will do is allow a _shorter_ import ofimport "/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.
Most helpful comment
+1 on either
import '/bar/baz/file.dart';or
import 'package:/bar/baz/file.dart';or ideally both