Jake Frederick
Jake Frederick

Reputation: 47

Inheritance in Babel transpiled ES2015 not working due to no class hoisting

I am developing a web app and have my Javascript broken into multiple files. I am using Babel to transpile the directory of ES2015 source files to a single ES5 file. Coming from an objected oriented background I love having "classes" whether they are just syntactic sugar or not.

I recently created a base class in a file and then tried extending it in a different class in a different file. What I quickly realized is that class definitions are not hoisted and when Babel combined the multiple files the order is such that the base class in not defined yet when I instantiate the inherited class (so it throws a runtime error).

Here is a general example that illustrates what I am talking about:

base.js:

class Base {
    constructor() {
        console.log("BASE");
    }
}

derived.js:

class Derived extends Base {
    constructor() {
        super();
        console.log("DERIVED");
    }
}

main.js:

var instance = new Derived();

Babel-CLI:

babel src --out-file index.js

results in index.js looking like:

class Base {
    constructor() {
        console.log("BASE");
    }
}
class Derived extends Base {
    constructor() {
        super();
        console.log("DERIVED");
    }
}
var instance = new Derived();

This works fine. However, if I were to change the filename of base.js to xbase.js then index.js ends up looking like this:

class Derived extends Base {
    constructor() {
        super();
        console.log("DERIVED");
    }
}
var instance = new Derived();
class Base {
    constructor() {
        console.log("BASE");
    }
}

this fails because the Base class is not defined before it is used:

index.js:1 Uncaught ReferenceError: Base is not defined

So clearly when Babel concatenates the files it grabs the file names alphabetically and sticks them together that way. How do I make this work without making sure my file names are named according to the order I want them to appear in the final file? Does using modules solve this problem? Is it the ONLY way to solve this problem?

Upvotes: 0

Views: 480

Answers (1)

Mario Tacke
Mario Tacke

Reputation: 5488

Make sure to import and export your files. That way, babel won't have to rely on file load order during concat of the files.

Example:

base.js

class Base {
    constructor() {
        console.log("BASE");
    }
}

export default Base;

derived.js

import Base from './base.js';

class Derived extends Base {
    constructor() {
        super();
        console.log("DERIVED");
    }
}

export default Derived;

main.js

import Derived from './derived.js'

var instance = new Derived();

Upvotes: 1

Related Questions