philipwalton / webpack-esnext-boilerplate

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Initial and async `.mjs` chunks are loaded differently (async `.mjs` are loaded as "classic" JS)

jakub-g opened this issue · comments

There's one thing that is not immediately obvious when using the module/nomodule technique with webpack 4: the initial modern chunks (declared as <script type=module> in HTML) will be fetched and evaluated as ES modules, whereas the async chunks will be fetched and evaluated as "classic" JS (this is because what webpack outputs is just a regular ES5-compliant bundles, and we just load them as ES modules, which "just works").

I'm not sure what are the full implications of this yet. Perhaps in reality there are none. But I just though I'll open this ticket to make everyone interested aware of this.

There are some well known differences about ES modules compared with "classic" JS:

  • modules are always parsed in strict mode
  • this is undefined in modules
  • ...

It might be that due to the way webpack packages things, none of this matter at the end of the day.

One thing that does matter is if you use preload; the initial chunks are modules, so you'd need modulepreload, whereas the async chunks are "classic", hence normal preload does the job. (If you implement preloading differently, you'll end up with double downloads). I did a POC of that in https://github.com/jakub-g/webpack-esnext-boilerplate/pull/1/files#diff-d13e648c450173d77b5e04da795274fd if someone's interested. This sounds like a dirty hack though.

When I learn more things, I will write my discoveries here.

Yes, that's true. When I originally wrote the article promoting this strategy, pretty much 100% of developers were transpiling all their JS to ES5, so the fact that webpack would load its async chunks as classic scripts wouldn't change any behavior. The only change in behavior would be the initial module load, but I tried to cover those difference in my article.

If you're looking for a solution that incorporates dynamic import(), I'd check out Rollup v1, which just came out and supports this.