Israel Cruz

A developer's blog

Babel Source Maps in NodeJS


Let's say you start your NodeJS project and want the latest ECMA despite your server (or local env) having an outdated node version, so you:

Install Babel:

  $ npm install --save @babel/core @babel/cli @babel/preset-env

Write your awesome complex app:

import messages from './messages';
(() => console.log(messages.hello))();

Configure your .babelrc:

  {
    "presets": [
      "@babel/preset-env"
    ]
  }

Transpile your code (assuming your source code is in src and your distribution folder is dist):

  $ babel ./src --out-dir dist

Et voilá, you have an awesome ECMAscript app that runs in older node versions, but then when some exception ocurrs:

import messages from './messages';
throw new Error('An error');

The stack trace looks bad:

  /awesome-app/dist/app.js:7
  throw new Error('An error');
  ^
  Error: An error
     at Object. anonymous (/awesome-app/dist/app.js:7:7)
     at Module._compile (node:internal/modules/cjs/loader:1101:14)
     at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
     at Module.load (node:internal/modules/cjs/loader:981:32)
     at Function.Module._load (node:internal/modules/cjs/loader:822:12)
     at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
     at node:internal/main/run_main_module:17:47

Everything is pointing towards the transpiled files. This is the reason why source maps exist, and babel is already capable to generate them; and all you need to do is...

TLDR:

Enable source maps in babel's configuration (.babelrc):

  {
    "presets": [
      "@babel/preset-env"
    ],
    "sourceMaps" : "inline"
  }

Now when transpiling (babel ./src --out-dir dist) you'll notice a line like this at the bottom of each transpiled file:

Inline source map

Install source-map-support and babel-plugin-source-map-support

the first one will override the stack trace when you add a line on top of a compiled file, and the second one will ad this line for you.

  $ npm install source-map-support babel-plugin-source-map-support --save

Configure your .babelrc for this plugin:

  {
    "presets": [
      "@babel/preset-env"
    ],
    "plugins": [
      "source-map-support"
    ],
    "sourceMaps" : "inline"
  }

And that is it! Now whenever you transpile and run you'll see a better stacj trace:

   /awesome-app/src/app.js:2
   throw new Error('An error');
         ^
   Error: An error
       at Object.(anonymous) (/awesome-app/src/app.js:2:7)
       at Module._compile (node:internal/modules/cjs/loader:1101:14)
       at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
       at Module.load (node:internal/modules/cjs/loader:981:32)
       at Function.Module._load (node:internal/modules/cjs/loader:822:12)
       at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
       at node:internal/main/run_main_module:17:47