Modules in Javascript

Modules in Javascript

##Modules in HTML

JavaScript started with a small role to play on an otherwise mostly HTML web. Today, it’s huge, and some websites are built almost entirely with JavaScript. In order to make JavaScript more modular, clean, and maintainable; ES6 introduced a way to easily share code among JavaScript files. This involves exporting parts of a file for use in one or more other files, and importing the parts you need, where you need them. In order to take advantage of this functionality, you need to create a script in your HTML document with a type of module. Here’s an example:

<script type="module" src="filename.js"></script>

A script that uses this module type can now use the import and export features you will learn about in the upcoming challenges.

##Modules in JS

Modules ES6 finally, officially, adds Modules to JavaScript. This means, that you may split up your code over multiple files, which of course is a good practice.

This is common in ES6 already, however you always require a module loader for that. Once ES6 is broadly implemented into browsers, this will no longer be necessary.

Reuse JavaScript Code Using import

The keyword import allows you to choose which parts of a file or module to load. In the previous sections, the examples exported some variables. Here's how you can import it to use in another file:

import { add } from './math_functions.js';

Here, import will find add in math_functions.js, import just that function for you to use, and ignore the rest.

The ./ tells the import to look for the math_functions.js file in the same folder as the current file. The relative file path (./) and file extension (.js) are required when using import in this way.

You can import more than one item from the file by adding them in the import statement like this:

import { add, subtract } from './math_functions.js';

Use * to Import Everything from a File

Suppose you have a file and you wish to import all of its contents into the current file. This can be done with the import * as syntax. Here's an example where the contents of a file named math_functions.js are imported into a file in the same directory:

import * as myMathModule from "./math_functions.js";

The above import statement will create an object called myMathModule. This is just a variable name, you can name it anything. The object will contain all of the exports from math_functions.js in it, so you can access the functions like you would any other object property.

Here's how you can use the add and subtract functions that were imported:

myMathModule.add(2,3);
myMathModule.subtract(5,3);

Use export to Share a Code Block

Imagine a file called math_functions.js that contains several functions related to mathematical operations. One of them is stored in a variable, add, that takes in two numbers and returns their sum. You want to use this function in several different JavaScript files. In order to share it with these other files, you first need to export it.

export const add = (x, y) => {
  return x + y;
}

The above is a common way to export a single function, but you can achieve the same thing like this:

const add = (x, y) => {
  return x + y;
}

export { add };

When you export a variable or function, you can import it in another file and use it without having to rewrite the code. You can export multiple things by repeating the first example for each thing you want to export, or by placing them all in the export statement of the second example, like this:

export { add, subtract };

Types of Exports

There are two kinds of exports:

  1. named exports (several per module)
  2. default exports (one per module).

1. Named exports

A module can export multiple things by prefixing its declarations with the keyword export. These exports are distinguished by their names and are called named exports.

To split up your code, you basically export variables, functions, objects, … in one file and then import it in another file:

// In export.js file: 
export let myExportedVar = 42;
export function greet() {
   console.log('Hello!');
}

// In import.js file: 
import { myExportedVar } from ‘./export.js’;
import {greet} from './export.js';

For now till ES6 is not fully implemented onto all browsers, the .js in the file path is required. The official RFC of ES6 omit the filetype in the filepath.

We can also group export and imports. Example:

//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

//------ main.js ------
import { square, diag } from 'lib'; // Grouped imported variables
console.log(square(11)); // => 121
console.log(diag(4, 3)); // => 5

As explained already, you can also import the complete module - all variables, functions and objects using the *. As a recap, see example below:

//------ main.js ------
import * as lib from 'lib'; // defines an alias for the module and call it like an object name
console.log(lib.square(11)); // =>121
console.log(lib.diag(4, 3)); // => 5

2. Default exports

Modules that only export single values are very popular in the Node.js community. But they are also common in frontend development where you often have classes for models and components, with one class per module. An ES6 module can pick a default export, the main exported value. Default exports are especially easy to import.

Example of export:

//------ lib.js ------
var abc = 'abc';
function greet() {
   console.log('Greeting!');
};
export default 'abc'; // use `default` keyword to define it as default
export default greet();

//------ main.js ------

import abc, greet from '../lib.js'; // import with no **curly braces** syntax
console.log(abc) // => "abc";
greet(); // => "Greeting!"

Both named and default exports

If you need to export both default and named exports, the import can be either written in multiple lines like:

//------ lib.js ------ var abc = 'abc'; var num = 123; function greet() { console.log('Greeting!'); };

export num; // named exports export default 'abc'; // default export export default greet();

//------ main.js ------ import {num} from '../lib.js'; // import named exports import abc, greet from '../lib.js'; // import default exports


OR in a single line import

import abc, greet, { num } from './lib.js'; // always put default export first ```