It's been too many years since I seriously looked at the problem, so my memory is fuzzy at best. But I do remember coming away thinking that it's a lot less of a magical or useful feature than I'd originally expected it to be.
It's been too many years since I seriously looked at the problem, so my memory is fuzzy at best. But I do remember coming away thinking that it's a lot less of a magical or useful feature than I'd originally expected it to be.
You can still `await import(someVariable)` and your tree-shaking will be limited at that point without a lot more manual configuration. But import syntax makes that an edge case, not the base case.
> You still need a build step to get value out of tree shaking, no?
ESM was also designed so that browsers can tree-shake at runtime. (Whether they will or not is an implementation detail based on whatever optimizations the browser's engine decides to make, of course.) Imports to modules that are never referenced by URL are never loaded, for one obvious part, that's the most basic form of tree-shaking in general, the browser never has a full view of your file system tree.
Beyond that, the module objects that `await import()` most directly returns (but are used to back all imports and are also represented as `something` in `import * as something from 'module'`) are designed to be "immutable" proxies that the Browsers can store as weak-references until needed and can in turn store the exports of that module themselves as weak-references. If the reference is never dereferenced it stands possible to be garbage collected like anything else. The browser might not have parsed anything beyond the top-level of a module and the name of the export, delaying paying any attention at all to the definition itself of that export until dereferenced. (It delays even parsing in some optimization cases; any JIT compilation is obviously delayed further until after parsing.) An export that was never parsed/compiled and eventually garbage collected away as the app ran is a very close equivalent to tree-shaking from an optimization standpoint (of nearly all but raw bandwidth/memory usage). The garbage collection churn isn't nearly as optimized as build-time treeshaking can be, but most engines have heavily optimized garbage collectors and there are worse garbage collection churn in the average application than that.
Relying on the browser to do most of your tree-shaking for you at runtime is maybe not the best idea, but ESM was certainly designed that browsers could optimize it as much as possible. There are still runtime benefits/optimizations to expect from ESM that CommonJS was never designed to support.
> How are polyfills done in a pure ESM world?
Maybe you could give an example? In my experience you’d just
import “polyfill-module”;
At the top of the file. But I suspect you have something specific in mind.