We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Browser Modules

Modern browsers now support ES6 modules, but there are a few things to be aware of. If your HTML has "normal" old script tags, those scripts will not be treated as modules. They will execute one after the other, in the order they appear in the HTML file.

<script src="meFirst.js"></script>
<script src="meSecond.js"></script>

If you want to use ES6 modules, you need to use the type="module" attribute on your script tags.

<script type="module" src="math.js"></script>
<script type="module" src="main.js"></script>

Modules have a few great advantages:

  • Stuff defined in a module is not in the global scope. To be accessed from another module, it must be exported.
  • Modules are deferred by default, meaning they only run after the document has been parsed.
  • Strict mode is enabled by default. Yay!

Assignment

Let's take a break from heifer and try doing some JavaScript in the browser.

No, this still isn't a frontend course, don't @ me

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>🚨 Breaking News</title>
    <style>
      body {
        font-family: sans-serif;
        text-align: center;
        margin: 0;
        padding: 0;
      }
      h1 {
        color: red;
      }
      button {
        padding: 10px 20px;
        font-size: 16px;
        cursor: pointer;
        display: none;
        border-radius: 8px;
        background-color: #252936;
        color: #ffffff;
        border: none;
      }
      button:hover {
        background-color: #3c4d4f;
      }
      canvas {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        pointer-events: none;
      }
      .fullscreen {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
      }
      html,
      body {
        height: 100%;
      }
      .dark-mode {
        background-color: #121212;
        color: #ffffff;
      }
      .dark-mode button {
        background-color: #b2c1d0;
        color: black;
      }
      .dark-mode button:hover {
        background-color: #919dab;
      }
      .dark-mode h1 {
        color: #ff5555;
      }
    </style>
    <script>
      if (
        window.matchMedia &&
        window.matchMedia("(prefers-color-scheme: dark)").matches
      ) {
        document.body.classList.add("dark-mode");
      }
      if (
        window.matchMedia &&
        window.matchMedia("(prefers-color-scheme: light)").matches
      ) {
        document.body.classList.add("light-mode");
      }
    </script>
    <script>
      import confetti from "https://cdn.jsdelivr.net/npm/[email protected]/+esm";

      const button = document.getElementById("celebrate");
      button.style.display = "inline-block";

      button.addEventListener("click", () => {
        confetti({
          particleCount: 100,
          spread: 70,
          origin: { y: 0.6 },
        });
      });

      document.getElementById("headline").textContent =
        "🚀 JavaScript Takes Over the World!";
      document.getElementById("loading-text").style.display = "none";
    </script>
  </head>
  <body class="fullscreen">
    <h1 id="headline">Loading latest news...</h1>
    <p id="loading-text">
      (Please wait... our top reporters are investigating!)
    </p>
    <button id="celebrate">Celebrate the News! 🎉</button>
  </body>
</html>

and bright if you're used to dark mode... sorry, not sorry

So what went wrong here? If you open your browser's developer console you should see two errors.

  • A syntax error – this is caused by the import in the second script tag.
  • A type error – this happens because the script executes before the page content exists, meaning a property is null.