tooling.report

feature

ECMAScript modules

Can ECMAScript modules bundles be generated?

Person in shorts with blue hair walking left

Introduction

ECMAScript modules are supported in all modern browsers, representing more than 90% of web traffic. ECMAScript modules are a fast, lightweight way to load scripts without the need for a custom loader. Modules are also always executed asynchronously and in strict mode, improving performance and helping surface otherwise hidden errors.

In addition to widespread browser support, ECMASCript Modules are supported in Node.js 12+. This makes them a great choice for portable JavaScript that needs to be able to run in any environment.

The Test

This test bundles two entry modules, index.js and profile.js. Each depends on a method imported from a shared utils.js module, and index.js dynamically imports a fourth module which should create a split point.

index.js

import { logCaps } from './utils.js';

async function main() {
  const { exclaim } = await import('./exclaim.js');
  logCaps(exclaim('This is index'));
}
main();

profile.js

import { logCaps } from './utils.js';
logCaps('This is profile!');

exclaim.js

export function exclaim(msg) {
  return msg + '!';
}

utils.js

export function logCaps(msg) {
  console.log(msg.toUpperCase());
}

The output of this test should be four bundles in ECMAScript Modules format. Two entry bundles corresponding to the two entry modules, a code-splitted utils.js module, and a fourth bundle containing exclaim.js that is loaded via dynamic import().

Conclusion

browserify

Browserify does not support es-modules output (out of scope for the project).

Issues

  • N/A
parcel

Parcel outputs ES modules by default when you use a <script type="module"> in your HTML file. It uses native dynamic import() to load async bundles. It also can create a nomodule fallback if a browserslist is configured to include older browsers.

Issues

rollup

ESM is Rollup's most natural output format.

webpack

Webpack 5 has an experimental JavaScript Modules output format, however this format does not leverage the module system for exports or code loading. At present, the new output format removes the enclosing function around bundled code, loads bundles using <script type=module>, and adjusts the default minifier configuration to compress module-scoped variables.

In the future, Webpack could add an output mode that leverages JavaScript Modules for code loading and export sharing, similar to the current CommonJS-based runtime used when compiling for a Node target.