Modules: what and why
As a Web Developer, working with text files is just a part of the game. The languages of HTML
, CSS
, JavaScript
, and PHP
are how we describe content to the browser, define behavior and reduce workload for the server and humans. But what happens when the text files get too long? It can be hard to find functions, variables, and objects you need to get the job done.
JavaScript Modules to the rescue!
Part of the ES6 JavaScript standard (to improve the interoperability of web pages across web browsers), modules are a self-contained unit of code that encapsulates related functionality. A term associated with OOP (object-oriented programming) encapsulation refers to two concepts: the bundling of data with their associated methods, and the limiting of access to data.
A module allows you to organize your JavaScript into separate modules/ files. Doing so makes your code more maintainable and reusable. By encapsulating related functionality you can easily track down problems and improve code instead of combing through a long text file.
The tools you’ll need
As convenient as JavaScript modules are, to use them you will need some special software and knowledge. The tools are:
A web server
Because JavaScript modules are fetched by the browser as HTTP requests (to the web server). The server uses the attributes on the script tag to recognize it as a module and fetch the file. These attributes will be discussed soon. There are many different server software available, personally, I use MAMP.
A web browser and text editor! obviously. I like Chrome and Sublime.
Knowing the JavaScript keywords
Using the ES6 module feature requires knowledge of the correct HTML
attributes and JavaScript
keywords. The keywords to know are:
import/from
Imports the code from the file path defined as a string after the
from
keyword. Note: The names used for the namedimport
must match the names used in theexport
statement.
//script.js
import {getElement, USDollar} from "./utility.js";
Note: Do make sure the file path is correct. As always, if any issues arise just check the console. If anything went wrong with the file path, you’ll get an error like this:
export/default
Export the code following the keyword (or contained in the code block).
default
tellsJavaScript
that the code following the keyword is thedefault
(primary) function to export from the current file.//utility.js export default function getElement(element) { return document.querySelector(element); }
Note: This isn’t the only way to export JavaScript
. As you’ll soon see, there is another way.
Choosing the HTML attributes
To include JavaScript
in our HTML
, we use the script
tag. The attributes and values needed are as followed:
src=“path-to-file”
Assuming your JavaScript is in an external file (for proper organization and separation of concerns, it should be!)
type=“module”
This is necessary to tell the browser to treat the
script
tag as a module. Otherwise, you get an error similar to this (see the first console error): Cannot use import statement outside a module. This happens because theimport
keyword is only valid when the script is a module, defined by thetype=“module” attribute
.The import keyword used outside of a JavaScript module is considered invalid. So, mind your HTML attributes!
The final result looks like this
//index.php
<script src="./scripts/script.js" type="module"></script>
Preparing the script for export
Now that we have gone over some keywords, let’s discuss their implementation. Before you can import
anything, you must first export
it in its file of origin. As we saw above, the syntax looks like this.
//utility.js
export default function getElement(element) {
return document.querySelector(element);
}
As mentioned before, the default
keyword tells JavaScript
that this code is the primary export. It isn’t necessary and can be omitted.
//utility.js
export function getElement(element) {
return document.querySelector(element);
}
The first example using default
is called a default
export. The second example above uses a named export
. You can have multiple named export
-s per module but only one default
export. One advantage to using the default
keyword is that when you import
it, you can name it whatever you want:
//utility.js
export default function getElement(element) {
return document.querySelector(element);
}
//script.js
import {elementGetter} from "./utility.js";
// since it was exported as default, JavaScript knows it is the primary code exported from the file. So you can name it anything
Another variation you will see for exporting multiple pieces of code is the export
keyword followed by a code block AKA curly braces:
//utility.js
function getElement(element) {
return document.querySelector(element);
}
let USDollar = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
});
export {
getElement,
USDollar
}
Preparing the script for import
As you’ve seen by now, how you import
JavaScript
is intrinsically linked to how it is export
-ed. If you export
-ed it as default, you can name the import
anything. As you saw above, If you used a named export
you have to use a named import
.
If you are familiar with the newer features of JavaScript
, like object destructuring, the syntax for the import statement may look familiar to you. But be warned, this IS NOT object destructuring. It may have a similar syntax to object destructuring but is actually a named import. Compare the differences in syntax by clicking the MDN links in the resources section of this blog post.
Putting it all together: the code
I wrote the code used in this article for a challenge from the excellent book by Brian P Hogan, Exercises for Programmers. You can see the code on my GitHub and find a link to the book in the resources below. I hope you learned something from this article. Let me know in the comments how you use JavaScript
modules to organize your code.