Understanding JavaScript/ES modules | Stephan Haewß | Skillshare
Search

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Understanding JavaScript/ES modules

teacher avatar Stephan Haewß

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Intro

      1:12

    • 2.

      Import and export

      25:03

    • 3.

      Dynamic import

      16:51

    • 4.

      Conclusion

      2:05

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

28

Students

--

Project

About This Class

In this course, I introduce the functionality of ECMAScript/JavaScript modules. With their help, you can structure your JavaScript applications to make them maintainable and easy to extend. The course goes into the various ways to import modules or individual exported functions/variables using the import keyword and also shows how to create modules using the export keyword.

Meet Your Teacher

Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Intro: Hello and welcome to my course ES6 modules, how to use them and how to create them. Es6 modules are the new standard for loading modules in JavaScript, which is supported in all modern browsers. It has a new syntax and extra keywords for importing and exporting. Almost all modern browsers can use it. They have integrated module loaders and also no jazz in its latest version supports it. Then every modern transpiler and Bundler and also TypeScript supports it. New projects starting out use the new module system and more and more of the existing projects are updated to support it. And it also helps with tree shaking and minimizing the bundle sizes. So if you're using ES6 modules, you're on the right track for developing modern and maintainable web apps. So in this course, you will learn how to use the Export and the import statements and how to integrate modules into your HTML page, how to use dynamic imports and how to use the syntax. I hope you will enjoy the course and see you in the first video. 2. Import and export: Hello and welcome to this video. I will explain in this video how to use ES6 modules, how to input them, how to create them, and how to integrate them into your HTML. First, let's talk about shortly about my development environment. I have videos to recode as an IDE. You can use that too. It's a great idea from Microsoft. It's free. You can download it for my girls, for Windows, for Linux. But you can also use something else. You can use your favorite text editor, whatever. It doesn't really matter. And I'm using a VGS as a deaf server, which is transpiring code on the fly. But you don't have to use it. You can use anything else. You can use a normal server, you can use a webpack, dev server, anything you like. So let's get started. And every web page and every rep application starts within HTML, in this case, index.html. And here it is. It's quite simple. It has the title VII tab because I'm using create VT to create a project. So I have this div here, which only contains little texts. So that doesn't matter. But here we have the important first tag. It's the script tag of course, because it's, it's loading a script. In this case, it's the sauces main JS, which is over here. We check it right now. Main JS, at the moment it's empty, but I will put in some code there. So you could also put some code here inside the script tag and then omit the source. That's also possible that you should already know that it's normal script tag. It works like a normal script tag. Only difference is you have type module here. And this the important thing if you want to use keywords are statements like import and export. In the script, you have to use type module here. There's another possibility too. Do dynamic imports. You can use the import function and you can import modules, ES6 modules with that. But the standard way to statically referenced them is the script tag and type module. So this the important thing, type module. And you can write your code here inside, or you can use the source attribute and point to your JavaScript. So let's check if this is really loaded. So I put a year some log, Just main JS, and let's check the console output. Okay, so here we have it. That really works. So our script, our module, is loaded. And at the moment, it's not visible that it's a module. But we will put in some modules specific code here. So at the moment we have this log, we can leave it here. But what is the important thing in the module? It is that the module can export something or you can import something or both. Of course, I'm doing here the import first, of course, because exporting here doesn't make any sense. Because I'm loading this via the script tag here. And I cannot use any export here. So we have to use first some import. So I'm putting an import statement here. This is the new thing. This is the ES6 module import statement. And so now we have to write import something. And then after that from and you can read that as import something which we specify later from the file, which is specified here, which is I created mod one. So it's mod one dot js. Please use the extension here. I could also omit the extension here, but this is because I'm using VHS as deaf server and it can resolve also the modules without any extensions. But I think it's best practice to put in the extension here. So it could also be something like JSX or you can also if your, if your environment supports it, you can also use, you can also import CSS. But for that you need some kind of a bundler, or in this case, the jazz deaths have also supports CSS importing. But normally you import a js dot js file. So we are importing from this file. And here we need to tell the JavaScript engine what to import. We can import different things. We can import specific exports, single exports. Or we can import a default, a default export, or we can import the complete module, which I'm doing here with this asterisk. And then I need to put them some identifier. I can completely make this up. So I'm using mod one. It doesn't really matter what the identifier is. I can reference the module with this identifier. So I can write here mod one dot something. It's empty at the moment, so I don't have anything here. So I'm just writing mod one. But the important thing here is the asterisk. As mod one means I'm importing the complete module as an object, and I'm naming it mod one. So this is my identifier for the module, the complete module. Let's go to the mod one module. At the moment is completely empty, so there's nothing to be imported actually, but we put in something here. We're importing something. So I must export something in this module. And this is where we use the export keyword. And after the export, we need to specify what we want to export. And I'm exporting a function here. And I cannot, I cannot export and anonymous function, I must name it here. So we name it, do it because it's just doing something, something like this console log. I'm just logging. Do it. Okay, so here we are exporting this function in main JS. I can import that and I'm inputting the complete module. So I should be able to do something like mod one dot, do it, and call it here. Let's check if it's working. Hello modules, that's our div, doesn't matter. Important thing is here in the console. Let's do it. This is what we, what we log in the, in the export at function to it. And then we have main js. Let's check back the code. Yeah, So we are calling the export function, do it. And in this function we're doing console log it. And after that, we do console log main JS. So that did work already. So that's fine. Let's export second function. So we copy this one and name it, do it too. We locked to its to the console. Okay, so what we should do here, what we should be able to do here is do it. Do it too from the mod one module. And is already suggesting me do too. And let's see if it works. Do it, do it too. It works. Okay, So we export it to functions here. Export function, do it. Export function due to the syntax is straightforward. You just put the export statement before the function here. And you can also export variables like liger, const, for example. This is a constant. I'm exporting this here. Mod one dot. This is a constant. And I can just console log it here. And let's check if it's working. Yeah, so it's outputting to here. So that works. We can export functions, we can export variables. So let's see if we can import a specific function or specific export. So here we have the syntax too. Import the complete module and reference it as this identifier mod one. I could rename mod one to just mod, for example, I can call it anything alike. But now if I want to import a specific export, I need to use different syntax. The syntax here is the curly braces, which is also used for structuring and which is kind of similar. So I'm putting here these curly braces and I'm getting this the exports here as suggestions for import. So I have to do is to, and this is a constant as the exports from this mod one dot js module. Let's import, do it. And we're commenting this out for the moment. And now I have imported do it. So I need to remove that because I just have do it now as an identifier. And I can call do it as a function because it's, it's exported here in mod one. And I'm importing just this one, export, this one function here. And it's called the same as it is exported here, do it. And I'm calling it. So let's see. Now it's working. I could do the same with due to an actress all kowtow could also import the const. So right now I'm completely importing every export here separately. I could call do it to an icon console log. This is a constant. And we should have the same output as before. It's due 22. So far so good. So we can import the complete module. You can import single exports or you can, you can import them separately here, like I did here. What if you want to call it? Let's say you have already have a function which is called to do it. You don't want to change the name because you want to use it here. And this one is just doing console log. And we'll output Local. Do it. So now we have a problem because we are defining here this function do it, and it's the same identifier as this import. But how can we import this and rename it to different identifier? This is possible with the same syntax as we did before with the star. As do it, as, let's say, imported. Do it. With this syntax. We renamed the export to this identifier imported, do it. Let's see if we can change this one to import it, do it, and see what the output is. So let's do it. Do it to two and local dude. That's what we expected now. Because here, this do it is, of course this function declaration. This do it and the exported do it from this module. We, we renamed it to import it to it. And you could do the same year if you like, do it to imported. So if you already have and identify in your module scope which is identical to an export of a module. You can use this syntax to rename the import. Let's check if it's still working. Yeah, it's working. So this is how you import exports separately. And this is important because you could also of course, import all with always with a star and important complete module. But it's a problem because you don't tell the bundler or the program that you use to bundle your JavaScript and minified and stuff like that. You don't tell this system what you actually use from this module. If you do this and just want to have, let's say you just wanted to have do it. So i'm, I'm commenting this out. If you just want to have, do it as important to it. The bundler, if it uses, for example, it's something like three tree shaking. The bundler knows that you only use, do it this function from this module. So theoretically if nobody else uses, are no other module users do it too, or this constant, the bundler could just erase this code. And so make your bundle size smaller. This is the advantage of this syntax here you just import one single export. So you should prefer this syntax. You can also, of course, if you use the complete modular, almost any, almost all the functions or the exports in the module. You can, of course, use this syntax. So, but if you, let's say you have something like low dash, which contains like 3030 exports or something like that. And you just need one function. It would be wise to just import this one function. Because your Bundler would then erase all the other functions. You have a much smaller bundle size. So I'm going back to this. Now. Let's, let's jump right to different syntax or a different import style. Let's call it like that. What we can also do is we can define a default export, default, export, default after the export. And I'm telling the module system that this is my default export. Of course. What can I do here to import the default export? So let's say this is my main function here. This is where, let's say 80% of the module users want to use. Or it's, maybe it's also the only function. Let's, let's do it like this. It's the only function is the only export. So you can, you can say export default function do it. And what you can do here is you can just write it like this. We'll change it to do it. And I'll erase this one. Let's check in the browser if it's working. Do it. It works. So if you ride export default, you can import this default. In this way. Just write import, then any identify, I could use a different identifier here I could use imported. Do it. Doesn't matter because this syntax is for importing the default export. So I can name it as I like. Still working. Doesn't have to be the export a name. So I could call it anything alike because I'm not specifying. I don't have to specify what I want to import because this syntax is for importing the default. Of course you have to have a default in the other module. So if I erase that, it shouldn't work anymore, I get a syntax error. Requested model does not provide an export named default. Okay? So doesn't work. Of course, I have to mark the export as default to import it as a default. So here you can put in some, any identify you, you'd like to import the default export here. And I can have a second export, which is not default. Of course you can only have one single default. But I can have a second one. That's not a problem. So how do this import I, of course I can. Right to import statements. The first one is importing the default, and the second one is importing. Do it too. That's completely possible. So I call it here, do too. And it should also work. I think I didn't change the console log here. So now do it and do it too. Okay, so that's how you use the import with a default export. You can also, you can also combine this. So the syntax is also possible. So if you want to import explicitly in this curly braces, in these curly braces, you can also explicitly say, I want to import default, name it important to do it. You must provide an identifier, of course, because this doesn't work, because you need an identifier here. So you can do this. So as soon as you put a default before the function, you will need to consider this here and import it as default as and then some identifier. Or you can, of course, use the much shorter expression and import it like that. Of course it's double now. So I should comment this out, or I just delete that one. Default as important to it. So that's totally fine. Let's check it. Okay, it's working. Okay. So this is how you import, and this is how you export. And in the next video we will talk about dynamic import, which is Yeah, it's just a function you can use to import modules. And you can use it to delay the loading of a module, for example. That will be the next video and hope to see you there. Bye. 3. Dynamic import: Hello, Welcome to this video. Here we'll explain how to use dynamic imports. So let's say we want to load a module, but not at the beginning of the load time over the page. But we want to load it later. Maybe wherever UI component, which is quite big, as many dependencies. So we don't want to load it at the start. At the beginning of the page load. We want to delay the loading of the module. To a later point in time. The user navigates, for example, to a new page. At this moment, the module will be loaded and not at the start. We can simulate this. Because we don't have user interaction here in our webpage at the moment, we can simulate this by using a setTimeout with the delay of a 1 second. And here we can try to load the module. Let's be naive and try this. Just erase this here. We don't need that anymore. Just put the import statement here in this function. So that doesn't work. It's already marked as an error. We tried anyway. And see what the browser says. Uncaught syntax error, inspect unexpected token. Okay? So this is the, the error message which is not quite, not quite explanatory, but I will explain it. This is the static import statement. And steady means it has to be at the top of the module. So it must be here. And you also, normally, you're not allowed to do this for example. So it is working here. But I think in the specification, it says that nothing else should come before the first input statement. Nothing in-between. So you should put your, all your inputs, your static imports at the top of the file, at the top of the module. So we've tried that. That doesn't work. But there's another possibility. And it's the import function, the dynamic import function, which is also called Import. And it's a function so we can call it. And we can give parameters. And the parameters, of course, the from. So where to get that module from. So we take the same path, the same module as with a static import and check it out what the result is. So there's nothing printed out here. Which is not very surprising because we're not doing anything here. So if this module's only loaded, there is no code to be executed here. Only the function declarations for do it and do it too. So that seems to work. We can also write a console log here to see that it is really loaded and really execute it here. After 1 second, mod one. Let's reload the page. After 1 second we see mod one printed out here. Okay, so that seems to work. But okay, so how do we get our module or the exports of the module? We could try something like that and put a debugger statement here to check it in the debugger. Okay, so it's stopping here and we check what is returned from the import function. Okay, this is not the module, as we can see. It's a promise, a so-called promise. If you don t know what promises are, I'll explain right now. But it's not what we may have expected here. One could think that, okay, so important is returning the module, the important module. But it is not. Instead it returns a promise. And the promise is something for asynchronous tasks. So import is loading a file from the server, which is naturally asynchronous. So it needs to get to the server. And the server needs to send the module code. And then the JavaScript engine needs to execute the code. So this is something which would block the JavaScript engine. So this is why it is asynchronous. And for asynchronous processes, we have the promise API. If you're not familiar with the promise API, we can check what is, what are the properties of the promise returned. It already suggests catch finally, and then the important thing is done here. Then is a method on the promise. And it takes a function. And it also, this function has a parameter. In this case, it's the module. So I should call this promise. And so we have a promise and we have the method then. And then method gets a, you can call it a callback methods, callback function. And this callback function is called if the promise is resolved. And in this case the promise is resolved when the module was loaded. And the parameter of the function will be the module. We can check this if put a debugger here and delete this one, we can check what mod is. And if my assumption is true, just reload the page nafta 1 second. We are really coming to this debugger and we check module. And yes, this looks like a module. It's also called module here. And we have the default export here in the default property. And we have do it to. The default function was called to do it, but it's, you can find it here on the default. So the actual name is not used as a property name by default is used here. And the second export was to do it too, which is accessible by the same name. So with this, we have the module. Here, we can use it. Let's do it. And suggestions already there, default or do it too. So we use first the default. And then we can use two to two and check what is printed out. So we have mod one, which is printed out at the start of the module, of the loaded module. Then we have do it and do it too. So that's what we have expected and it's working. This is not very nice syntax that you can write it in a better way. And for that we can use the async await mechanism or the async await syntax. If you have a promise, a return value with a promise like you have with the import. You can call or you can write a weight. And that means we are waiting. We are awaiting the resolving of the promise. So it's the same as here in this call back function. Except that it's not a callback function, but it's kind of normal code as you write it. In normal situations, synchronous situations, the only differences we have this await keyword. So I could write something like constant mod equals or is assigned a weight import. So this await, waits for the resolving of the promise. And the return value. Or the, in this case, the module will be the value of this expression. And I'm assigning it to mod. And then I can call do it and default. And due to, that should work except for I forgot something. And that is the async keyword over here. So if you're using a weight, you have to use async in the function you are using the weight in. These two go together. If you have a weight, then always use async. In front of the function. Except for you can also use it on the top level here. And then you don't use the async because you don't have a function. But as soon as you have a function that we have one because we're using setTimeout. You have to use the async before. Before the function. You can also use a normal function like this. And before the function keyword, you have to use async or before the 40 error function is shorter syntax for this. And if you use the async, you can also use the await. Await can be used everywhere where you have a return value of a promise or you have a promise. So you can await the resolving of the promise. There's also function in the browser called fetch, and it is also returning a promise and you can also use await with that. For example, it will be something like that. Await and here you would put the URL. Well actually we can use it. We can check out mod one dot js. We can load it as text. So let's check what response will be. This has nothing to do with modules, but anyway, it has something to do with promises and the weight. So I'm showing it here the response. The response is a response object. To get the actual texts, we need to call something on the response object. And this text. And this is also returning a promise, as you can see. So we already know how to use promises. So I'm signing more texts with a weight, responds to text. Dot text is also returning a promise and I'm waiting for the resolving of this promise. And then I'll get the mod text. Let's check it. More text. Yeah, and then we have our text of mod one dot js. So this little excursion for promises, which we have to use here. So either you use dots then with the callback function. And this callback function is called whenever the promise is resolved. Which in this case is when the module was loaded. Or you use the much nicer syntax await import. And then you directly get the molecule. And then you can use the module as if you would. Write a static import mod from dot mod one, JS that will be the same. So in this case mod would be the same. You can call default or do it too. So we can test it here. Yeah, So I'm reloading. First. It's writing, do it, do it too with the static import, and then do it and do it too with a dynamic import. Static import, and here, dynamic import. So if you want to load a module just in time, for example, if the user navigates to a new page and you want to render a new control. Then you can use the dynamic import. And it returns a promise. And you have to either wait the promise or use the dot then methods. And then you get the module. Just like if you would use this syntax. 4. Conclusion: So in this video, I will conclude the course and summarize what I've showed you about ES6 modules. We've seen how to integrate modules into HTML with a script tag and type module. So this was our first module here, main js. Then we've imported the second module in our first module into our first module. And this is the second module. We have exported two functions here. One is a default export and one is not. And you have seen how to import the whole module, the complete module with this asterisk. We have also seen how to import only specific exports. So for example, here we import only do it two. Or we could also import default as do it. And finally, we've seen how to use the input function here, which is used to dynamically load modules at runtime. And we have learned how to use the promise API and how to use the new keywords, a single weight, to use the import function and immediately get the module so that we can call the exported functions here. So I hope you've enjoyed the course, and I hope that you are now able to use ES6 modules successfully. And with a bit of confidence. Feel free to check on my other courses on web development and JavaScript. And good luck to you and goodbye.