Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure .babelrc to support ES6 module imports and async/await?

Desired Behaviour

I am trying to import code from one file into another with:

lib.js

// generate unique id
export const guid = () => {
    const s4 = () => {
        return Math.floor((1 + Math.random()) * 0x10000)
            .toString(16)
            .substring(1);
    }
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
        s4() + '-' + s4() + s4() + s4();
}

// get current date as ISO string  
export const currentDateTimeISOString = () => {
    var iso_string = new Date().toISOString();
    return iso_string;
}

// convert boolean string to boolean
export const stringToBoolean = (val) => {
    var a = {
        'true': true,
        'false': false
    };
    return a[val];
}

app_es6.js

import { guid, currentDateTimeISOString, stringToBoolean } from './src/js/lib';  

Actual Behaviour

After build I get the error:

export const guid = () => {
^^^^^^

SyntaxError: Unexpected token export

What I've Tried

I've googled this error and come across various solutions.

The most up to date approach seems to be:

npm install babel-register babel-preset-env --save-dev  

source

I currently have the following babel related dev dependencies in package.json:

"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-0": "^6.24.1",

And .babelrc is:

{
    "presets": [
        [
            "env",
            {
                "targets":
                {
                    "node": "current"
                }
            }
        ]
    ]
}

I recently changed .babelrc to the above in order to handle async/await usage, it used to be:

{
    "presets": [
        "env",
        "stage-0"
    ]
}

My build script in package.json is:

"build-server-file": "babel app_es6.js --out-file app.js",

I'm concerned about implementing a solution that is outdated or breaks functionality with another part of the codebase (ie, if i revert to my previous version of .babelrc then async/await will throw errors). I've also read that stage-x is depreciated.

Question

What is the most up to date way to import/export modules in ES6 in a Node.js environment whilst still supporting the .babelrc requirements for async/await?

like image 840
user1063287 Avatar asked Nov 07 '22 23:11

user1063287


1 Answers

Notice that the SyntaxError is being thrown from within lib.js and not app.js --this is almost certainly the result of that file not being transformed.

The babel command you're using, babel app_es6.js --out-file app.js is processing app_es6.js; however, lib.js is untouched and that's likely why you still see ESM export syntax when require()ing the file.

I set up a minimal gist with updates to what I know about your current setup to make this work the way (I think) you intended: https://gist.github.com/knksmith57/a554defde2d3d7cf64c4f453565352a0

The trick is to process the entire source directory and not just your entrypoint file.

tl;dr:

  1. process the entire source directory, not just the entrypoint
  2. tell preset-env to use cjs (alias for commonjs) as the target module type
  3. enable a plugin to transform async functions to generator functions (in babel 7.x, that's @babel/plugin-transform-async-to-generator)
  4. look at that gist for a complete working example

If you run into trouble backporting my example to babel 6.x, let me know and I can make some time to follow up.

Hope this helps!

like image 158
knksmith57 Avatar answered Nov 14 '22 23:11

knksmith57