-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Similar to JavaScript/TypeScript ES Module syntax, create a linter rule that forces developers to explicitly show every imported symbol (e.g., classes, functions, constants, extensions) from a library or use the as keyword to explicitly import an entire library under a namespace alias symbol. This rule could be used by teams that would like to opt-in to have it be clear from the top of every file what library each symbol comes from. While static analysis and hovering over a symbol in an IDE can help you find what library something comes from, it is not possible to tell from a Pull Request/file view in GitHub or by simply looking at a raw file. Such a lint rule would make the code more readable when IDE tooling is not available. This lint rule should also be automatically fixable using tooling that exists today.
I'm curious what thoughts the Dart community has for such a rule. I'm a relatively new Dart developer so I'm sure I'm missing some important implications for such a rule and the encouraged use of it.
Justification
- Improved readability: By explicitly listing all imported symbols or using a namespace alias, it becomes immediately clear what is being used from each library without needing to rely on IDE tooling.
- Better code reviews: In code reviews (e.g., on GitHub), reviewers can easily see where each symbol originates without needing to cross-reference the IDE or search for definitions.
- Reduced namespace pollution: Explicit imports or namespace aliases prevent accidental usage of unintended symbols from a library, reducing the risk of conflicts or unintended dependencies.
- Consistency: Enforcing explicit imports or namespace aliases ensures a consistent style across the codebase, making it easier for teams to maintain and understand the code.
- Precedent in other languages: Languages like JavaScript/TypeScript and Python encourage or enforce explicit imports or namespace aliases.
- Existing Tooling support: This rule could be automatically fixable using existing tooling to reduce the burden of adoption.
Examples
Allowed
// Explicitly importing specific symbols using `show`
import 'package:example/example.dart' show MyClass, MyFunction;
// Using a namespace alias with `as`
import 'package:example/example.dart' as example;
void main() {
// Using explicitly imported symbols
MyClass myClass = MyClass();
MyFunction();
// Using symbols via the namespace alias
example.AnotherClass anotherClass = example.AnotherClass();
}Disallowed
// Importing the entire library without `show` or `as`
import 'package:example/example.dart';
// Importing a library with the `hide` keyword
import 'package:example/example2.dart' hide MyHiddenClass;
void main() {
// This usage is disallowed because it's unclear where the symbols come from
MyClass myClass = MyClass();
AnotherClass anotherClass = AnotherClass();
}Further Thoughts
Performance Impact
This rule should have minimal performance impact during linting, as it primarily analyzes import statements and their usage within a file.
Configuration Options
The rule could include configuration options such as:
- Allowing implicit imports for specific libraries.
- Intended for well-used core libraries (e.g.,
dart:core,package:flutter/material.dart) - Using
hidewould be allowed for these libraries.
- Intended for well-used core libraries (e.g.,
- Enabling/disabling the allowance of
asnamespace aliases.- Some teams may opt to avoid
asfor stylistic reasons.
- Some teams may opt to avoid
Naming
Rule name ideas:
explicit_importsexplicit_symbol_importsno_implicit_importsrequire_explicit_imports

