Don't use Babel transpilers when debugging an application

To clarify, I use many Babel plugins when developing an application (I have written a handful of Babel plugins to improve DX). Furthermore, I transpile my code using heavy presets such as es2015 and various other stage-X transpilations before deploying the application. Heck, I even use a Babel plugin to overload an existing syntax to enable function composition. However, I don't use any transpilations when debugging an issue.

I can afford not using Babel transpilers in my development environment because I know in advance about the features of the environment in which the code is going to run. Here is an example of the .babelrc configuration I am using in the current project:

{
  "env": {
    "test": {
      "plugins": [
        "istanbul",
        "transform-export-default-name",
        "transform-es2015-modules-commonjs",
        "transform-async-to-generator",
        "transform-flow-strip-types",
        "transform-es2015-destructuring",
        "transform-es2015-parameters",
        [
          "transform-object-rest-spread",
          {
            "useBuiltIns": true
          }
        ],
        "transform-class-properties"
      ],
      "sourceMaps": "inline"
    },
    "development": {
      "plugins": [
        "transform-export-default-name",
        "transform-flow-strip-types",
        [
          "transform-object-rest-spread",
          {
            "useBuiltIns": true
          }
        ]
      ]
    },
    "production-mainstream": {
      "plugins": [
        "closure-elimination",
        "transform-flow-strip-types",
        "transform-async-to-generator",
        "transform-es2015-destructuring",
        "transform-es2015-parameters",
        [
          "transform-object-rest-spread",
          {
            "useBuiltIns": true
          }
        ],
        "transform-class-properties",
        "transform-es2015-classes"
      ]
    },
    "production-legacy": {
      "plugins": [
        "closure-elimination",
        "transform-flow-strip-types"
      ],
      "presets": [
        "es2015",
        "stage-0"
      ]
    }
  }
}

In the above example, I am using NODE_ENV=development configuration to run Babel with the least possible transpilations required for the code to work in my browser (Google Chrome 57 has 97% ES6 support).

The main benefits of this approach are:

  • You don't rely on source maps. (There are issues related to using sourcemaps.)
  • You are able to set breakpoints and evaluate code at the breakpoints. (If you ever had to inspected a heavily transpiled code, chances are that you ran into issues of variable names changing or not being able to set a breakpoint at the script execution time.)
  • The overall code bundling and execution time is faster.

A simple tip that saves me pains when debugging a code base, yet I see few development setups that utilise it.

Ingvar Stepanyan reminded me about babel-preset-env. It is a Babel preset that automatically determines the required Babel plugins based on the provided environment criteria (e.g. Chrome 54, current node version, etc). It has reached v1.0.0. Think of it as a autoprefixer in your continuos-delivery setup.