This is the 12th day of my participation in the August Challenge

preface

As applications get bigger and more complex, we want to break them up into multiple files, called modules. A module can contain classes or libraries of functions for a specific purpose. But eventually scripts became more complex, so the community invented many ways to organize code into modules, using special libraries to load modules on demand.

Traditional modular systems

  1. AMD – one of the oldest modular systems, originally implemented by the require.js library.
  2. CommonJS — a module system created for node.js servers.
  3. UMD – Another module system, recommended as a generic module system, compatible with both AMD and CommonJS.

Summary: Language-level module systems appeared in the standard (ES6) in 2015 and have evolved since then, and are now supported by all major browsers and Node.js. Therefore, we’ll start learning about modern JavaScript modules from now on.

The nature of modules

A module is a file, a script is a module, modules can load each other, you can use export and import to exchange functions, call each other in the method.

  1. The export keyword marks variables and functions that can be accessed from outside the current module.
  2. The import keyword allows you to import functionality from other modules.

Example:

// sayHi.js export function sayHi(user) { alert(`Hello, ${user}! `); }Copy the code

… Then another file might import and use this function:

//  main.js
import {sayHi} from './sayHi.js';
​
alert(sayHi); // function...
sayHi('coolFish'); // Hello, coolFish!
Copy the code

The import directive loads the module through the path./ sayhi.js relative to the current file and assigns the imported function sayHi to the corresponding variable. Let’s run this example in a browser. Because modules support special keywords and functions, we must use them

<! doctype html> <script type="module"> import {sayHi} from './say.js'; document.body.innerHTML = sayHi('coolFish'); </script>Copy the code

The browser automatically retrieves and parses the imported module, and then runs the script.

Module import

If the same module is imported to more than one other location, its code will only be executed on the first import and then the contents of the export will be made available to all importers. That is, modules compile once and then share the contents of export with each other.

Example:

//  1.js
import {admin} from './admin.js';
admin.name = "Pete";
​
//  2.js
import {admin} from './admin.js';
alert(admin.name); // Pete
Copy the code

1.js and 2.js import changes made to the same object in 1.js, which are also visible in 2.js. So modules are executed only once. The export is generated, and then it is shared with all imports of it, so if the admin object is modified somewhere, other modules can see the change. This behavior lets us set the module on the first import. We only need to set its properties once, and then we can use them directly in further imports.

This in the module

This is a small feature, but we should mention it for completeness. In a module, the top-level this is undefined. A comparison with a non-module script shows that the top-level this of a non-module script is a global object

<script>
  alert(this); // window
</script>
​
<script type="module">
  alert(this); // undefined
</script>
Copy the code