Max
Max

Reputation: 15965

Why is the execution order of my modules different than expected?

I am using Babel to compile some ES6 JavaScript down to ES5. I am having some trouble with my code because my modules are being evaluated in an undefined order.

Let's say I have a modules:

// a.js
class A {
  constructor() {
    this.prop = window.randomProperty;
    console.log("Prop " + this.prop);
  }
}

const a = new A();
export default a;

This module relies on window.randomProperty to be set before it can instantiate itself.

Now I have a main file:

// main.js
import "babel-polyfill"; // Not sure if this is relevant

window.randomProperty = function() { return "hi"; };
console.log("randomProperty set");   

import A from "a";

The console output of this is:

Prop undefined
randomProperty set

How can I have the code execute in the correct order?

Upvotes: 1

Views: 760

Answers (3)

Bergi
Bergi

Reputation: 664548

Imports are loaded (and executed, unless cyclic) before the module is executed statically. In your case, a.js will be loaded before main.js is executed.

If you have dependencies, you should declare them explicitly:

// random_prop.js
window.randomProperty = function() { return "hi"; };
console.log("randomProperty set");

// a.js
import "random_prop";
const a = {
    prop: window.randomProperty;
}
console.log("Prop " + a.prop);
export {a as default}

// main.js
import "babel-polyfill"; // Not sure if this is relevant
import a from "a";
console.log(a.prop);

Of course, you could also import the random_prop.js in main.js before a.js, and it would work in this simple setting, but I would not recommend relying on side effects like that.

Upvotes: 1

Bobby Matson
Bobby Matson

Reputation: 1488

Your problem lies in where you instantiate A, try doing it in main.js. Check this out:

// a.js
class A {
  constructor() {
    this.prop = window.randomProperty;
    console.log("Prop " + this.prop);
  }
}

// do not instantiate here
// const a = new A();
export default a;

Just make sure you create the object here:

// main.js
import A from "a";

window.randomProperty = function() { return "hi"; };
console.log("randomProperty set");

const a = new A();

The reason is, when you import a module, it will invoke any methods that are not tied to a function or class definition.

Hope this helps!

Upvotes: 0

madox2
madox2

Reputation: 51851

import statements are hoisted, so imports are loaded before your code is executed. To execute it in order you want, you should use other module loader such as using require.

const A = require("a");

Upvotes: 1

Related Questions