Taktech
Taktech

Reputation: 485

Javascript classes in ES6, how to import them within other js-files and in html files?

Obviously, I am a beginner and trying to figure out basic staff, so please bear with me!

I have all these files (index.html, app.js and calc.js) in the same folder and their content is shown below.

I have 2 issues:

1: why in file (app.js), importing class Calc and creating a new instance of it works, whereas in file (calc.js) similar process doesn't work with class Test?

2: how could I use the class "Calc" for example in the *.html file?

Note: I am using chrome (62.0.3202.94 (Official Build) (64-bit)) on mac OS 10.13

// app.js
import { Calc } from './calc.js';

class Test {
    static hello() {
        console.log("hello from class1");
    }
}

let c = new Calc(); // this works!

console.log(c.sum(2, 3) + 1); // 6

export { Test }; 

and

// calc.js
import { Test } from "./app.js";

class Calc {
    sum(a, b) {
        return a + b;
    }
}

let t = new Test(); // Uncaught ReferenceError: Test is not defined
t.hello();

export { Calc };

Finally the HTML file:

<html>

<head>
    <meta charset="utf-8" />
    <script src="./app.js" type="module"></script>
    <script src="./calc.js" type="module"></script>
</head>

<body>
    <h1>ES6</h1>
<script>
    let c = new Calc();
    // simulate input summation from two textboxes for example
    console.log(c.sum(2, 1)); //Uncaught ReferenceError: Calc is not defined
</script>
</body>

</html>

Upvotes: 1

Views: 5120

Answers (1)

Joe Clay
Joe Clay

Reputation: 35787

Problem 1:

You have a circular dependency - app.js imports calc.js, but calc.js imports app.js.

Usually the module system will ensure all of a module's dependencies are executed before the module itself, but this is impossible when your dependency tree has cycles - it has to pick one of them to run first. In this case, calc.js is run first, at which point Test isn't yet defined!

There are ways to work around this if you're careful, but cyclic dependencies are pretty much always a sign that you're structuring your code wrong - the best solution is to reorganize it so you no longer have a cycle.

Problem 2:

ES2016 modules don't execute in the global scope. If you want to make something available to the window as a whole, you need to be explicit:

window.Calc = Calc;

Upvotes: 4

Related Questions