Thanks for all your valuable contributions to this space! I have been curious if development on Lucy is continuing? I might like to port some of my existing machines over if the project is still active.
You really don't have to worry about these things until your module graph is > 100 modules. You are falling into "all or nothing" thinking here, because you need tools in some use-cases doesn't mean that a feature is worthless. Not needing tools for small projects and then needing them for large projects is pretty good tradeoff.
I'm not sure what you mean by all or nothing thinking here. The problem with imports is precisely that it is incredibly cumbersome to use without a bunch of additional "add-ons". You can't just "use a little bit of it." Want to do the supremely simple task of importing a JSON file? Better make sure your browser supports import assertions (assuming one even knows these exist). Want to not have to import a long incomprehensible URL? Better write a manifest file called an import map that only recently got full browser support. You can't even trivially add a script tag with an ESM module because it won't work from a file:// domain, you have to start up a simple server for your simple.html file. So I have no idea where this notion of not needing tools comes from. I think what people actually mean is "my tools support ESM out of the box". It is not trivial to get a nice experience with zero tooling. Again, you at minimum need to run a server (and I believe you have to fiddle with the MIME types for python's one line simple server too, although perhaps that has now been rectified). The simplest projects require strictly more tools to use this thing. And on the opposite end of the scale, it appears that you agree that of course you will use tooling. Only hopefully those tools aren't generating imports but just bundling because if not they are creating slower and less secure resources.
ESM imports have fallen into the C++ trap: every year the determination is made that "if we just add these 5 extra features (both to the the ECMAScript spec and W3C spec), then they'll finally be great out of the box!" This is how we ended up with import.meta and dynamic import and import maps and import assertions and preloadmodule link tags, which are all still less flexible than require/bundler, and somehow still don't have any answer whatsoever to integrity checksums that originally shipped in 2015. It's absurd.
To be clear, I am not saying there shouldn't have been "an" import spec. I am saying this one is tragically flawed and remains realistically a bad option (unless you are using a compiler that is just going to turn it into roughly the same minified mumbo jumbo it was turning your requires into before). This is fairly well accepted at TC39. The spec was rushed. Nothing would be allowed to ship with that level of consideration anymore. Usually someone at this point asks "well what would you have done?!". I would have punted on import until after async/await. Many of the most fundamental issues in imports come from having to have conceived them in a pre-async/await world. They are essentially a "top-level-await-ish" statement, in a world with async/await. However, had async/await and top-level-await shipped first, and then import was introduced, you could have started with the expression form of import (await import()), which would not have required any new syntax (you could just use destructuring, the same way you do now), and not required a "exercise left to the host environment" hand-waivy async-link resolution system, but instead used the actual existing semantic of the language. We ended up having to do it anyways with dynamic import. It is so weird that `x as y` becomes `{ x: y }` and `x` becomes `{ default: x }` merely by moving the entrypoint around in the file. It would also be a lot more transparent to the user: by typing `const x = await import("blah")`, you aren't (erroneously) lead to believe that this is a synchronous action when it isn't. It's also way easier to add additional features to a function (such as integrity hashes or assertions or whatever), vs. in a statement where it requires a parser level change, and for no real benefit other than causing people to have to learn a bunch of weird new syntax that increasingly feels out of place.
> I'm not sure what you mean by all or nothing thinking here.
I mean this:
> Want to do the supremely simple task of importing a JSON file?
Surely you realize that "importing JSON" is not something every project or page needs. By "all or nothing thinking" I mean the idea, which you expand in this response, that unless it supports everything it's not worth ever using. But that's a false dichotomy. A lot of projects are simple. A lot don't need all of these advanced bundler features. Those projects can (and do) use bare ESM in the browser. And that's ok.
To answer your question more directly, the reason they do it this way is because bundling dozens of features into a spec and then releasing them all at once has never worked in the history of web standards. For better or worse, doing one small thing at a time is what works.
As someone on TC39, I can tell you that’s not why this was done this way. It’s an accident if history, and recognized as a rushed spec. The async/await first then import expression path I described would actually follow the “don’t ship one huge thing” (that then takes 5 years to implement) advice that you are suggesting.
> You can't even trivially add a script tag with an ESM module because it won't work from a file:// domain, you have to start up a simple server for your simple.html file.
This isn't an ESM problem. Last I checked this is still a per-browser security decision that applies to all JS, not just ESM, because browsers fear they can't trust malware or adware not to spread if file: were too open. (Thanks to such things in the IE days existing.) Too many developers are in Chrome 24/7 and forget that Firefox still exists and has good development tools and that Firefox allows file:// origin for scripts still in 2023 (with some caveats, but fewer than "doesn't run at all" as has been the Chromium default for a long time).
Also, I recall there are command line flags in Chrome to allow it if you really do want to use Chrome for development and can't just spin up a simple server on localhost.
It is an ESM problem, since it works just fine with non-ESM script tags. ESM isn't some theoretical thing, it's the reality of how it works, in particular when we are specifically discussing the practical reality of using it. And the fact is that it absolutely is more cumbersome than the old technologies (and more cumbersome than alternative approaches that could have been taken). The fact that we're now talking about launching Chrome with special command line flags demonstrates this. I mean, the rest of my comment that delves into all the other problems proves it even more, but the fact that it fails the bare minimum requirement of just loading when you drag and drop a file into the browser is fairly bad.
> It is an ESM problem, since it works just fine with non-ESM script tags.
This is not my experience. I've had many cases where Chrome security blocked non-ESM script tags to file: URLs (that Firefox was much more fine with).
The security mechanisms in the browser have gotten extremely sensitive (and rather baroque) and blocking file: by default is a part of that. This isn't an ESM-specific thing in any way, this is an overall browser security thing. It is a response to the arms race of malware.
People that have been writing/developing apps and scripts designed for local use (such as Twine) have been complaining about Chrome security defaults for years now for non-ESM development. "Drag-and-drop" of Twine games is generally only reliable on Firefox. There are so many obscure Chrome security issues that can break such games. This is not a new complaint for ESM.
(I didn't break down the "problems" with the rest of your comment because it was a bit of a rant and a lot of it felt to me more like opinions and bike shedding rather than "problems". I didn't think I can convince you that ESMs are good and wasn't going to try. I can point out the facts that script loading from local files is a Chrome [and IE] problem more than an ESM problem, because the facts back that up.)
If you expect to be able to develop with the file protocol you're going to be disappointed. Essentially all modern features don't work with it; not just ESM. You can't use Service Workers with the file protocol either.
It uses it to know what JS is needed for the client. If it sees <Section /> that means that no-JS is needed. But if it sees <Counter client:load /> it knows to build + bundle the Counter component and attach its JS to the page.
The reason why you don't know is that you've decided in advance that it's not actually needed.
.astro is not actually like MDX at all. MDX extends Markdown, Astro does not, it extends HTML. MDX is a variant of JSX, Astro is not, it supports things that JSX does not like void elements. Astro supports text inside of script and style tags, JSX does not.
If you think you can rebuild Astro with "a few extra preprocessor rules", then by all means go for it. But you're going to fail.
Most of those tools are focused on giving you a full SPA on the client (and therefore load a lot of JS). Astro is focused on sites that are mostly static with "islands" of interactivity. To that end every component is server rendered only, by default, and you opt-in to client render when you need it (with different loading strategies).
Currently you build a static site like you do with Gatsby or Jekyll or any other static site generator. In the future it will support dynamic server rendering.
I can't speak for every frameworks' SSG tool but most of them load a full SPA on the client and have poor performance. Go pick out a random website for Gatsby's showcase page and see how much JS is loaded (spoiler: a lot).
Astro focuses on partial hydration where you only load the JS for the specific components that need to run in the client. Very few tools and none of the framework SSG's that I'm aware of do this.
There's also a variety of other features that Astro brings, the blog post talks about them.
Not yet, Lit has support for SSR in prerelease and we've experimented with supporting it. Once it's ready it will be included. In the meantime you can of course use web components (with any framework) like you normally would, just without SSR.
Amusing to me to see the return to concepts that the dynamic web started with in the form of CGI, mod_perl, Cold Fusion, PHP, ASP.NET and all that. It’s the same, but different. Next we’ll be on to multi-tiered caching.
What’s the difference conceptually between islands and e.g. Hole-punching in Varnish? The result in each case seems to be a site that is mostly static with some dynamic portions.