// lib/my_library.dart
library my_library;
class MyClass {}
// lib/a.dart
import 'my_library.dart';
compare(Type type) => type == MyClass;
// main.dart
import 'package:my_library/my_library.dart'; // importing MyClass
import 'lib/a.dart'; // importing compare, which imports MyClass
main() {
print(MyClass == MyClass); // true
print(compare(MyClass)); // false
}
Whereas importing both a.dart
and my_library.dart
as a package:
URI, or as a relative path, results in both statements printing true:
// main.dart
import 'lib/my_library.dart'; // importing MyClass
import 'lib/a.dart'; // importing compare, which imports MyClass
main() {
print(MyClass == MyClass); // true
print(compare(MyClass)); // true
}
// main.dart
import 'package:my_library/my_library.dart'; // importing MyClass
import 'package:my_library/a.dart'; // importing compare, which imports MyClass
main() {
print(MyClass == MyClass); // true
print(compare(MyClass)); // true
}
If I want to interact with a type _within_ a library, but I send the type I want to interact with from _outside_ the library, even though the type is declared _within_ the library, strange inequalities results in weird behaviour.
That is the expected behavior. A library is _identified_ by the URI used to point to it (after resolution and nomalization).
If you use two different URIs to import what ends up being the same file, it's still treated as two different libraries, each defining its own version of the class. You _should_ get a warning because you have imported two libraries with the same name, which is a good way to detect this problem.
The solution here is to always refer to a package library using a package:-URI (except inside the package's lib/ directory itself). Or, in other words, never ever write "lib/" as part of an import.
I see. However, in my case, the package has multiple libraries. Like so:
lib/
a.dart // is library
b.dart // is another library that imports a
c.dart // outside library, imports both a and b, and want them to agree on classes
That means, to make sure b
and c
identifies classes in a
as equal, b
must import a
with a package:
URI. Even though they are in the same _package_ (share lib directory).
It's not really a problem, but it seems the convention to only use package:
from the outside of a package might result in unexpected behaviour.
Shouldn't the convention then be: _ALWAYS use package:
when importing _public_ libraries, and ONLY use relative path when it is private to the package_ ?
If you always import package libraries (this in the lib/
dir of a package) using a package:
URI from any other place, then it's ok for the libraries in a lib/
dir to refer to each other using relative paths. The relative path will be resolved against the library's own URI, which will then always be a package:
URI, and all is well.
What usually goes wrong is that you refer to a library in a lib/
dir directly from somewhere in the same package (in test/
or in bin/
perhaps), or even that you run one of them directly as a script. Being in the same package structure is not enough, it's being in the same lib/
dir that's the rule for when you can use relative references.
Using a package:
URI to refer to a different file in the same lib/
dir will not prevent a problem - using a relative path is only a problem if the importing library was imported improperly, so you already have a problem that should be fixed. If anything, getting an error is a good way to catch that problem (but so should duplicate library name warnings).