ES6 - Native Modules

Defining modules were not available in Javascript earlier, compared to other languages. requirejs and other libraries were used to overcome this. However, ES6 introduced a module loader API which enables native module loading in javascript.

Let's look at how to implement native modules.

Look at the code below.

Notice the script tag has type='module and the script has .mjs extension.

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Native Modules</title>
</head>

<body>

    <h1>Native Modules</h1>

    <script type="module" src="main.mjs"></script>    
</body>

</html>

main.mjs

import { apiKey, uno as onu, deffer, fed } from './src/config.mjs';
import User from './src/user.mjs';

const vetri = new User('vetri', 'vetri02@gmail.com', 'thetascript.com')

console.log(vetri)

console.log(onu)

console.log(deffer)

const ages = [1,2,3,12,1,2,3];


You can import modules from other modules, refer to the full code here on github.

== This will only work with a server ==. You might get an error if you open index.html directly.

Install browser-sync to test this.

npm install -g browser-sync

then run

browser-sync start --directory --server --files '*.js, *.html, *.css'

this should load the page on http://localhost:8080 in the default browser.

Though most of the browsers support modules, adding a fallback option wouldn’t hurt. Follow the below steps to load the script as .js.

You can use webpack or parceljs to bundle this as a .js. Let's use parceljs.

npm install -g parcel-bundler

run

parcel index.html

this will create a dist folder in the local as shown below.

/dist
 --index.html
 --main.4b231a1f.js
 --main.4b231a1f.map

Now you can use the main.4b231a1f.js as the fallback in main index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Native Modules</title>
</head>

<body>

    <h1>Native Modules</h1>

    <script type="module" src="main.mjs"></script>
    <script nomodule src="/dist/main.4b231a1f.js"></script>
</body>

</html>

add nomodule attribute to the script tag which will load main.4b231a1f.js if modules are not supported in the browser.

References

  1. https://jakearchibald.com/2017/es-modules-in-browsers/
  2. http://exploringjs.com/es6

I have been going through Wes Bos's ES6 Course, a well-designed course for beginners/intermediates to jump into ES6. It's a must for all who work in any modern JS framework. However, I felt one of the course modules (ES6 Tooling) especially the systemjs part can be done using the native modules which has good support now. That's the start for this article.