Create-react-app: Hot reloading doesn't update Chrome sourcemaps

Created on 29 May 2017  路  27Comments  路  Source: facebook/create-react-app

We have not merged hot reloading support yet but I noticed a very unfortunate issue: Chrome doesn't update sourcemaps.

See how the Hello in browser Sources pane doesn't change.

Note that if we change Webpack devtool setting from cheap-module-source-map to eval it will update on hot reloads:

It used to be broken too but at some point Chrome fixed it. I remember chatting with @paulirish about it in the past.

However we can't switch to eval mode because we need the source mapping.

We should reach out to somebody at Chrome and figure out if this is fixable. We can live with the broken behavior for a while but if it鈥檚 not possible to fix later, then hot reloading experience would be confusing.

underlying tools

Most helpful comment

The fix for crbug.com/438251 has landed and will be available on tomorrow's Canary.

All 27 comments

And this is a similar bug that was fixed for eval case by @pavelfeldman and (if I鈥檓 not mistaken) @ak239:

https://bugs.chromium.org/p/chromium/issues/detail?id=492902

Related webpack discussion (closed in favor of Chromium bugs): https://github.com/webpack/webpack/issues/2478

I provided a detailed standalone repro case here: https://bugs.chromium.org/p/chromium/issues/detail?id=438251#c28

For the record, I'm suffering from the same issue in a completely different environment too for 2 years by now:

  • [org.clojure/clojurescript "1.9.562"]
  • [tailrecursion/boot-static "0.0.1-SNAPSHOT"]
  • [hoplon/ui "0.2.1-SNAPSHOT"]

The phenomena is present in both Chrome 61, Firefox 53, Safari 10 and Opera 45.

The alt-r workaround recommended in the Chromium discussion doesn't work (again?) in Chrome Canary 61.0.3124.0 either.

Maybe worth mentioning the related issue here too:
https://github.com/gaearon/react-hot-loader/issues/180

Closing and re-opening the dev tools in Firefox will load the latest source code, but since it doesn't preserve the state of its windows, we have to re-open the desired source files again.

Using the :source-map-timestamp option mitigates the problem slightly by making the latest original source code available in the browser under a timestamped name (eg. application.cljs?rel=1496943424545), but it doesn't remove earlier versions, so it's still a bit confusing...

At least clicking on error references in the console brings us to the correct version of the original source code.

This commit https://github.com/webpack/webpack/commit/84b6554f982fd9bc130262cfe0a8003531d4bcb9 has now landed in Webpack, which enables setting a contentHash as a query-string suffix. This workaround should be sufficient to solve this problem.

Could you help me understand how it solves the problem? What's the developer experience like? Do we need to update our config?

@gaearon yeah, just change the Webpack config to include:

{
  // ...
  output: {
    // ...
    sourceMapFilename: "[file].map?[contenthash]"
  }
}

This will use the workaround which makes the sourcemaps work in Chrome together with cheap-module-source-map.

It still won't replace sourcemaps on edit, right? Will just add new copies of the file.

I believe the mapping should update too, since the code-paths will be different.

@niieani I can't reproduce that it fixes the issue. If I use module.hot.accept calls, I still see old code on hot reload. Can you provide full instructions for me to see how this fixes it?

Hmm, the old code will still be visible (since we cannot unload sourcemaps), however new code should appear and be mappable, correctly.

What works for me is adding timestamps:

const now = Date.now()
map.sources = map.sources.map(source => source + (source.includes('?') ? '&' : '?') + now)

The full source map plugin we use:

const { RawSource, ConcatSource } = require('webpack-sources')
const path = require('path')

module.exports = function sourceMapPlugin() {
  return {
    apply: compiler => {
      compiler.plugin("compilation", compilation => {

        // make sure webpack stuff keeps their source maps
        compilation.plugin("build-module", module => {
          module.useSourceMap = true
        })

        // add source map assets for anything that still has one
        compilation.plugin('after-optimize-assets', assets => {
          Object.keys(assets).forEach(name => {
            const asset = assets[name]
            const map = asset.map()
            if (map) {

              // make sure sources in the source map are timestamped, this helps with hot reloading
              const now = Date.now()
              map.sources = map.sources.map(source => source + (source.includes('?') ? '&' : '?') + now)

              const [startComment, endComment] = name.endsWith('.css') ? ['/*', ' */'] : ['//', '']
              assets[name] = new ConcatSource(asset, `\n${startComment}# sourceMappingURL=${path.basename(name)}.map${endComment}\n`)
              assets[name + '.map'] = new RawSource(JSON.stringify(map))
            }
          })
        })
      })
    }
  }
}

Excuse rant.
Could we potentially, in dev, not bundle everything? Maybe just bundling the deps, and providing a source map for them, then generate a slow source map for individual JavaScript that could then be cached (since most files don't change) then bundle them together at the end or just push heaps of small files.. How much slower would it be? Could a service worker help? Would not merging the files make hot loading certain libs that rely on symbols or object identity more reliable?

@gaearon : I know it's not a _build_ tool thing or even CRA specific, but if we could poke the browser devtools developers to finally implement this, it would be a huge win for the JS ecosystem...

We did poke them a few times. I think the issue even got a patch and it has a milestone. So I鈥檓 hopeful 馃檪

Is there a corresponding Firefox DevTools issue?

I think so, mabye.

The fix for crbug.com/438251 has landed and will be available on tomorrow's Canary.

馃槏 馃槏

I'm a big fan of HMR and I see it's been several weeks since the Canary fix landed.
Apologies if I'm missing something but it seems like this still needs to be verified, right?

Is there a recommended way to do so? I use Canary and would be happy to take the necessary steps.

@onpaws : fwiw, I can verify that a copy of Chrome 66 correctly updates sourcemaps on hot reloading in my own non-CRA app.

Hello, is there any progress?
Latest chrome 65, no source map reload.
Doing Alt+R manually to reload devtools is too slow.

Is there a solution?

update chrome Version 67.0.3370.0 (Official Build) canary (64-bit)) , the bug has fixed ,according the bug issues: https://bugs.chromium.org/p/chromium/issues/detail?id=438251

update chrome Version 66.0.3359.117(64-bit) , the bug has fixed. 馃檪

Was this page helpful?
0 / 5 - 0 ratings

Related issues

barcher picture barcher  路  3Comments

wereHamster picture wereHamster  路  3Comments

rdamian3 picture rdamian3  路  3Comments

Evan-GK picture Evan-GK  路  3Comments

alleroux picture alleroux  路  3Comments