The Dart team's Medium blog announces Dart releases and explains language design choices such as sound types and nullable types.
HN commenters cite it for Dart's sound type system, the end of open-source AngularDart maintenance, and release news tied to Flutter.
The code seems generate to generate a very simple service worker that enables offline more for the web app: it puts the static assets in a cache that serves them if the network is down.
While it is a great start, and nothing wrong with that, I encourage people to check the more advanced features of routing and caching, where you have much better control of what is happening in the service worker. I have found the best JS library for that is sw-toolbox:
https://github.com/GoogleChrome/sw-toolbox
Shameless plug: I have also developed a Dart library for progressive web apps: https://github.com/isoos/pwa
One significant advantage of the library over the original solution is that you can have offline mode without sweating as much as 100-ish characters:
https://medium.com/dartlang/making-a-dart-web-app-offline-capable-3-lines-of-code-e980010a7815
(Scroll ~to the middle, super-simple to setup).
Another advantage is that cache invalidation is really hard. Neither the linked quickstart, nor the sw-toolbox addresses this, but there should be a way to control your cache updates, invalidations, and making sure you don't leave it in a broken state. Also, these should make sure that you don't pollute the user's browser too much.
My pwa package does cover a lot of these edge-cases, and I'm happy to answer questions wrt/ pwa caching if there are any.
(Next up: messaging solution between service workers, web workers, isolates...)
Flutter 3 comes with an upgrade to Dart 2.17 [1], which has quite a few improvements as well... including state on enums.
While that's great, I was hoping it would be like in Rust, where each enum variant can declare its own state components, but unfortunately it seems to be more like Java: same state for all variants.
Well, at least there's quite a few other small but useful improvements... and they showed how they really listen to the community by implementing the new syntax for passing on constructor parameters to a super-class... and by improving the docs of the 200 most popular packages with lots of examples, as requested by the people.
I like how they're listening to the community as well to implement meta-programming (like macros) [2] to solve the main pain point, currently, in Dart, which is how verbose it is to generate code for things like serialization and data types.
Once they get that, Dart will be a really good language to work on (it's already quite ok IMO, despite most people, usually those who don't actually use it much, hating on it).
[1] https://medium.com/dartlang/dart-2-17-b216bfc80c5d
[2] https://github.com/dart-lang/language/issues/1482
Dart actually observed this exact thing and added if expressions inside the language; more exactly, "if" works as an expression if it is inside of an initialization of a collection. It might seem a bit less elegant that the semantics of such an important token changes with context, but I think it solves this particular problem pretty well.
Dart also has spread operators and for-expressions to make writing "UI with code" much easier. It's fresh to see how language design choices are being made more by pragmatic ones (for Dart it's the fact that it's primarily being used for Flutter to make UIs) instead of ideological ones (One might claim that "if" should be a pure expression following the tradition from functional languages like ML, but that also has its own set of problems in a language designer's perspective)
https://medium.com/dartlang/making-dart-a-better-language-for-ui-f1ccaf9f546c
Runtime size depends on a few things. The biggest is JIT vs native. If you're willing to dedicate the time to making (or interfacing with) a completely native compiler, then the runtime penalty isn't that large. In contrast, any halfway decent JIT is going to be several MB of code (and unlike an image, has to be parsed and executed -- potentially on slow phones).
In both cases, the GC issue is non-trivial. LLVM has finally started to make performant GCs possible. Wasm (to my knowledge) doesn't have similar capabilities and guarantees (I suspect the are actually impossible with untrusted GC code). The only viable solution IMO is the addition of GC primitives and hope that your particular language maps well on that specific browser's GC.
https://medium.com/dartlang/dart-on-llvm-b82e83f99a70
Regarding AngularDart, see:
https://medium.com/dartlang/angulardart-flutter-and-the-web-spring-update-f7f5b8b10001
TL;DR - It's still heavily used inside of Google, but the team decided to stop maintaining the open source version of it. It was a fair bit of work to do both - different build rules, different tests / test infra, different priorities. Effectively, AngularDart has been forked. There is an internal-only version that is actively developed, and there is an external community project.
Regarding Flutter on the Web, there is a lot of active work, but I'm not the best to speak to all of it. On the Dart side, it's one of the major reasons we're investing in things like compilation to Wasm.
We recently added pattern matching to Dart [1], so I'm always keen to see how it compares to similar features in other languages. In case it's interesting, here's that Ruby example ported to Dart:
print(switch (
{'name': 'John', 'friends': [
{'name': 'Jane'},
{'name': 'Rajesh'}]})
{
{'friends': [
{'name': var firstFriend}, ...]} => "matched: $firstFriend",
_ => "not matched"
});
Pretty similar! The main differences are that Dart doesn't have symbols, so the keys are string literals instead. Also, variable bindings in patterns are explicit (using "var") here to disambiguate them from named constant patterns.
[1]: https://medium.com/dartlang/announcing-dart-3-53f065a10635