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.
<!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:
// 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:
// 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:
function sayHello() {
alert('Hello!')
}
And try to call it from the HTML:
<button onclick="sayHello()">Say Hello</button>
You'll get the following exception:
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.
<body>
<h1 id="title"></h1>
<button id="year-btn">Get Current Year</button>
</body>
<script type="module" src="./index.js"></script>
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: </span><span class="p">${</span><span class="nx">currentYear</span><span class="p">}</span><span class="s2">
;
});
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 extension from the extensions marketplace.
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 🥳
Top comments (0)