I had a logging tool I built for us to start measuring metrics with logs. One of the things that I needed to do was support down to Node 4. Sadly that means most of the great features of Node 8 like async/await string.includes and Object.entries are all missing.

Originally I required the @babel/polyfill to be used to try to compensate for the missing feature sets. There were quite a few people who were upset with the regeneratorRuntime error that would be produced if they forgot to include it. (My bad on not making it a peer dependency)

If you aren't familiar with the regeneratorRuntime error here is a brief reason why it will appear on any node version. regeneratorRuntime error will appear if you try to use something that could compile down to a generator. Generators also don't exist on Node 4 but you can pseudo make them work by using the @babel/polyfill. So without it, you get the `regeneratorRuntime is not defined` error.

Now I am writing this tutorial because with babel you can quickly find articles that are no longer relevant on how to fix the issue with previous versions of babel. For this I am specifically targeting version 7.

The Fix

Here is my .babelrc file:

{
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "node": 4
        },
        "exclude": ["transform-regenerator"]
      }
    ]
  ],
  "plugins": [
    [
      "module:fast-async", {
        "spec": true
      }
    ]
  ],
}

Basically, I took the approach of removing the usage of string.includes or Object.entries. I replaced string.includes with lodash.includes and replaced Object.entries with lodash.topairs. Once that was done I could still use async/await but used instead fast-async instead of relying on the transform-regenerator. Essentially avoiding needing to use generators or the runtime at all.

Dependency versions

These are the versions that currently work for me.

"devDependencies": {
  "@babel/cli": "^7.2.0",
  "@babel/core": "^7.2.0",
  "@babel/preset-env": "^7.2.0",
  "@babel/register": "^7.0.0",
  "fast-async": "^6.3.8",
}

Test Support

For mocha you will still want to require the core and register so that way they can be interpreted correctly.

"test": "mocha -r @babel/core -r @babel/register"

Application Start

I will also usually include source-map-support at the beginning of any lib or app so that way I can see where in source the error occurred rather than somewhere in the compiled assets.

"dependencies": {
  "source-map-support": "^0.5.9"
}

Start of application or lib:

require('source-map-support/register');

Conclusion

Anyway, that should give you everything you need. Just be mindful of using functions that don't quite work yet in Node 4. With the use of lodash, it is easy enough to still get all the same functionality with minimal changes for the future.