<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: themlsmith</title>
    <description>The latest articles on DEV Community by themlsmith (@themlsmith).</description>
    <link>https://dev.to/themlsmith</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F55650%2Fb599a83f-d4e4-48ed-ae67-8aab515970e1.jpeg</url>
      <title>DEV Community: themlsmith</title>
      <link>https://dev.to/themlsmith</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/themlsmith"/>
    <language>en</language>
    <item>
      <title>Debugging JavaScript with Source Maps</title>
      <dc:creator>themlsmith</dc:creator>
      <pubDate>Fri, 02 Mar 2018 22:55:25 +0000</pubDate>
      <link>https://dev.to/themlsmith/debugging-javascript-with-source-maps--5bie</link>
      <guid>https://dev.to/themlsmith/debugging-javascript-with-source-maps--5bie</guid>
      <description>&lt;p&gt;One of the frustrating situations I often encounter when debugging JavaScript, is tracking down &lt;strong&gt;&lt;a href="https://dev.to/error-tracking/javascript/"&gt;JavaScript errors&lt;/a&gt;&lt;/strong&gt; to &lt;strong&gt;&lt;em&gt;line 23 col 63475&lt;/em&gt;&lt;/strong&gt;. I felt as though I was right on the edge of seeing the offending code and being able to fix it. And then, reality came crashing down. I realized that I’ve managed to debug myself right into the middle of a minified JavaScript file 😞.&lt;/p&gt;

&lt;p&gt;There is a better way - Source Maps. JavaScript source maps are the key to taking what you’ve narrowed down in the minified code, and then being able to map them back to the source code so that you can view and resolve the problem without having to figure it out in the minified code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/" rel="noopener noreferrer"&gt;Source maps&lt;/a&gt;&lt;/strong&gt; are generated when JavaScript code is minified. By using the source map in production, you can trace your problems back to the exact line of source code. It also allows you to use your browser's developer console to step through the source code when debugging problems. We’ll look at how to generate a source map, and then we’ll look at how they work, and how we can use them to make our lives easier.&lt;/p&gt;

&lt;p&gt;You can download or clone the source for the following demo from &lt;strong&gt;&lt;a href="https://github.com/echovue/javascript-calculator" rel="noopener noreferrer"&gt;https://github.com/echovue/javascript-calculator&lt;/a&gt;&lt;/strong&gt;. The source includes the original JavaScript file, the minified JavaScript file, and the source map. If you already know how to generate a source map or just want to use the generated file, you can skip down to &lt;strong&gt;How Do Source Maps Work?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating a Source Map
&lt;/h2&gt;

&lt;p&gt;For this example, I’m going to be using a simple JavaScript application. Keeping it simple will help keep the demo manageable, and the concepts apply to any application, no matter the size.&lt;/p&gt;

&lt;p&gt;The first thing that we’ll need is a tool to minify the code. I’m going to use &lt;code&gt;UglifyJS&lt;/code&gt;, but most tools should support the ability to generate a production source map as part of the minification process. You can install &lt;code&gt;UglifyJS&lt;/code&gt; with npm if you have that installed on your workstation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;uglify-js &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then validate installation by executing the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;uglifyjs &lt;span class="nt"&gt;--version&lt;/span&gt;
uglify-js 3.2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In some cases, you may have to add the installation folder to your path.&lt;/p&gt;

&lt;p&gt;Now that we have &lt;code&gt;uglifyjs&lt;/code&gt; installed and we’ve verified that it works, let’s minify our code. If you’re using the example project, this command will overwrite the existing minified file and source map.&lt;/p&gt;

&lt;p&gt;From the JS folder of the demo project, enter the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;uglifyjs calculator.js &lt;span class="nt"&gt;--compress&lt;/span&gt; &lt;span class="nt"&gt;--mangle&lt;/span&gt; &lt;span class="nt"&gt;--source-map&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; calculator.min.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command takes our JavaScript file &lt;code&gt;calculator.js&lt;/code&gt; and converts it to a minified version &lt;code&gt;calculator.min.js&lt;/code&gt;, along with a source map &lt;code&gt;calculator.min.js.map&lt;/code&gt;. Even with this small file, the minification process reduces the size of the file from 4KB to 1KB.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do Source Maps Work?
&lt;/h2&gt;

&lt;p&gt;Let’s open up the source map file to see what it has in it. I used a JSON parser to format it for easy reading, and shortened some of the lines with ellipses as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sources"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;calculator.js&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"names"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;resultNum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;document&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mappings"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CAAC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;WACC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;aAyGA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;IAAK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;IAvFHA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;EACAC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;EAhBEC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;EAAK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;SAASC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;GAChB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;MAA&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;MAAtBA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file specifies the mapping version used and identifies the source files and names of parameters. The useful part is the mappings, although unfortunately since they are in Base 64 VLQ, they’re not very useful for the human brain.&lt;/p&gt;

&lt;p&gt;If you’d like to understand more about how the mappings work, and how they translate the minified code back to the source, I’d recommend reading &lt;strong&gt;&lt;a href="http://www.mattzeunert.com/2016/02/14/how-do-source-maps-work.html" rel="noopener noreferrer"&gt;How do source maps work&lt;/a&gt;&lt;/strong&gt;. For now, let’s look at how to leverage the source map in production to make debugging easier.&lt;/p&gt;

&lt;p&gt;If you open the &lt;code&gt;index.html&lt;/code&gt; in Chrome or your browser of choice, you’ll notice that there is a JavaScript error which is thrown on the first line of our minified file. Let’s make it easier to identify and resolve this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frollbar.com%2Fassets%2Fblog%2Fimages%2Fsource-maps%2Fcan-not-set-property.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frollbar.com%2Fassets%2Fblog%2Fimages%2Fsource-maps%2Fcan-not-set-property.png" alt="Screenshot of Uncought TypeError: can not set property"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Error within the minified JavaScript file&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To complete the next set of steps, you will need to have the JavaScript-calculator web application running on a publicly accessible web server. For this demo, I created an AWS instance, installed an Apache Web Server, and served the web application from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with Source Maps in Production
&lt;/h2&gt;

&lt;p&gt;When you’re debugging a production application, it gets trickier since production servers often don’t serve source maps. Do you want to make it easier for people you don’t know to see your raw source code? Fortunately, Rollbar supports using source maps to get meaningful stack traces while still using minified JavaScript in production.&lt;/p&gt;

&lt;p&gt;Rollbar provides real-time &lt;strong&gt;&lt;a href="https://dev.to/features/"&gt;production error monitoring&lt;/a&gt;&lt;/strong&gt; with support for most programming languages and frameworks, including &lt;strong&gt;&lt;a href="https://dev.to/error-tracking/javascript"&gt;JavaScript&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://dev.to/error-tracking/angular"&gt;Angular&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="///error-tracking/node.js"&gt;Node&lt;/a&gt;&lt;/strong&gt;, React, etc. Because &lt;strong&gt;&lt;a href="https://github.com/rollbar/rollbar.js/" rel="noopener noreferrer"&gt;&lt;code&gt;rollbar,js&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; supports source maps, you can see the line of exact code where each error originated along with the stack trace. Let’s dive into an example of how it works.&lt;/p&gt;

&lt;p&gt;Once you have &lt;strong&gt;&lt;a href="https://dev.to/signup/"&gt;created an account&lt;/a&gt;&lt;/strong&gt; and your first project, you’ll be given a client-side access token. Add the script included in the &lt;strong&gt;Quick start browser&lt;/strong&gt; section inside the &lt;code&gt;&amp;lt;HEAD&amp;gt;&lt;/code&gt; tag in &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can upload your source maps via the &lt;strong&gt;&lt;a href="https://dev.to/docs/"&gt;API&lt;/a&gt;&lt;/strong&gt;. Usually, we would use a script do this automatically at deployment time, but we will do it manually for this tutorial. From the root folder of the web application project, execute the following curl command after updating the access token and the minified_url to your token and URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl https://api.rollbar.com/api/1/sourcemap &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="nv"&gt;access_token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8888888888888888888888888 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.0.1 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="nv"&gt;minified_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://ec2-52-43-138-168.us-west-2.compute.amazonaws.com/javascript-calculator/js/calculator.min.js &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="nv"&gt;source_map&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;@js/calculator.min.js.map &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-F&lt;/span&gt; calculator.js&lt;span class="o"&gt;=&lt;/span&gt;@js/calculator.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is done, clicking on an error should take you to a page with the stack trace. Here we can see the proper source code with files and line numbers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frollbar.com%2Fassets%2Fblog%2Fimages%2Fsource-maps%2FCan-not-set-property-onClick-null.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frollbar.com%2Fassets%2Fblog%2Fimages%2Fsource-maps%2FCan-not-set-property-onClick-null.png" alt="Screenshot of Uncaught TypeError : Can not set property onClick null"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Stack trace showing the original source code&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you click the source file link, it will open to the file and line number in &lt;strong&gt;&lt;a href="https://dev.to/docs/source-control"&gt;GitHub, BitBucket, or Gitlab&lt;/a&gt;&lt;/strong&gt;. There, you can use the tools to see what changes were made and when. To learn more, check out the &lt;strong&gt;&lt;a href="https://dev.to/docs/source-maps/"&gt;source maps documentation&lt;/a&gt;&lt;/strong&gt; for additional details and config options.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tips for using source maps in production and debugging with Rollbar
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Don't forget to update the version number when you update your JavaScript. If you don't, the filename, line and column numbers will be incorrect. &lt;/li&gt;
&lt;li&gt;The value of &lt;code&gt;minified_url&lt;/code&gt; must be the full URL of the minified file. This should start with &lt;code&gt;http:&lt;/code&gt; or &lt;code&gt;https:&lt;/code&gt;, which we'll strip off.&lt;/li&gt;
&lt;li&gt;Make sure you're not missing one or both of the config params in the on-page JavaScript snippet. Set both &lt;code&gt;payload.client.javascript.source_map_enabled&lt;/code&gt; and &lt;code&gt;payload.client.javascript.code_version&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you're using the upload method, check to be sure that the &lt;code&gt;code_version&lt;/code&gt; used in the on-page snippet matches the version provided in the upload call.&lt;/li&gt;
&lt;li&gt;If you're using the download method, make sure your source map file or minified JavaScript source files are on a host that's reachable from the public internet and are not gated behind an authorization wall.&lt;/li&gt;
&lt;li&gt;If the JavaScript error that you are expecting to be un-minified does not have column numbers, and you haven't enabled &lt;code&gt;guess_uncaught_frames&lt;/code&gt;, we won't be able to apply the source map. We need column numbers to be able to apply the source map without guessing.&lt;/li&gt;
&lt;li&gt;If your source map file combines multiple sub-maps into "sections" within the top level map, we, unfortunately, don't yet support this source map format (but we are planning to soon).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;In conclusion, source maps help you debug production code right in your browser's developer console. They tell you the exact file and line number when there is an error, and make it natural to use the debugging feature within your browser to step through the code. This makes it much easier to find the root cause of problems and fix them quickly. When monitoring production systems, make sure to choose solutions like Rollbar that support source maps and make debugging production super easy.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note: This was originally published on &lt;a href="https://rollbar.com/blog/top-10-javascript-errors/" rel="noopener noreferrer"&gt;Rollbar's blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>sourcemaps</category>
    </item>
  </channel>
</rss>
