Professional JS: Features You Need to Know

ES Modules Import Tree

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
Professional JS: Features You Need to Know

Check out a free preview of the full Professional JS: Features You Need to Know course

The "ES Modules Import Tree" Lesson is part of the full, Professional JS: Features You Need to Know course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano creates a simple example where he imports three modules, and each module logs a message to the console. He explains the concept of module execution order and how modules are only executed once, even if they are imported multiple times.

Preview
Close

Transcript from the "ES Modules Import Tree" Lesson

[00:00:00]
>> Maximiliano Firtman: This is the lab, the only one that I will do completely from scratch. So you don't need to download anything, in case you wanna follow along. It's not a big deal, it's gonna be a very simple example of modules, okay? The rest of the examples we will jump directly into the URL that we mentioned before but this one I will get out, I will open BS code.

[00:00:21]
I'm in an empty folder, nothing is here. I'm going to create a new index HML file, and I'm going to create a basic HML, okay? Nothing fancy, something very simple, and I will add a script source script1.js okay? I will save this. And of course, I don't have that file, script1.js so I will Ctrl click on Windows command, click on the Mac, on my BS code, I will create the file, okay?

[00:00:54]
And I can say, console, low, I'm script1, okay? Nothing fancy, something very simple. So is this a module? Actually, when you're reading a module you don't know if it's a module or not. Because actually a module is not the file itself, it's how you imported the file, or how the engine imported the file.

[00:01:21]
When you're looking at the file, you don't know if it's a module or not, okay? In fact, I am not actually loading that file as a module. So, in this case, if I execute this, it's not going to be executed as a module. So I need to add type = module.

[00:01:42]
So if you don't add this, that's fine. It's not a module, okay? So now it's a module and because it's a module I can import other modules as well. So I'm going to create three modules here, script1, script2.js, script3.js. So very simple, very simple to understand the concepts.

[00:02:09]
And everyone will just say in the console m1, m2, m3, okay, nothing really complicated. Shot three messages in the console. So of course I can go to my index HTML and add three scripts, I can do that. If I do that, I'm creating the three different trees. Okay, actually it's one three in the context, the whole context but in this case we are opening three different trees, but I don't need to do that, I can just import.

[00:02:48]
For example, from a script one I can import ./script2 and look at this BS code by default, give you a suggestion, that suggestion is not gonna work. If I press return, it's not adding the.js, okay? So for .js, it may work, it depends if you're going through a bubble or not.

[00:03:13]
If you're going through a bubble for the browser, it will work, but it's not gonna work in my browser directly. I need to add the node.js. By the way, I'm not specifying what I'm importing, actually. Can I do that? Yes, you can. It's not mandatory to say that I wanna import something in my context, in my local module context.

[00:03:37]
And that import sounds weird, I know. Even if you have experience working with modules, you feel like something's missing there. But let's run this. So, I will open a trusted terminal here, and I'm going to say npx serve. I also have live server here, plug in. It's just opening this in a web server, actually, I can open this directly with the file protocol.

[00:04:05]
So of course, it's an empty page, but if I open the console, I have a 404 on the file icon. I don't care, but I can see this. You can see the three scripts are being loaded and I'm pretty sure that some of you were not expecting this, because I didn't import anything in particular from each module, okay?

[00:04:27]
So I'm not saying I wanna import the variable, actually, I don't have anything exported from these modules. I have three modules, but just console log messages. And now that's a tree, and you can see the order in which they were executed. It's also not the order that you were expecting, probably, I guess, so why?

[00:04:52]
Look at this. I have an HTML that is loading a script1, so we're expecting that to be executed first, right? Because it's the first entry point. And 1 is importing 2 and 3. But actually, the execution because JavaScript has two phases, I'm not sure if you know that.

[00:05:17]
When JavaScript is actually executing your code, it has a two-phase process. In the first phase, for example, it's recognizing the import statements. And it says, you have an import? Okay, let's go and import that, okay? And then it's executing the file. So that's why the order is 2, 3, and 1.

[00:05:41]
>> Maximiliano Firtman: Yes.
>> Male Speaker 1: Now, would that order change if you put the line four console log in script1 up to line one before?
>> Maximiliano Firtman: So you're saying what happens if I change the order like this? Will it work? First, for some of you, I think that it will hurt your eyes, right?

[00:05:56]
Like some of you are expecting all the imports to be at the top. Let's see, if I execute this, it's not changing the execution order, why? Because of the two phases. So on the first phase, JavaScript is not executing the JavaScript code. It's just picking some things. For example, imports.

[00:06:20]
It's also variables. Defining variables and functions is picking them. And then after it's in this case, downloading all the other scripts and executing the scripts, it will execute the console log, okay? Another question for you to think about. Again, if you have experience with modules, maybe you haven't thought about this in these details.

[00:06:45]
What happens if a script2 is also importing a script3?
>> Maximiliano Firtman: Will I get two console logs? So saying I'm a script3 or only 1,
>> Maximiliano Firtman: No idea I am seeing phases of no idea. So again, I have a script1 is importing 2 and 3, and now 2 is also importing 3, okay?

[00:07:14]
So this is what we have right now. I'm going to refresh, and I'm having something similar but in different order. But the important part here is that three is not executing twice. So if a module is already in the tree, it doesn't matter if someone else is importing it, it's not executing it again.

[00:07:39]
>> Maximiliano Firtman: Okay, makes sense? So you can safely add or import as many modules as you want from any module without caring too much about what if other module is also important it doesn't matter. It will be loaded only once and executed only once, okay? So that's the tree, there is no simple way to see the tree actually visually see the tree.

[00:08:06]
So, doing counselor is a way to see the order in which they are executed, okay? But okay, it makes sense?
>> Male Speaker 2: Is this the same as hoisting?
>> Maximiliano Firtman: Hoisting, so, it's not the same as hoisting. But hoisting has to do with the two phases that I mentioned before.

[00:08:28]
For example, hoisting will let you create a variable x and use the variable before the declaration, why? Because there are these two phases. So hoisting had to do with this, in the first phase it recognizes, we will have an x variable, okay? And then on the second phase, it executes that.

[00:08:52]
So x is a variable. So it says, okay, it's that. So it's not the same as hoisting, but the relationship is actually that part, this two-phase declaration. The imports are going through the first phase before executing, okay? But typically you don't do this. I mean, do we have use case?

[00:09:12]
In fact, if you have ever played with modules, do you remember any use case where you were importing like this without specifying something here with the from key?
>> Male Speaker 1: CSS files for long.
>> Maximiliano Firtman: Can you import CSS files in JavaScript? What's that?
>> Male Speaker 1: That might be with.
>> Maximiliano Firtman: That's probably Babel with React or with a framework that will let you import a CSS file or an SVG file.

[00:09:43]
And then use that, that then will replace that import into something else. But that's definitely not ECMAScript. In ECMAScript, I mean, if you try to import a CSS file, you will get a syntax error, because it will try to parse your CSS as JavaScript. And yeah, it's not JavaScript.

[00:10:03]
So one use case to these imports is web components. If you're using web components and you create one file per component, the only thing you need is to have them in the tree, in the module tree. And you don't need to even import the component, okay? Because typically component goes to a new HTML tag.

[00:10:30]
So it's registered in the systems with a different system. So that's a way, but most of the time what you are used to is that I know script3, we create a function, okay? And the function will return an item three. We have an export declaration, that's the most common way to work with modules, okay?

[00:10:53]
So then from a script2, you can import and specify in curly braces, all the items that you actually want to import Import from, and you need to use the from keyword. So you're going to import, and here you will say test three from a script3. So then you can execute test three from another.

[00:11:19]
From a script2, you can execute or you can create an object from a class declaration that is in a different file, or you can use a value variable and object that was defined in the other file. That's the most common scenario. And can I use it from script1?

[00:11:35]
No, unless I also add something similar here. There three from.
>> Maximiliano Firtman: On every module that you wanna use that function you need to explicitly say when I import that function, okay? And that's probably something that you have already used before. And the default one is one instead of exporting different things, you use export default and then you pass only one value can be a class declaration, a variable, it can be a function, or it can be an object.

[00:12:10]
So then I can export an object and that object I have several properties, the name, I'm a script2, and then I have a function that is a test. Let's say it's a function that will do something.
>> Maximiliano Firtman: And now I'm exporting an object, only one object. And from the other side, when you import.

[00:12:34]
For example, from here when you import you just specify one name for that object. And this is the pattern where we can discuss if that object will be capitalized or not, like script2 capital S or not. It's up to you. But then you can say a script2 dot and you have test and you have name
>> Maximiliano Firtman: Okay, that's the difference, so if you have calibrases it's not a default export it's just a series of exports available from the other module.

[00:13:09]
If it doesn't contain the calibrases, it's just a default export. Actually, that's all for modules. It's not so complicated. It's just to understand how you can now modularize all your scripts have in mind this works also node.js with everything we've mentioned on how to enable modules before.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now