Using ES Modules in native HTML & CSS apps
Tags: javascript, es6, esmodules, html
Published: 2024-02-04 19:31:10

---
title: Using ES Modules in native HTML & CSS apps
published: true
description: 
tags: JavaScript, es6, ESModules, HTML
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c51eii1t4hnm0miitljo.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2024-02-04 18:57 +0000
---

While using ES module imports in native HTML apps is a powerful feature, it comes with a set of challenges along the way. This blog will teach you how to overcome them.

## Challenge #1: The module script tag
To be able to use Import() statement in your JavaScript files and have them work as HTML scripts, you need to add `type="module"` tag to your script tag.

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1 id="title"></h1>
    <button id="year-btn">Get Current Year</button>
  </body>
   <!-- type="module" enables ES Modules-->
  <script type="module" src="./index.js"></script>
</html>
```


## Challenge #2: When importing custom modules you need to add .js suffix to the file import path

Consider this module:

```js
// date.helper.js
export const currentDateTime = new Date();
```

To use it elsewhere you need to import it using a file path, but you also need to set a `.js` extension on the import:

```js
// importing date.helper into index.js
 import { currentDateTime } from './date.helper.js';

console.log(currentDateTime.getFullYear()) // 2024
```

## Challenge #3: You can no longer call JavaScript functions from HTML

If you declare a function in the index.js file:

```js
function sayHello() {
  alert('Hello!')
}
```

And try to call it from the HTML:

```html
    <button onclick="sayHello()">Say Hello</button>
```

You'll get the following exception:

```js
ReferenceError: sayHello is not defined
    at HTMLButtonElement.onclick
```

The alternative to this is to use the `addEventListener` function to listen to click on the button and then act upon it.

```html
  <body>
    <h1 id="title"></h1>
    <button id="year-btn">Get Current Year</button>
  </body>
  <script type="module" src="./index.js"></script>
```

```js
import { currentDateTime } from './date.helper.js';

// pick up the button element from the HTML
const yearBtn = document.querySelector('#year-btn');

// listening to click events
yearBtn.addEventListener('click', (event) => {
  const currentYear = currentDateTime.getFullYear();
  document.querySelector('#title').textContent = `Current Year: ${currentYear}`;
});
```

## Challenge #4: You can no longer run the HTML files natively in the browser:

Usually, the HTML page can loaded just by double-clicking on the .html file. With ES modules in place, you'd need a background server to serve the index.html document for the script to work.

This can be achieved using NPM modules, but if you're using Visual Studio Code you can install the [Live Server](https://mirzaleka.medium.com/powerful-visual-studio-code-extensions-that-youll-want-to-use-1dc58cdc423a#c501) extension from the extensions marketplace. 

![live-srver extension VSC](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1y8aifnv5zdro68xczbp.png)

Then right-click on the index.html file and choose the *Open with Live Server* option. It should open up the web browser running on some port and modules will work fine.

From this point, you should be good to go. Happy coding 🥳