riverpod_lint 1.0.1
riverpod_lint: ^1.0.1 copied to clipboard
Riverpod_lint is a developper tool for users of Riverpod, designed to help stop common issue and simplify repetetive tasks.
Riverpod_lint is a developer tool for users of Riverpod, designed to help stop common issue and simplify repetitive tasks.
Riverpod_lint adds various warnings with quick fixes and refactoring options, such as:
- Warn if
runApp
does not include aProviderScope
at its root - Warn if provider parameters do not respect the rules of
family
- Refactor a widget to a ConsumerWidget/ConsumerStatfulWidget
- ...
Table of content #
- Table of content
- Installing riverpod_lint
- Enabling/disabling lints.
- Running riverpod_lint in the terminal/CI
- All the lints
- All assists
- Upcoming content:
Installing riverpod_lint #
Riverpod_lint is implemented using custom_lint. As such, it uses custom_lint's installation logic.
Long story short:
-
Add both riverpod_lint and custom_lint to your
pubspec.yaml
:dev_dependencies: custom_lint: riverpod_lint:
-
Enable
custom_lint
's plugin in youranalysis_options.yaml
:analyzer: plugins: - custom_lint
Enabling/disabling lints. #
By default when installing riverpod_lint, most of the lints will be enabled. To change this, you have a few options.
Disable one specific rule #
You may dislike one of the various lint rules offered by riverpod_lint.
In that event, you can explicitly disable this lint rule for your project
by modifying the analysis_options.yaml
analyzer:
plugins:
- custom_lint
custom_lint:
rules:
# Explicitly disable one lint rule
- missing_provider_scope: false
Note that you can both enable and disable lint rules at once.
This can be useful if your analysis_options.yaml
includes another one:
include: path/to/another/analys_options.yaml
analyzer:
plugins:
- custom_lint
custom_lint:
rules:
# Enable one rule
- provider_parameters
# Disable another
- missing_provider_scope: false
Disable all lints by default #
Instead of having all lints on by default and manually disabling lints of your choice,
you can switch to the opposite logic:
Have lints off by default, and manually enable lints.
This can be done in your analysis_options.yaml
with the following:
analyzer:
plugins:
- custom_lint
custom_lint:
# Forcibly disable lint rules by default
enable_all_lint_rules: false
rules:
# You can now enable one specific rule in the "rules" list
- missing_provider_scope
Running riverpod_lint in the terminal/CI #
Custom lint rules created by riverpod_lint may not show-up in dart analyze
.
To fix this, you can run a custom command line: custom_lint
.
Since your project should already have custom_lint installed (cf installing riverpod_lint), then you should be able to run:
dart run custom_lint
Alternatively, you can globally install custom_lint
:
# Install custom_lint for all projects
dart pub global activate custom_lint
# run custom_lint's command line in a project
custom_lint
All the lints #
missing_provider_scope #
Flutter applications using Riverpod should have a ProviderScope widget at the top of the widget tree.
Good:
void main() {
runApp(ProviderScope(child: MyApp()));
}
Bad:
void main() {
runApp(MyApp());
}
provider_parameters #
Providers parameters should have a consistent ==. Meaning either the values should be cached, or the parameters should override ==.
Good:
// Parameters may override ==
ref.watch(myProvider(ClassThatOverridesEqual()));
// Constant objects are canonalized and therefore have a consistent ==
ref.watch(myProvider(const Object()));
ref.watch(myProvider(const [42]));
// Passing a variable disable the lint, as the variable may be cached.
ref.watch(myProvider(variable));
Bad:
// New instances passed as provider parameter must override ==
ref.watch(myProvider(ClassWithNoCustomEqual()));
// List/map/set litterals do not have a custom ==
ref.watch(myProvider([42]));
stateless_ref #
Stateless providers must receive a ref matching the provider name as their first positional parameter.
Good:
@riverpod
int myProvider(MyProviderRef ref) => 0;
Bad:
// No "ref" parameter found
@riverpod
int myProvider() => 0;
// The ref parameter is not correctly typed (int -> MyProviderRef)
@riverpod
int myProvider(int ref) => 0;
generator_class_extends #
Classes annotated by @riverpod
must extend _$ClassName
Good:
@riverpod
class Example extends _$Example {
int build() => 0;
}
Bad:
// No "extends" found
@riverpod
class Example {
int build() => 0;
}
// An "extends" is present, but is not matching the class name
@riverpod
class Example extends Anything {
int build() => 0;
}
All assists #
Wrap widget with a Consumer
#
Wrap widget with a ProviderScope
#
Convert widget to ConsumerWidget
#
Convert widget to ConsumerStatefulWidget
#
Convert functional @riverpod
to class variant #
Convert class @riverpod
to functional variant #
Upcoming content: #
- Warn if a provider's
dependencies
parameter doesn't match theref.watch/read/listen
usages. - Refactoring to convert AsyncNotifier<>Notifier + autoDispose/family variants
- Warn if an
AsyncNotifierProvider.autoDispose
doesn't use anAutoDisposeAsyncNotifier
and much more