-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Development server inexplicably strips type="module" from <script> tag #9716
Comments
Further to this, |
I am also affected by this, any workarounds? |
In development we don't use esm, so this is intentional. What is broken about it for you? |
What? Is that really true? Development should use ESM so I don't have to build the whole app at once... manual bundle splitting is the worst, and also impossible right now because:
Is there any way to force the dev server to use ESM properly? |
It shouldn't matter. ESM is just a syntax. What parcel outputs is an implementation detail that shouldn't affect the behavior of your source code.
I don't understand this. That has nothing to do with ESM output. |
It matters when Parcel has to rebuild the bundle every time I change any module. Because the app can't even start to load until the entire bundle is rebuilt, because Parcel has to come up with a single file that contains every module. Hot reload works once, but if you change a file multiple times in a row, then the other changes have to wait for the first entire bundle rebuild to complete. It's super slow and annoying. |
The ESM format does not affect whether you bundle or don't bundle. Those are separate concerns. You can bundle both ESM and non-ESM or not bundle both ESM and non-ESM. Switching to type=module does not make it non-bundled. Parcel delivers HMR updates before packaging finishes via a websocket, so it should update quickly regardless what module format you use. If you don't want a bundler at all and just want an ESM dev server then I'd suggest a different tool. Parcel is a bundler and will continue to be. |
OK, thanks for the clarification.
This is (partially) incorrect. If you make one edit, then the HMR update is indeed instantaneous. However, if you make another edit before the bundle has finished fully rebuilding, then your edit won't be applied until the first update has finished rebuilding the entire bundle. Our app requires almost a minute to rebuild the whole bundle, so this really hurts. I don't want to wait for our huge bundle to compile just to iterate rapidly on a single module. :/ I think this would suggest that Parcel builds the edited module first, sends out the update, then begins to rebuild the bundle. Then it refuses to do any other tasks until the bundle build is complete. So any additional HMR updates are delayed. |
I'm confused, |
To some degree this is to be expected because production builds don't have hot reload or anything. I just hate that Parcel has to build every module into a single JS file before the webpage can even load. I wish it could build/load modules individually/lazily like Vite does. Native ESM import would be amazing. |
Obviously the output can't actually be identical, but I would've expected it to function as if it was the same. Edit: doesn't look like vite does what i need (it does top level await, just not some other stuff), guess i have to just rewrite the top level await stuff and just hope this isn't a problem again... |
That seems to be the consensus, according to Parcel devs? They say parcel is a bundler so if you don't want it to bundle your code then switch to something else. This is difficult to do for our company monorepo but if that's really the attitude then I'll keep pushing to switch to Vite. It doesn't exactly help that Parcel miscompiles code as well. |
Vite supports top level await in ES modules, not sure why that would be the limiting factor here. I think Parcel also supports it but only in production builds because dev builds are CJS for no good reason... |
That's always been the case. Minification, tree shaking, and lots of other stuff doesn't run in development. The other important difference is HMR, which requires a different module format so that modules can be replaced. Native ESM modules cannot be replaced in the browser's module cache, so we need a custom format for that. Regardless, these are implementation details and shouldn't matter too much as long as the behavior is the same.
This also has some downsides. It just moves the work from the bundler to the browser. This may actually be slower because the browser needs to download many more modules on each page load, each of which has overhead, vs downloading a single bundle. We did this long before bundlers, e.g. require.js, and bundling was partially a response to this to improve performance. With many modules, bundling is faster. Vite's approach is ok for smaller apps, but slows down as your app grows.
This seems like something we could potentially improve. But that's a totally different problem than this initial issue. Perhaps focusing on the issues you're encountering rather than the solution would be a good place to start. |
But it isn't, I can do top level awaits in one and not in the other... If you read my comment you'll notice I said "differently functioning outputs", I understand that they will, under the hood, work differently, but it's not just an "implementation detail" if it makes a noticeable difference to the end result... Edit: To be clear, I understand if parcel doesn't/won't support top level awaits at all, but I would've preferred it not work immediately instead of breaking sometimes, because it wasted my time. |
I don't see the bundle as necessary whatsoever in development if the individual module can be rebuilt and applied just fine without ever even thinking about a bundle. So the most obvious solution in my eyes is to stop building everything into a single file during development. Why fix only one symptom when you can fix the root of the problem? Is Parcel determined to stay in the past or something? Is there a reason why the entire bundle has to be rebuilt every time any file changes? I'm OK filing an issue for the HMR slowness if that sounds like something you'd be interested in fixing. One of the main reasons I haven't already done that is because I'm pretty sure trying to do anything in parallel is what has resulted in constant "expected content key <id> to exist" errors (or in other words, "there's a good reason it's done this way"), which is why I have to restart the Parcel server nearly every time I switch branches or perform any multi-file refactors. Of course, sometimes instead of throwing any actual error, the server just craps the bed and stops rebuilding anything, even though it still responds to requests. Which is annoying as hell and also super misleading as the code in the browser is perpetually out of date until the server is restarted (which has to be achieved via Not sure how valuable it would be for me to file bug reports for every issue I've ever encountered with Parcel. My experience is that many of the issues I'm having were filed years ago and no effort is being put into diagnosing or fixing them. (If you say you're all unpaid volunteers and I'm not entitled to anything, then that's why I don't generally file issues with the expectation of them being fixed! Because I know I don't personally have time to investigate them.) |
TLA support is a different issue: #4028. Unfortunately it's quite difficult to implement.
You would definitely notice the performance issue even in development when you start loading thousands of individual modules as separate requests. This happens every time you load every page, even with browser caching, rather than only when you change a file (and we don't need to rebuild bundles for pages that didn't change). See this thread on the Vite repo for some reports from their users with large apps: vitejs/vite#4803. There are definitely tradeoffs on each side, neither option is a silver bullet. |
I would think so, probably because of scope hoisting or something. And also the fact that module loading suddenly becomes asynchronous, and you might want to cancel the Promises e.g. in the case of HMR. I authored a Node.js package that let you use |
We no longer remove |
🐛 bug report
Development server inexplicably strips type="module" from <script> tag, breaking the page. The normal build process does not do that.
🎛 Configuration (.babelrc, package.json, cli command)
No config.
Input HTML:
🤔 Expected Behavior
Don't remove type=module
😯 Current Behavior
type=module is removed from the script tag in development server build only.
💁 Possible Solution
🔦 Context
Can't leverage dev server
💻 Code Sample
npx parcel --no-cache app/index.html
🌍 Your Environment
Mac OS
The text was updated successfully, but these errors were encountered: