Getting Back to Where We All Started

Using ES Modules + JavaScript Today

Years ago, when I was developing Java J2EE applications, I was jealous of the front-end developers that could just save a HTML file and refresh the browser to see their changes. With J2EE, we wrote JSP files that had to be compiled, then a server had to be started to serve our content up. The simpler development cycle was one reason I started to enjoy doing front-end development.

But over time, JavaScript started to become more powerful and complicated. We added Babel to compile our JavaScript, WebPack or Browserify to bundle our applications, etc… This has made the setup, development, and build process a little more complicated. Today, one of the main issues we solve with WebPack is taking all of our JavaScript files and bundling them into one JavaScript file.

So front-end development used to be easy, then it got harder — let’s work towards making it easier again.

ES Modules to the Rescue

At Capital One, we have started to move our front-end development to use web components to structure our applications. One way to do this is using Webpack to bundle multiple JavaScript files into one JavaScript file. But Webpack can do more than just this. Webpack’s tree shaking uses ES modules import/export for the static structure to shrink the file size of our JavaScript. ES modules are highly decoupled, distinct pieces of functionality stored in modules. As you probably know, loose coupling facilitates easier maintainability of apps by removing dependencies where possible. Custom elements fit nicely into this structure, since custom elements must use the class syntax. ES modules have their own scope, this helps us from polluting the global namespace and namespaces our module code. We can now import only the code we need from JavaScript libraries. ES modules standardize the way module loading should be done in browsers, among many other benefits. Let’s look at how we are doing this today.

Today’s Structure

Here is an example application with the structure we are using for web components. I’m showing a list of people and if you click on the person it will show you the details of this person.

We have a src dir with our JavaScript file.

Our build files has just one line, build.js. require(‘../dist/people-list’); The WebPack will use this file as the entry file and build data.js as its output. The info, list, and data files are our web components.



This is our sample application that we call with the index.html after WebPack has finished bundling the JavaScript to people-data.js.


We can now serve this page up and see a list of characters. Structuring our code this way will allow us to move to ES modules quickly. ES modules are starting to land in browsers. They’re currently in:

  • Safari 10.1
  • Chrome Canary 60 — Behind the Experimental Web Platform flag in chrome:flags Firefox 54 — Behind the dom.moduleScripts.enabled setting in about:config
  • Edge 15 — Behind the Experimental JavaScript Features setting in about:flags

To change our code to use ES modules all we have to do us update our index.html. To use modules all we need to do is add type+module this script as a ECMAScript module.This will tell the browser to treat this script as a ECMAScript module.

So our index.html turns into this:

Now we don’t have to bundle our JavaScript together and the browser will load the JavaScript files as they are

needed. We can also use the attribute nomodule on the script tag to add a fallback if the browser does not

support ES modules.

Our final index.html looks like this:

We now can take advantage of modular code without using WebPack. There are some other advantages as well such as by leveraging imports to only use the parts of the code we want to use. We can also go back to using individual files which makes development and debugging a lot easier to work with. With individual files we can also take advantage of HTTP2 and load the code in one pipe with faster download.


ES modules allow us to write our code in modules, create local scope, and avoid polluting the global scope with our functions. We can shrink the size of our code using tree shaking from bundle applications like WebPack. We can also enjoy easier unit testing of our module code.

In the near future, we will be able to use ES modules native in the browser. This will allow us additional benefits such as http2 support, modules executing only once, async loading, and many more!

DISCLOSURE STATEMENT: These opinions are those of the author. Unless noted otherwise in this post, Capital One is not affiliated with, nor is it endorsed by, any of the companies mentioned. All trademarks and other intellectual property used or displayed are the ownership of their respective owners. This article is © 2017 Capital One.

Related Links

Show your support

Clapping shows how much you appreciated Jason Dalton’s story.