-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Proposal: Add lint to enforce package imports and avoid duplicate library loading
Summary
When mixing relative and package: imports for the same Dart file, Dart treats them as separate libraries.
This can lead to multiple instances of singletons or static state, breaking expected behavior in Flutter and Dart projects.
We propose a new lint rule to detect and warn about relative imports in lib/ directories, enforcing package imports to prevent this issue.
Problem / Usage Example
Investigation revealed the root cause:
- Related Flutter issue: [Web]The singleton pattern breaks. flutter/flutter#171324
The problem occurs because the singleton class is imported differently depending on the worker's environment
(this can be influenced by IDE auto-import behavior and other factors):
- Screen A:
import 'package:app_name/abc/app_manager.dart';- Screen B:
import '../../../abc/app_manager.dart';These imports currently create separate instances, breaking the singleton pattern.
This behavior is due to Dart's URI resolution:
- SDK issue: Two internal types created from one type declaration when a test uses relative imports #41868
- Language issue: Dart uses raw URIs for library identity. language#939
According to the Dart specification:
-
Section 19.5:
Note that a relative URI is interpreted relative to the location of the enclosing library (Section 19.7), which means that L1 and L2 may both have a part identified by 'myPart.dart', but they are not the same URI unless L1 and L2 have the same location.
-
Section 19.7:
A URI of the form package:s is interpreted in an implementation-specific manner.
Otherwise, any relative URI is interpreted relative to the location of the current library. All further interpretation of URIs is implementation-dependent.
In practice, this means that the same Dart file can be loaded twice under different URIs, causing multiple instances of singletons.
Proposed Solution
Introduce a new lint rule (e.g., always_use_package_imports) that:
- Issues a warning when a relative import is used in a
lib/directory - Encourages the use of
package:imports for all files withinlib/ - Helps prevent duplicate library instances and ensures singletons behave correctly
Example Configuration for projects
pubspec.yaml
dev_dependencies:
lints: ^6.0.0analysis_options.yaml
include: package:lints/recommended.yaml
linter:
rules:
# Enforce package imports
always_use_package_imports: true
prefer_relative_imports: false
analyzer:
exclude:
- build/**
- test/**Additional Considerations
- IDEs like Android Studio may generate relative or package imports differently depending on the user environment.
- Configuring the IDE to default to package imports would reduce the likelihood of this problem.
- This lint would not be a breaking change; existing relative imports would simply trigger a warning.