What is ESM, and How to use them in Next.js?

What is ESM, and How to use them in Next.js?

Published 8th, November, 2022

4 min read

ESM simply means 'EcmaScript Module'. For those who missed the initiation ritual in Vanilla JavaScript, EcmaScript simply means the set of rules coupled with the syntax that make up JavaScript.

JavaScript, on the other hand, has progressed so drastically, that it's descendants are hardly relatable. But thanks to Vercel who is building and maintaining NextJS, now you can use plain JavaScript modules with it, boosting its functionality and efficiency! If used alongside NodeJS backend with its EcmaScript module, Next.js can do wonders on your front end.

However, the Vercel development team has been working to make ES Modules full-fledged compatible with Next.js 11.1, both as input as well as output modules. As of today, you can import npm packages with the help of ES Modules by declaring “type”:”module” in the project’s package.json.

Vercel team has upgraded its own experimental support version for importing ES Modules, not directly in NextJs, but rather through URL, which does not require building any packages.  Perhaps, the best thing here, is that ES Modules are run as default and prioritized over CommonJS modules.

Now, take a good look at the snippet from Next.js official documentation, which exemplifies this.

// next.config.js
module.exports = {
    // Prefer loading of ES Modules over CommonJS
    experimental: {
        esmExternals: true
    },
};

URL import modules

As mentioned above, you can use ES Modules with Next.js through using URL imports rather than locally install and import. And this feature is game-changing since it does not consume any local resources such as computation and memory, thus helping not burden your local machine’s resources. This in return enables you with faster development.

After Vercel did its job, many independent developing teams have created their own JS-based packages to work along with Next.js. One such project is the Skypack, which is gaining rapid popularity.

Skypack works the network in a Bootstrap-like CDN fashion, thus not requiring the developer to compile and build it locally. It scans your npm code builder and then build executable packages for the ES module, which can be directly imported from your browser.

To enable this feature, you must specify the URL in your next.config.js configuration file and then enable the domains that you think are safe and reliable. This is how it’s done.

// next.config.js
modulename.exports = {
    experimental: {
        urlImports: ['https://cdn.skypack.dev'],
    },
}

The below code links to a confetti explosion animation by Skypack. The animation is defined in the variable 'confetti' which pretty much does all the heavy-lifting.

/* pages/index.js */
import styles from "../styles/Home.module.css";
import confetti from "https://cdn.skypack.dev/canvas-confetti";

export default function Home() {
  return (
    <div className={styles.container}>
      <main className={styles.main}>
        <h1 className={styles.title}>
          Welcome to <a href="https://nextjs.org"> Next.js! </a>{" "}
        </h1>{" "}
        <button onClick={confetti}>Throw Confetti </button>{" "}
      </main>{" "}
    </div>
  );
}

If you run the above snippet on your local machine, you will be able to able to get a wonderful animation of confetti blown up in the air on a button press.

The story of an error: Code gone ‘wrong’

Whenever we write a piece of code in Next.js, the data structures used are discoverable to other JS modules as well.

Consider that our code exports a variable and prints a string

// message.js
export default (message) => console.log(message)

//mainfile.js
import printName from "./message.js"

printName("This message is not cryptic")

Voila! It’s done! Is it?

Cool, now deal with this!

But why?! The reason, might be simple. Next.js is a very new technology relative to other front-end frameworks of JavaScript. As a result it takes time for browsers, frameworks and other JavaScript front-ends to adapt to. And hence the developer howling!

This all results in a cascade of changes the developer might do such as downgrading packages, adding new ones, upgrading others, creating new modules before the gears and gauges move again. However, this might further add into the problems.

Also consider the fact that the above code usage requires a lot of interfacing with imports and packages, and this makes the whole machinery a bit shaky. If there is something minutely incorrect in our code or its build, either due to design or the mentioned upgrades and degrades, our code base becomes shaky.

And by the way, the above error is due to the fact that using the CommonJS method of importing is not going to make the cut for ES Modules.

Dynamic imports to save the day

Next.js brings you Dynamic Imports feature which makes working with JavaScript modules a cake walk for developers. Dynamic importing is pre-rendering of modules with the help of server-side rendering feature, which saves a lot of time and efforts of sending continuous requests to the server(for an application using a Next.js front-end that imports a JavaScript module. This feature pre-renders imports to the browser by default.

const varRehyping = dynamic(() => import('rehype-slug'), {
    ssr: false
})

const varRehypedCodeTitle = dynamic(() => import('rehype-code-titles'), {
    ssr: false,
})

const varRehypedAutolinkHeadings = dynamic(
    () => import('rehype-autolink-headings'), {
        ssr: false
    }
)

const varRehypedPrimsPlus = dynamic(() => import('rehype-prism-plus'), {
    ssr: false
})

The above snippet is a cool example of how various ES Modules can be imported within a Next.js file, where we import rehype plugins through server-side rendering.

A side note

Vercel, the original maker of Next.js have provided an awesome feature of building and refreshing at lightning pace with the help of Rust. Also, you can make use of other technologies such as using React Server Components for rendering diverse code entities.

Now you can use good old JavaScript along NextJS with ESM.

As a developer in the early 2020s

Knowing multiple(but not many) front-ends in this day and age can be a good plus point on your skills. The biggest fruit of this tendency is that you get good at picking up new technologies quickly. Next.js is closely related to Node.js as both are considered ‘hand-in-hand’ technologies to build powerful browser-based apps, since using ES Modules has become a common trend in JavaScript full-stack development. If you are looking for the ‘next-step’ after learning HTML, CSS and Vanilla JS, you can try Next.js+Node.js

References:

  1. esm.vercel.app
  2. enlear.academy
  3. freecodecamp