Skip to content
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

Bug: Source maps don't work with hot reload #643

Closed
ozgrozer opened this issue Jan 24, 2018 · 10 comments · Fixed by #8034
Closed

Bug: Source maps don't work with hot reload #643

ozgrozer opened this issue Jan 24, 2018 · 10 comments · Fixed by #8034

Comments

@ozgrozer
Copy link

In the console I get an output like index.jsx:6 "test1" and that's okay.
But when I save the file, it turns like VM335:18 "test2".
I have to refresh the page to see this one index.jsx:6 "test2".

So source maps don't work unless I refresh the page.

Software Version(s)
Parcel 1.5.0
Node 9.2.0
npm/Yarn 5.6.0/1.3.2
Operating System MacOS 10.13.2
@DeMoorJasper
Copy link
Member

This is currently the expected behaviour, flagged as feature. This is quite hard with the current implementation of hot module reload

@devongovett
Copy link
Member

We evaluate the new code with new Function, so maybe we could generate an inline base64 source map for only the changed asset and put a source mapping URL comment in the code we eval?

@mischnic mischnic added the HMR Hot Module Reloading label Jan 13, 2019
@mischnic
Copy link
Member

mischnic commented Feb 24, 2019

so maybe we could generate an inline base64 source map for only the changed asset and put a source mapping URL comment in the code we eval?

I've got this nearly working, but there is one oddity:

eval(`console.log("test");
console.log("hello");
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNjcmlwdC5qcyJdLCJuYW1lcyI6WyJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiQUFFQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksTUFBWjtBQUlBRCxPQUFPLENBQUNDLEdBQVIsQ0FBWSxPQUFaIiwic291cmNlUm9vdCI6Ii4uIiwic291cmNlc0NvbnRlbnQiOlsiXG5cbmNvbnNvbGUubG9nKFwidGVzdFwiKTtcblxuXG5cbmNvbnNvbGUubG9nKFwiaGVsbG9cIik7Il19`);

correctly prints:

test       script.js:3
hello      script.js:7 

But hmr-runtime uses new Function and

new Function(`console.log("test");
console.log("hello");
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNjcmlwdC5qcyJdLCJuYW1lcyI6WyJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiQUFFQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksTUFBWjtBQUlBRCxPQUFPLENBQUNDLEdBQVIsQ0FBWSxPQUFaIiwic291cmNlUm9vdCI6Ii4uIiwic291cmNlc0NvbnRlbnQiOlsiXG5cbmNvbnNvbGUubG9nKFwidGVzdFwiKTtcblxuXG5cbmNvbnNvbGUubG9nKFwiaGVsbG9cIik7Il19`)();

prints:

test       script.js:7
hello      script.js:7 

https://stackoverflow.com/a/49464959/2352201:

My current attempts at getting this to work in Function constructors is failing, which is a shame- in this case, in both Edge and Chrome, the original source is correctly listed, but it appears that the line number information is broken (the instruction pointer always points to the last line). I am currently investigating this. However, the source map spec does allude to Function constructors containing sourcemaps:

So TLDR:

😞

Correct code, but nowhere supported: https://github.com/parcel-bundler/parcel/tree/hmr-sourcemaps-v2

@connorjclark
Copy link

@mischnic do you think hmr-runtime could use eval in the meantime?

@connor4312
Copy link

Continuing #5313 (comment)

As far as I can tell, neither Firefox nor Chrome support sourcemap comments in new Function() at this point

Chrome supports this on a protocol level.

Because it's supported there, we have already been able to use function sourcemaps in widely scenarios in VS Code and its JS debugger (for example, vscode has web worker extensions which are all invoked with new Function()).

So if Parcel emitted sourcemaps in this scenario, Parcel users would be able to successfully debug using HMR in VS Code. And it puts a little pressure on the chrome devtools team to implement support for it within their UI 🙂

@mischnic
Copy link
Member

mischnic commented Nov 4, 2020

Firefox nor Chrome support sourcemap

Neither of them actually show the correct line, but they do try to map something.

WIP PR: #5316

@connor4312
Copy link

Thanks for looking at this, let me know if you'd like me to lend a hand with anything 🙂

@mischnic
Copy link
Member

A workaround for the browser bugs would be somehow evaluating the new code via a <script> tag.

@webcodion
Copy link

webcodion commented Jan 7, 2022

Hi!

This is still an issue for me. Page reload prints:
image

HMR prints:
image

Any workaround for this?

Webpack HMR works correctly.

Thank you!

@devongovett
Copy link
Member

Investigated this a bit. There are some challenges here. The situation hasn't changed much since @mischnic commented in 2019. Chrome and Firefox support sourceMappingURL and sourceURL in eval, but not in new Function. So we can do something like this to work around that:

let id = '_' + Math.random().toString(36).slice(4);
(0, eval)(`function ${id}(require, module, exports) {${asset.output}}`);
let fn = window[id];
delete window[id];

Unfortunately, while Safari seems to support this as well for console calls, it does not set stack traces to use the right source URLs. https://bugs.webkit.org/show_bug.cgi?id=137297

I think the only option then would be to load a <script> element over HTTP (inline scripts also have the same problem in Safari). But that means the HMR runtime would need to become async, which would be a big change. Rather than sending the content of the updated modules over the web socket and evaluating, we'd need to send an update via web socket, and then download a script before applying the updates. Not sure how much that would affect performance as well...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants