Modules

Roger PoonBy Roger Poon

JS++ Designer and Project Lead

Modules provide a way to organize code and divide an application into smaller parts. For example, a personal computer can be divided into keyboard, mouse, and monitor "modules" that can be separately connected.

Ideally, in modular design, we want our modules to be independently "re-usable." A PS/2 keyboard can be connected to any machine that has a PS/2 port because it's not tailored for an individual machine. Likewise, in software, your company or organization might have multiple applications that require authentication. Rather than re-writing the login and authentication code repeatedly for each individual application, you might want to expose the authentication functionality via a single module instead.

Modules in JS++ can be declared using the 'module' keyword.

Create a folder named 'Calculator'. Create a file inside the folder named 'Calculator.jspp' and add the following code:

    module Calculator
    {
        int add(int a, int b) {
            return a + b;
        }
        int subtract(int a, int b) {
            return a - b;
        }
    }
    

However, we can't just execute module code in the same file. JS++ encourages "modular design" and requires your modules to be separated from your main program logic.

Main File

The "main file" is the application entry point. In other words, you are telling the JS++ compiler, "My application starts here." JS++ allows only one application entry point. Let’s start with an example; create a file named 'main.jspp' that will import our 'Calculator' module with the following code:

        import Calculator;
        external $;

        int result = Calculator.add(1, 1);
        $(".display-result").text(result);
        

There's a lot going on here so let's break it down. In earlier chapters, we imported JavaScript libraries using the 'external' keyword. We still import jQuery (a JavaScript library) using the 'external' keyword in our above code. However, to import JS++ libraries (defined with the 'module' keyword), we need to use the 'import' keyword. This is an important distinction because it allows us to isolate unsafe JavaScript code.

The 'import' statement expects the full module name. In our simple example, the full module name is just 'Calculator'. JS++ knows what to do from there.

Next, we use one of the methods defined in the 'Calculator' module: the 'add' method. We simply add 1 + 1 and store the result in the 'result' variable. We then use jQuery to display the result of our calculation.

Let's create a calculator.html file for displaying our result:

        <!DOCTYPE html>
        <head>
            <title>Calculator</title>
        </head>
        <body>
        <div class="display-result"></div>

        <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
        <script src="app.jspp.js"></script>
        </body>
        </html>
        

Compile both the Calculator.jspp and main.jspp files. For Windows, this is as easy as selecting both files, right-clicking one of the files, and choosing "Compile with JS++". For Mac and Linux, use the following command:

> js++ Calculator.jspp main.jspp

An 'app.jspp.js' file should be generated by JS++.

The order of the input files does not matter. JS++ will automatically resolve the order that the files need to be compiled.

Open index.html and you should see the result: 2.

Nested Modules and Partial Qualification

In JS++, we can declare nested modules to further organize our code. There are two ways to do this:

        module MyApplication
        {
            module Calculator
            {
                // ...
            }
        }
        
or:
        module MyApplication.Calculator
        {
            // ...
        }
        

Let's change Calculator.jspp so that the 'Calculator' module becomes exclusive to 'MyApplication' to organize our code:

        module MyApplication.Calculator
        {
            int add(int a, int b) {
                return a + b;
            }
            int subtract(int a, int b) {
                return a - b;
            }
        }
        

Now that we've changed our module structure, we have to change our main.jspp import statement to reflect this. However, we're going to add a twist to save ourselves some typing:

        import MyApplication.Calculator; 
        external $; 
         
        int result = add(1, 1); 
        $(".display-result").text(result);
        

Compile the files and open index.html in your web browser. You should notice the same result: 2.

Did you notice the added twist?

Instead of calling Calculator.add, we simply called the addition function via 'add'. All of the following are correct ways of calling the 'add' function:

        add(1, 1); 
        Calculator.add(1, 1); 
        MyApplication.Calculator.add(1, 1);
        

The first two lines are known as "partial qualification." The third and last line is known as "full qualification." A fully-qualified name is the "full path, " and a partially-qualified name is a "relative path."

JS++ allows you to use such relative paths via partially-qualified names to keep your code terse. However, the more you qualify a name, the easier your code will be to read and follow. The choice of code style is up to you.