Image without description
  • Jacco Meijer
  • |
  • Mar 10, 2022

On Javascript transpilers, bundlers and modules

There's Javascript transpilers, modules, bundles and bundlers. This is a brief overview of all of these.

Transpilers

Transpilers convert code from and to a specific ES version. Do not use more than one unless you have a specific need to do so.

Microsoft Typescript

Targets a specific ES version. Setting the 'dom' lib adds definitions like window and document.

Babel

Targets a specific ES version. With '@babel/preset-env' the target can be a browser list like 'last 2 versions, not dead'

Module specifications

Before the release of NodeJs/CommonJS in 2009 it was hard to write modular Javascript. For HTML, the best option was using multiple <script> tags. Without HTML modular Javascript did not exist.

Anno 2021 many module specifications exist. The two most used are CommonJS and ES Modules (ESM). Worth looking at is also the universal specification called UMD.

CommonJS

CommonJS uses 'require' for importing and 'module.exports' for exporting.

This is the module specification used by NodeJS. Not supported by browsers. Biggest disadvantage is that 'tree shaking' is impossible.

EcmaScript Modules (ESM)

ESM uses 'import' for importing and 'export' for exporting.

This is the module specification added to the Javascript language since ES6. Besides being language native, it allows for 'tree shaking'.

Being native Javascript it is supported by modern browsers: chrome 61+, firefox 60+, safari 10.1+, edge 16+.

UMD

The UMD (Universal Module Definition) specification allows for importing from different module loaders like CommonJS and AMD.

UMD uses an IIFE (Immediately-Invoked Function Expression) which looks for a module specification. When found, the module is setup accordingly. Without a specification the module is globally set.

Bundles

Browsers bundles

Since 2017 modern browsers can load ESM by using <script type="module">. This makes bundling code easier but bundling is still required. This is because sending your code to the browser in one request is more efficient than by using multiple requests.

Module bundles

Module bundles are different from browser bundles in that they are not executed on load. Using a module system, a part of the module can be used. With e.g. CommonJS a function can be loaded with 'require' and then executed later.

When a module is intended for browser use, a module cannot 'import' from another module. This is because once the code runs in the browser, the browser has no way of knowing where the module to import lives.

Future solutions will solve this by importing from full repository urls.

Bundlers

The four most used bundlers are Browserify, Webpack, Parcel and Rollup. They originated solving different problems, but evolved to be very much alike.

Bundlers are configured to transpile using Babel or Typescript and are setup to creates either a 'module' or a 'browser' bundle.

Browserify (2013)

Make Node modules run in the browser. Browserify lets you require('modules') in the browser by bundling up all of your dependencies.

Webpack (2014)

Create a dependency graph for all of the assets in a website. Then create modules from the graph and bundle everything into one Javascript file.

Anno 2021 Webpack does not bundle ESM into one file.

Parcel (2017)

A faster alternative for Browserify and Webpack with zero configuration.

Rollup (2018)

Compile small pieces of code into a library. As opposed to Webpack, Rollup uses ESM to create bundles and thus can bundle ESM.

ES with Gatsby and NextJs

Using products like Gatsby and NextJs, what version of ES should you use? Both use Babel and Typescript to transpile and both use Webpack to create a bundle. This means you can write your code in EsNext and Typescript.

Configuring Gatsby and NextJs is hard because you need to know which transpiler does what. Adding Webpack to the mix does not make it easier.

Someday, Gatsby and Nextjs might default to Typescript and modules can be loaded by using full url's.

Using node modules from the NPM repository things become even harder to grasp. Gatsby and NextJs create bundles that target the browser. This means that node modules must work in the browser. The browser?

Modern browsers support ES6+ and ESM. Old browsers do not. This is why things like 'browserslist' exist.

Because of the current (2021) default bundler configuration of Gatsby and NextJs this is how you should create a node module that works with Gatsby and NextJs:

  • transpile to ES5 (use typescript, not babel)
  • bundle into one file (use rollup, not webpack)
  • React anno 2020 is distributed in UMD, therefore use CommonJS, not ESM

More on this in this article.


Other posts

Image without description
  • Jacco Meijer
  • |
  • Mar 21, 2024

UI Library with MDX documentation

Using the simple Render JSX plugin for Esbuild this post shows how to setup a simple UI library.

Image without description
  • Jacco Meijer
  • |
  • Mar 20, 2024

Render JSX plugin for Esbuild

Transform Esbuild generated JSX bundles to HTML pages.

Image without description
  • Jacco Meijer
  • |
  • Mar 19, 2024

Esbuild as a static site generator for MDX

Static site generators gain popularity. This blog is about using Esbuild as a static site generator for MDX.

Image without description
  • Jacco Meijer
  • |
  • Mar 18, 2024

11ty and Github pages

Simplifying the Contentful-Gatsby-Netlfy trio.

Image without description
  • Jacco Meijer
  • |
  • Mar 15, 2024

OWASP and CISSP

OWASP recommendations from the independent information security certification CISSP.

Image without description
  • Jacco Meijer
  • |
  • Jun 30, 2022

NPM7 and @npmcli/arborist

@npmcli/arborist is a powerful library that handles the new NPM 7 workspaces. This blog is about a simple make tool that uses the library.

Image without description
  • Jacco Meijer
  • |
  • May 12, 2022

Comparing React app, Nextjs and Gatsby

A new React project starts with a React toolchain. Main tools in the chains are SSR, React server components and GraphQL.

Image without description
  • Jacco Meijer
  • |
  • May 10, 2022

Versioning strategy for NPM modules

It is important to be able to bump the version of a NPM package without side effects.

Image without description
  • Jacco Meijer
  • |
  • Apr 12, 2022

React component themes and CSS variables

Creating React components with flexible themes by using CSS variables.

Image without description
  • Jacco Meijer
  • |
  • Mar 21, 2022

Content modeling with variants

The efficiency of a variant field in a content model.

Image without description
  • Jacco Meijer
  • |
  • Mar 12, 2022

Documentation

Documenting a software project is challenging. Here's a few simple guidelines that help a team writing clear documentation.

Image without description
  • Jacco Meijer
  • |
  • Mar 11, 2022

Javascript history

In 1986 David Ungar and Randall B. Smith developed Self at Xerox PARC. Inspired by Java, Scheme and Self Brendan Eich created Javascript in 1995.

Image without description
  • Jacco Meijer
  • |
  • Mar 10, 2022

On Javascript transpilers, bundlers and modules

There's Javascript transpilers, modules, bundles and bundlers. This is a brief overview of all of these.

Image without description
  • Jacco Meijer
  • |
  • Feb 11, 2022

Agile Scrum

The Agile Scrum framework is flexible enough to be used in many different ways. Here's one way of working.

Image without description
  • Jacco Meijer
  • |
  • Jan 20, 2022

What happened to Wheelroom?

Founded in 2018. Started to fly in 2020 and abandoned in 2021. What happened?

Image without description
  • Jacco Meijer
  • |
  • Jan 19, 2022

Contentful, Netlify and Gatsby four years later

What did we learn from using Contentful for four years?

Image without description
  • Jacco Meijer
  • |
  • Jan 18, 2022

Typescript interface for React UI components

How to define an interface for React UI components that prevents breaking changes.

Image without description
  • Jacco Meijer
  • |
  • Jan 17, 2022

Naming React components

What's in a name? A clear naming strategy helps developers communicate. Most devs rather spend time writing component code than wasting time on a good component name.