JavaScript ES6 Modules ====================== ES6 modules provide a number of useful features. Perhaps the most important of these is the ability to keep your JavaScript in separate scopes. This means you do not have to worry about a variable in your code having the same name as a variable in some other JavaScript code on a given page. This is achieved without the need for namespaces. It is this aspect of ES6 modules that I want to discuss here but it is important to know about the other properties that ES6 modules have and some of these will be considered. The intention of this article is to illustrate some behaviours of ES6 modules in order to make it easier to use them effectively. The article does not attempt to describe how they should be used in production code. There is a section on further reading at the end which may be helpful for that and other information. In an HTML document, JavaScript is deployed by using the HTML, ```` If the JavaScript was written in a file called `main.js` in the same directory as the HTML document that needs to use the JavaScript, it could be used by including this code in the HTML document: ````. ES6 modules behave as if they had the ``defer`` attribute. Normally one would have to write `` When this code is run in a browser with developer tools open we get the following displayed in the console: .. code-block:: console :caption: Figure 2. browser console output myVar 42 Uncaught SyntaxError: redeclaration of let myVar If we now convert the code in one of the `` In the example above we have the variable ``myVar`` in global scope with a value of 42 and we also have the variable ``myVar`` in a module scope with a value of 43. We could add as many ES6 modules as we liked and declare a ``myVar`` variable in all of them without error as they would all be in their own scope. The output in the browser console when `index.html` is run is shown in figure 4. .. code-block:: console :caption: Figure 4. browser console output myVar 42 myVar 43 Import and Export ----------------- One of the most useful features of ES6 modules is that code can be exported from one module and imported into another one. However, this can not be done when JavaScript is written as the content of ``

ES6 Modules

.. code-block:: javascript :caption: Figure 6. main.js let myVar = 43; console.log('myVar', myVar); This situation is equivalent to that shown in figure 3 and like that does not generate an error in the console giving the same output as shown in figure 4. Also, no warnings are shown in visual studio code. The previous method is certainly not recommended but is useful to consider. Now we can create another JavaScript file and export a variable from it and import it into `main.js`. We will call the new file `utilities.js` and we will declare a variable called ``utilityVar`` in it. The declaration is followed by the ``export`` statement. Then we use the ``import`` statement inside `main.js` to import ``utilityVar``. Finally, in `main.js` we will ``console.log()`` the ``utilityVar`` and ``myVar`` variables: .. code-block:: javascript :caption: Figure 7. utilities.js let utilityVar = 'u'; export { utilityVar }; .. code-block:: javascript :caption: Figure 8. main.js import { utilityVar } from './utilities.js' let myVar = 43; console.log('utilityVar', utilityVar); console.log('myVar', myVar); There is no need to change `index.html`, which remains as it was in figure 5. When we now access `index.html` from the browser we get the result shown in figure 9. .. code-block:: console :caption: Figure 9. browser console output myVar 42 utilityVar u myVar 43 Module Scopes versus Modules ---------------------------- In `main.js` the variable ``myVar`` is declared and assigned a value of 43. We can declare a variable also called ``myVar`` in `utilities.js` and export it so long as we do not import it into `main.js`. We could import it into another file, say `main2.js`. If ``main2.js`` was the entry point for another ES6 module ``

ES6 Modules

.. code-block:: javascript :caption: Figure 11. utilities.js let utilityVar = 'u'; let myVar = 45; export { utilityVar, myVar }; .. code-block:: javascript :caption: Figure 12. main.js import { utilityVar } from './utilities.js'; let myVar = 43; console.log('utilityVar', utilityVar); console.log(myVar); .. code-block:: javascript :caption: Figure 13. main2.js import { myVar } from './utilities.js'; console.log('myVar', myVar); When we run `index.html` in a browser the output to the developer tools console is shown in figure 14. .. code-block:: console :caption: Figure 14. browser console output myVar 42 utilityVar u myVar 43 myVar 45 This shows that we can have the same variable name with different values because they are in different module scopes and one is in global scope. We can also see that the `utilities.js` file declares and assigns two different variables (``utilityVar`` and ``myVar``) which end up in different module scopes because one of the variables is imported into `main.js` and the other into `main2.js`. These two files are the entry points for two different ES6 module ``