DeepCode and Snyk joined forces. Find out more in our blog.

SummerAcademy on Debugging - 2.1.6 Compilers

Tuesday, August 25th, 2020

#

See the companion video here https://youtu.be/OwCSWVxDZGI

Compilers are programs that take source code in and generates lower level code down to binary code. But JavaScript is designed as an interpreted language (aka ‘script’). Modern JavaScript implementations use a technique called Just In Time compilation. In the companion video, we will look deeper on the way one of the most important JavaScript engine - V8 - is build. V8 is used broadly in for example NodeJS, Electron, and Chrome. Being aware of the underlying mechanism is important when debugging possible performance issues. But JavaScript is evolving very fast. Since JavaScript compilers or interpreters are not as fast in adopting new language features as the standard evolves, we see a transpilers like Babel being used which translates from more modern JavaScript (mainly ECMAscript 2015 and beyond) or including extensions towards the version of JavaScript spoken by the browser. Therefor Babel calls itself a transcompiler (see here). Simply said, the better you express your intent in your code, the easier it is for the compiler to optimize it. A simple example is using const instead of var, not chaining types of variables, or keeping complex structures relatively stable.

Note: Using Babel means that you might not see your original code in the browser debugger. Make sure to use SourceMaps and extensions

cpp
const city = address?.city;

becomes

csharp
var _address; const city = (_address = address) == null ? void 0 : _address.city;

Obviously, for any debugger it would be impossible to translate back to the original code without a table that translates between the output code of the compiler and the original code. So, you can ask the debugger to produce debug information and make it available.

2.1.6.1 Babel to JavaScript

Babel is widely used for Vue or React and lots of other occasions - so it is pretty likely you will find Babel in your tool stack. You can ask Babel to generate SourceMaps. Using SourceMaps you can ‘translate’ errors into your original source code

Note: Make sure you do not leak SourceMaps into production! Too much information for any attacker.

  1. When you are building different targets (npm run build vs npm run deploy), you might end up generating SourceMaps or not. If you cannot find a SourceMap, check that you do the right target.
  2. Babel does not do type checking as you would classically expect from a compiler. You need other tools for this (aka DeepCode and TypeScript)
  3. Make sure to keep Babel up to date to prevent your bug actually being a Babel bug

Key Take-Aways

In JavaScript, when using compilers, the code executed in the runtime will differ from your source code. Use extensions to enable an easy debugging experience.

Resources

awesome babel SourceMaps internals Debugging TypeScript in VSC Debugging TypeScript in WebStorm