GAZAR

Principal Engineer | Mentor

Source maps and how it works

Source maps are awesome. Why? Because they are used to display your original JavaScript while debugging, which is a lot easier to look at than minified production code. In a sense, source maps are the decoder ring to your secret (minified) code.

Using Webpack, specifying devtool: "source-map" in your Webpack config will enable source maps, and Webpack will output a sourceMappingURL directive in your final, minified file. You can customize the source map filename itself by specifying sourceMapFilename.

// webpack.config.js
module.exports = {
    // ...
    entry: {
      "app": "src/app.js"
    },
    output: {
      path: path.join(__dirname, 'dist'),
      filename: "[name].js",
      sourceMapFilename: "[name].js.map"
    },
    devtool: "source-map"
    // ...
};

And after running you would get something like

Hash: b59445cb2b9ae4cea11b
Version: webpack 4.1.1
Time: 1347ms
Built at: 3/16/2018 4:58:14 PM
       Asset       Size  Chunks             Chunk Names
     main.js  838 bytes       0  [emitted]  main
    main.css   3.49 KiB       0  [emitted]  main
 main.js.map   3.75 KiB       0  [emitted]  main
main.css.map   85 bytes       0  [emitted]  main
  index.html  220 bytes          [emitted]
Entrypoint main = main.js main.css main.js.map main.css.map
...

Maybe someone else has this problem at one point. If you use the UglifyJsPlugin in webpack you need to explicitly specify the sourceMap flag. For example:

new webpack.optimize.UglifyJsPlugin({ sourceMap: true })

Devtool has different options

__eval

eval generates code in which each module is wrapped within an eval function:

__cheap-eval-source-map

cheap-eval-source-map goes a step further and it includes base64 encoded version of the code as a data URL. The result contains only line data while losing column mappings.

__cheap-module-eval-source-map

cheap-module-eval-source-map is the same idea, except with higher quality and lower performance:

__eval-source-map

eval-source-map is the highest quality option of the inline options. It's also the slowest one as it emits the most data

__cheap-source-map

cheap-source-map is similar to the cheap options above. The result is going to miss column mappings. Also, source maps from loaders, such as css-loader, are not going to be used.

__cheap-module-source-map

cheap-module-source-map is the same as previous except source maps from loaders are simplified to a single mapping per line. It yields the following output in this case:

__hidden-source-map

hidden-source-map is the same as source-map except it doesn't write references to the source maps to the source files. If you don't want to expose source maps to development tools directly while you wish proper stack traces, this is handy.

__nosources-source-map

nosources-source-map creates a source map without sourcesContent in it. You still get stack traces, though. The option is useful if you don't want to expose your source code to the client.

__source-map

source-map provides the best quality with the complete result, but it's also the slowest option.

If you use it correctly you can see something like this in inspect tool

Which you can use it for debugging or if you want connect it to your workplace.

Conclusion

Source maps can be convenient during development. They provide better means to debug applications as you can still examine the original code over a generated one. They can be valuable even for production usage and allow you to debug issues while serving a client-friendly version of your application.

As you see in the chart above published in webpack documentation page, I usually use eval for production environment and source-map for development environment.

Sources:

  • https://webpack.js.org/configuration/devtool/
JavaScriptProgrammingSourcemapsWebpackDebugging

Comments