Closed Jomik closed 4 years ago
IMHO,
I don't think using import
is a good idea in this case since I can't think of no case when we need to import either state or event without the bloc itself.
part
, in my opinion, represents splitting an otherwise "too long" single file to make it more readable as multiple parts.
In bloc's case, using import will force each subsequent usages to add 2 additional imports (the bloc itself + event + state).
Even if it now use imports and use a "barrel export" file, it's still 1 extra file which is I think unnecessary.
Btw, I might missed something, is that any cons of using 'part' that you found?
Honestly, the only "issue" is that the Dart team says to avoid using it.
I simply had not seen the part
directive before, so I researched it and found the above link.
I agree that your idea of part
makes perfect sense, and I am not bothered by it, nor have I found any cons, other than Dart saying to avoid it.
The solution, without a barrel file, would simply be having the bloc file export state and event:
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
import './bloc_event.dart';
import './bloc_state.dart';
export './bloc_event.dart';
export './bloc_state.dart';
And of course removing part of
from the state and event file.
@Jomik where does the dart team say to avoid parts? Packages such as json_serializable which are written and maintained by Googlers use parts and in this particular use case it makes a lot more sense in my opinion to treat events and states as part of the bloc file because you eliminate the need for extra exports or barrel files.
For context, the vscode extension used barrel files and exports initially and moved to parts because we felt it was simpler and made more sense.
part of
allows you to generate code for events and states into the "main" *_bloc.g.dart file which is a huge space saver in the explorer (unless you decide to hide generated files).
@felangel On the link in the issue description, in the blue box.
Note: You may have heard of the part directive, which allows you to split a library into multiple Dart files. We recommend that you avoid using part and create mini libraries instead.
Some Stack Overflow question also mentioned what you say with json_serializable, and speculates that Dart may implement something similar to C++'s friend
directive.
~I do not suggest using creating a barrel file at all :)
Personally I do not think that the way to use a bloc would change at all, with no extra file either. As the only file that needs to export is the actual bloc
. There should not be any imports between the state and event file.
I guess the only thing that happens, is that the state and event file would need to import the packages that is used to create them, e.g. equatable
.~
@ResoDev answered while I wrote the above š
I am personally not a fan of code generation, but if that is the case, then that is a huge plus for part of
.
Can you elaborate on what it can generate and what it gives you? What sort of code is being generated?
On a side note: do you suggest generating all blocs in lib/bloc
, or should each bloc be in its own sub folder under lib/bloc
?
@Jomik that link I believe is referring to when making libraries not when consuming libraries in an application.
What @ResoDev is referring to is if you use json_serializable or freezed for bloc events and states, with the part approach all the generated code will become part of the bloc.g.dart as opposed to generating separate files (event.g.dart and state.g.dart) respectively.
Regarding directory structure, I would recommend organizing by feature so each feature has its own bloc directory alongside the widget(s) as opposed to a single top level directory for all blocs.
@felangel Hmm. I guess that can make sense. Though, I wonder why it would be different for libraries versus the application we create.
I believe we can close this issue, I agree with your reasoning for using part
.
Thanks for elaborating. I see - so Freezed essentially makes State and Event immutable, but uses code generation to do so.
@Jomik Iām guessing they were just trying to discourage having a library with multiple parts in favor of independent mini libraries to improve reusability and encourage the single responsibility principle. I opened an issue to clarify this on the docs.
Freezed does a lot of things including supporting data classes, unions, and providing copyWith etc... all through code generation š
Closing for now then but feel free to include additional details/comments and Iām happy to continue the conversation š
I think part
is cumbersome as a developer. As you are writing these files, regardless of which one you start with, there are code insight errors which go away only when you have event/state/bloc written and all tied together. It's pretty unnatural.
I understand the pros as well, but I'm not sure ~addi~ moving a couple more lines to a barrel makes the case.
An IDE plugin or one-time generator to produce the basic scaffold (https://github.com/felangel/bloc/tree/master/bricks/bloc) might help, but I suspect that some enterprises might opt for a custom brick which adds things that match their patterns even more (e.g. importing Equatable, asking for state properties and types, freezed, etc). There is a lot more boilerplate which can be taken care of at the same time using a cli-tool.
On the plus side, I suppose it is a matter of choice, and I don't think either approach is broken in any way. I'm only just starting my journey, so I might feel differently after a few months.
The parts approach violates the principle of least astonishment (POLA), at least for me.
When I initially read the code and saw the part decleartion it made me consider if this code is somehow generated.
I'm not arguing against using parts, as the matter should be viewed from several angles,
Describe the bug VSCode Extension generates code containing
part
andpart of
, even though they should be avoided.Expected behavior Use
import
to import bloc state and event files.Additional context https://dart.dev/guides/libraries/create-library-packages#organizing-a-library-package