A.4. Modules

To explore what modules are, we should take a peek at a common feature from other languages: the import. Consider the following class in Java, adapted from a tutorial at www.javatpoint.com/java-swing.

Listing A.16. Example of a Java import
import javax.swing.*;

public class SwingHelloWorld {
     public static void main(String[] args) {
               JFrame f=new JFrame();
               JButton b=new JButton("click");       1
               b.setBounds(130,100,100, 40);         2
               f.add(b);                             3
               f.setSize(400,500);                   4
               f.setLayout(null);
               f.setVisible(true);
    }
}

  • 1 Creates instance of button
  • 2 Sets x axis, y axis, width, height
  • 3 Adds button to UI
  • 4 Sets button size

In this Java-based example, we’re programmatically creating a button and placing it in a window. If you don’t know Java, this looks pretty easy, right? We could actually do something pretty similar and concise with HTML and JS. The difference with JS is that we would be using the document namespace to create our button:

document.createElement('button');

A.4.1. Top-level objects in JS

Have you ever thought about all of the methods we use every day from document or window? There are lots, and even though it can be a bit overwhelming, it’s manageable once you get used to it. These top-level, or global, objects are designed to control the DOM and your visual elements within. Meanwhile, there are other global objects that deal with other concerns. We print logs to our console with console.log and can parse JSON with JSON.parse. We also have a top-level Math object, which we can use to do trigonometry, create random numbers, and more.

When you think about all of these top-level objects that we, as JS developers, should just know, it can seem a bit chaotic. Alternately, when you consider the Java example in listing A.16, you’ll notice objects like JFrame and JButton to create the window and button, respectively—but where did those objects come from?

To answer this, consider that graphic interfaces aren’t necessarily something that Java developers do. Many do, but many will be happy doing all backend work. Given the wide breadth of everything Java needs to do and deal with when it comes to third-party libraries, Java, as well as most other languages, has an import feature.

Note the import javax.swing.*; at the top of the class. This is actually shorthand. To be more concise, we could expand this to be

import javax.swing.JFrame;
import javax.swing.JButton;

Using the .* syntax imports all classes or nested classes in javax.swing and makes them accessible by their name in the class you imported them in, which is why JButton has the smarts to create a visual button.

A.4.2. Module syntax for importing and exporting

Until now, browser-based JS has never had a built-in way to manage external dependencies other than by using a <script> tag. Third-party libraries like require.js have tried to fill this gap, but this was never adopted as a specification. Now, though, we officially have the native JS feature of modules. In order to use modules, which enable imports just like other languages, there’s a small bit of setup.

First, let’s prepare a little JS to be usable as an importable module. In a separate JS file, we can write just a few lines:

export default function demo() {
   console.log('demo');
}

Breaking this down, it’s obvious that we are defining a function named demo that logs “demo.” The keyword export is what makes this function able to be imported. The keyword default is simply declaring to any JS that imports this script that this function is the default variable, object, or function that is used when importing the script.

To be a little clearer, let’s look at how we import in the following listing. To do so, we need to declare that the <script> tag that we’re using is of type module.

Listing A.17. Setting the <script> tag type to enable JS modules
<script type="module">                           1
   import DemoModule from "./moduledemo.js";     2
   DemoModule();
</script>

  • 1 Uses script type of module
  • 2 Imports a script

We can simply import the few lines of JS we just made. The name DemoModule is a made-up name in this case. With this import, we could call what we import most anything we wanted, like in figure A.6. Because we’ve declared our function as default in the imported JS, we don’t need any further specificity.

Figure A.6. Using imports to link to external JS files for a variety of purposes, including custom classes or even other Web Components

A.4.3. Working with multiple functions in the same module

We do need a bit more specificity if there are multiple things to import from a JS file, like the example in the next listing.

Listing A.18. Exporting multiple functions in the same module
export function hi() {               1
   console.log('hi');
}
export function bye() {              2
   console.log('bye');
}

  • 1 A function exported from a module
  • 2 An additional function exported from the same module

Before, we could use shorthand and make up any name we wanted. In the next listing, we need to use the real names of the functions we defined in the modules as we import them.

Listing A.19. Importing specific and multiple functions from the same module
<script type="module">
   import { hi, bye } from "./multiplemoduledemo.js";     1
   hi();                                                  2
   bye();
</script>

  • 1 Imports two exports from the same module
  • 2 Uses the first of the two exports

That’s not to say we couldn’t invent our own names if we really wanted to. To accomplish this, we can use the as modifier.

Listing A.20. Aliasing functions from a module
<script type="module">
   import { hi as SomeName, bye as SomeOtherName } from
     "./multiplemoduledemo.js";                          1
   SomeName();
   SomeOtherName();
</script>

  • 1 Uses the “as” keyword to reference the imports by a custom name

Lastly, we can simply scope both the hi and bye methods to an object with the as modifier.

Listing A.21. Aliasing functions as a group from a module
<script type="module">
   import * as Greeting from      1
     "./multiplemoduledemo.js";
   Greeting.hi();
   Greeting.bye();
</script>

  • 1 Uses * to import everything under the object of “Greeting”

Modules are fantastic for use in Web Components. Chapter 5 details how they can be used to keep your Web Components completely self-reliant, managing all of their own dependencies.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset