-
Notifications
You must be signed in to change notification settings - Fork 28
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
Use of eval and local variables #95
Comments
Hey @MartinSherburn, thanks for the question! The problem with generating a single source map isn't a technical constraint, but rather a performance one. Generating a single source map for an entire bundle for every file save can be costly from what I've seen so far. It would require collapsing source maps one by one. Using As for local variables, as far as I can tell, local variable access will more or less always be needed. Modules will need access to Hope this helps clarify things! Out of curiousity though, what is the use case for running outside of NodeJS? :) |
Thanks for the quick and thorough reply @PepsRyuu. I agree that generating a single source map for the entire bundle on every file save would be a problem. But I don't think you need to do that for HMR to work. What I am suggesting is:
Regarding
These are the changes that are currently generated when the file is saved:
And what I am proposing is generating this instead:
I have removed the call to |
The problem there is that generating a full bundle again is needed. The assumption being made there is that HMR will always be perfect and be used everywhere, and while in theory this would be ideal, it's not applicable for all scenarios. Two frequent scenarios come to mind:
In those situations, only bundling at the beginning would mean that your code is out of sync with the generated bundle on a page refresh. It would introduce delays of several seconds for very common use cases. |
Right, yes indeed there are cases where generating a full bundle is required. One thought here would be to only re-generate the bundle at the point where it is requested by (i.e. on HTTP GET request). Then you only pay the cost of regenerating the full bundle when HMR fails and it has to fall back to a full reload. But I understand your concerns about frameworks that don't have any HMR at all. |
Lazy loading at point of request would work for HMR users, but would mean a page refresh would take several seconds for both HMR and Hot Reload users. Wouldn't be a great developer experience and would likely result in several complaints from users. It might be worthwhile posting an issue on those JavaScript engine projects and see what their position on |
Thanks for the discussion @PepsRyuu, this was useful. I have already raised the issue with the Hermes developer as well. |
Trying to debug some code with WebStorm, which doesn't let you to put breakpoints in "virtual" (nollup://) files as far as I know I stumbled upon this and I have a question: if it's hard to combine source maps, then why combine multiple files into one? Why not just keep the same number of files as source? Is it loading performance? In case of multiple files and non-inline source-maps they could be lazy-generated as well but it's not necessary. |
You could theoretically bundle each file into their own file (like how dynamic imports code split), the code won't be the same though as in the editor (modules will be wrapped and other various compilation like JSX) so sourcemaps are still important, and also there will be a penalty performance because of the network bottleneck. I don't use WebStorm, but it seems strange that it doesn't support the same source maps as Chrome does. I assume Webpack/Parcel have the same problem? They use the same techniques. Personally I just recommend using the Chrome debugger, it's always going to be the debugger with the most capable and reliable features compared to third party tools. |
Thanks for the answer! Network might be a bottleneck indeed but not too much locally I think. |
I was actually investigating earlier how to go about file splitting while maintaining full Rollup API compatibility. Was originally looking at ESM import/exports like a bunch of new tools are doing, but it's not a great solution because it cripples the capability of HMR and results in memory leaks because of the cache busting technique. Using Nollup's existing chunking mechanism will work a lot better since it's just a matter of splitting every file into a chunk. Going to be doing some prototyping in the spare time, but don't expect anything soon! :) |
I did some research and it seems like Webpack also uses eval by default for development and lists it as the fastest tool: |
Also regarding the screenshot above: you can get better stack if you click on the error to expand it 😉 |
Some JavaScript engines (specifically Hermes and QuickJS) don't support accessing local variables from within an
eval
function call. For example:Throws an exception:
Property 'foo' doesn't exist
.This is problematic because nollup makes use of this feature here.
So my question is, why use
eval
here? I was able to change the code to write it inline without converting it into a string and using eval with minimal changes. But I had to exclude the source maps. It should be feasible to write a single source map file for the whole bundle like rollup does instead of a separate maps for each module. I'm sure there is a reason for this approach but I'd like to understand what it is. For HMR we clearly do need to useeval
but from my experiments it doesn't need access to any local variables.I think potentially using a single source map for the entire bundle could be more efficient, I've heard that for large projects Chrome Dev Tools can struggle with a large quantity of source maps and it makes the client unresponsive when first connecting. I also believe that using
eval
makes it slower to execute the bundle although I haven't yet gathered any data to back that up.The text was updated successfully, but these errors were encountered: