refi64 / vuedart

Create Vue web apps in Dart
https://refi64.com/vuedart
310 stars 19 forks source link

0.5 / 0.6 / etc release plans and the future of VueDart #40

Closed refi64 closed 5 years ago

refi64 commented 5 years ago

So I figured I'd drop this to say what the future plans for this project are, just to keep people in the loop of the future plans. First off VueDart isn't going anywhere, just saying because usually when someone titles and issue with "future of XYZ" it means that the project is about to be abandoned and/or go downhill. None of that here!

Now release plans:

0.5

0.5 will be the last version that supports Vue 2.x! For 0.6, Vue 3.x will be required. (Details below.)

So, the basic idea is that VueDart 0.5's primary thing is going to be what I want to be one of the last breaking API changes: reaching a similar-ish API to Vue 3.0 TypeScript. It will largely be preparation for what should be a smoother 0.6 release.

It would look a bit like this:

@VueClass
class MyComponent extends Vue {
  // yes this looks kinda stupid, the planned API for template isn't entirely final
  @VueTemplate
  final String template = '<<';

  final components = <Vue>[AComponent(), BComponent()];

  @Prop()
  int myProp;

  // Any instance vars are automatically marked as data (no @data needed)
  String myData = 'abc';

  // Any getters / setters are automatically computed props
  List get something => [];

  // Any non-static methods are automatically Vue methods
  void doStuff();
}

Lifecycle methods may drop the lifecycle prefix I added previously because that was an incredibly stupid change and I want to change it back before I regret my life choices.

(The other thing I want is async component support, I still want to finalize the API but some support for it is already on master, most likely you'll put something like import 'my_module.dart' deferred as my_module; @VueAsyncImport(my_module.MyAsyncComponent) /* or (#my_module) and automatically infer the name based on the variable */ Vue MyAsyncComponent;.)

Now some context for this: in Vue 3.0, we have proxies, which should give is magic deep reactivity for our Dart objects. This means that it would be impossible to have non-data instance vars anyway, so might as well dive in.

Other than that, the release is minor-ish. Aspen has been completely revamped, which does mean I'll be able to include Vue itself in VueDart without requiring e.g. extra deferred script components, though this will be optional (e.g. you can still ship your own Vue, this will not be recommended for reasons I'll go into on the next section). This also means vdmc should become generally usable (though again, more notes on that later).

Target release time: May or June.

0.6

0.6 an onwards will be Vue 3.0-only! This will basically allow for some pretty nice code cleanup to boot, at minimum. The main plan for 0.6, however, is to interface with the actual Vue template compiler (the developer will be required to either have Node or Docker/podman installed) to allow for compiled templates, which also means that you will be able to use normal Dart code inside your templates! To prepare for this, it's highly advised that your templates be written in a way where they would work on both Dart and JS, e.g.:

This is also why it's recommended that you use the VueDart-included Vue from here on, since I'm not sure how the relation between Vue 3.0's compiler API and the JS compatibility will be.

Target release time: Maybe Q4 this year, most likely 1-2 months after Vue 3.0 is out (unless I end up having stuff ready ahead of time).

Road to 1.0

Other things in the future:

Material components

This is just a sucky part of the Vue ecosystem right now. I had chosen material-components-vue because it's based on Google's official Material Components for Web, so in the worst-case scenario, it would be possible to move directly to Material Components (which I do want to do at some point when VueDart is more mature). Unfortunately apparently there are some maintenance issues associated with it, and:

On that note, vdmc will likely be published alongside VueDart 0.5, because again now that Aspen actually inlines assets, the mess of downloading URLs from unpkg in the generate.dart script can go away.

Major deficiencies right now

Some other stuff that will be resolved by 1.0 but with no particular timeline:

New exciting stuff in the future

Should I use VueDart for a production application yet?

Probably not, simply because right now it won't have the community that I'd recommend for a full-on production application, and I may not always have the time to answer questions and help out like would be needed. That being said, if you have some sort of side project, feel free to try it! (Though maybe wait until post-0.5 unless you feel like making some changes due to the new APIs.)

Closing thoughts

The growth of VueDart has been pretty insane; it's the most-starred repo I have and was published at the perfect timing between Vue's explosive growth and Dart's own growth (largely due to Flutter). This shouldn't take as long as some previous releases have cough the last two cough, since I have a clearer game plan and am not trying to pack 20 things into one release like before.

Happy...Vue-ing? Dart-ing? Uhh... nvm

refi64 commented 5 years ago

Well, seems like the the class API proposal has been dropped. I'm not quite sure how to treat this entirely in VueDart yet (Dart has classes at its core, JS has them added on, and the latter seemed to be one of the causes for concern). However, I did spend some time thinking about an API if VueDart were to go the "composition functions" route; it would require the use of an ancillary state class (as Dart does not have structural typing), but Flutter already does that and it's not too bad. It would probably be a bit like this (converted version of the Vue proposal):

class App extends Vue {
  // Anything here is automatically a prop.
  final String a;
  final int b;

  final components = <Vue>[MyComponent(), MyOtherComponent()];
  final template = '...';

  VueState setup()  => AppState();
}

class AppState extends VueState<App> {
  // This may have to be something like Value<int>, unsure how the version shown here would
  // play with reactivity.
  int count = 1;
  // If the above were Value<int>, this would be count.value.
  int get plusOne => count + 1;

  void inc() => count++;

  void setup() {
    // component refers to the original component (App).
    watch(() => component.b, + count, (val) {
      print('changed: ${val}');
    });
  }

  @override
  void onMounted() { ... }
}

At the same time, the double-class system feels a bit...wordy for simple components. We'll have to see, I guess.

refi64 commented 5 years ago

So thinking about this more, I think part of the trouble is that Dart and JavaScript / TypeScript are fundamentally different languages:

So there's still the ability to stick to the original API plans... I can understand why Vue went with the system it did given their constraints, but a lot of those simply don't apply to Dart in the same way, and we end up with this dual-class layout thing because Dart doesn't have structural typing. From my perspective, trying to use the new API style feels like a crappier version of the abandoned, class-based proposal.

On the other hand, the entire point of this was to try to bring it closer to the TypeScript API, but I just really don't want it to feel unnatural from the Dart standpoint.

That being said, either way the new watch syntax being a function is being used; it's quite the improvement over the current VueDart system.

refi64 commented 5 years ago

Well the new functional API threw a giant curveball into these plans so I'm just closing this for now.

hjianjie commented 5 years ago

Expected version 0.5