πŸŽ‰ Appsmith Now Supports ESM Javascript Libraries πŸ”₯ But what are CJS, AMD, UMD, and ESM in Javascript?

Β·

4 min read

πŸŽ‰ Appsmith Now Supports ESM Javascript Libraries πŸ”₯ But what are CJS, AMD, UMD, and ESM in Javascript?

In the beginning, JavaScript was a wild and untamed language, devoid of any built-in modularity. Thankfully, the brilliant minds of the developer community recognized this limitation and embarked on a quest to bring modularity to JavaScript.

This journey gave rise to several module formats, each with its unique syntax, purpose, and behavior. Among these formats, we find CommonJS (CJS), Asynchronous Module Definition (AMD), Universal Module Definition (UMD), and ECMAScript Modules (ESM). These module systems have played pivotal roles in shaping the JavaScript ecosystem, and understanding them is essential for any modern developer.

During today's Release Jam, we announced πŸ”₯Support for ESM Libraries in Appsmith πŸŽ‰ , previously, we only supported UMD which sometimes meant a bit of a compatibility puzzle for our users.

In this article, we will delve into these JavaScript module formats, shedding light on their syntax, intended use cases, and fundamental characteristics. We aim to empower you, the reader, with the knowledge needed to recognize and leverage these modules effectively when encountered in the wild and understand the impact of this announcement and the many doors this opens for you as an engineer, and as a problem solver.

Whether you're a seasoned developer or just starting your coding adventure, this exploration will equip you with the insights and skills necessary to harness the power of JavaScript modules and, more specifically, the brand-new ESM support in Appsmith.

CJS

Historically, JavaScript was browser-only. Developers used several techniques to structure their code, all of which were abstractions over global variables. Among those solutions, a crowd-favorite called CommonJS (or 'cjs') emerged. CJS is short for CommonJS (It's on the title, I guess hehe). Here is what it looks like:

//importing 
const letsDoAThing = require('./letsDoAThing.js'); 
//exporting
module.exports = function letsDoAThing(n) {
  // do something
}

Some of you may immediately recognize CJS syntax from node. That's because node uses CJS module format.

  1. CJS imports modules synchronously.

  2. You can import from a library node_modules or local dir. Either by const myLocalModule = require('./some/local/file.js') or var React = require('react'); works.

  3. When CJS imports, it will give you a copy of the imported object.

  4. CJS will not work in the browser. It will have to be transpiled and bundled.

AMD

AMD stands for Asynchronous Module Definition. Here is a sample code:

define(['dep1', 'dep2'], function (dep1, dep2) {
    //Define the module value by returning a value.
    return function () {};
});

or also

// "simplified CommonJS wrapping" https://requirejs.org/docs/whyamd.html
define(function (require) {
    var dep1 = require('dep1'),
        dep2 = require('dep2');
    return function () {};
});
  1. AMD imports modules asynchronously (hence the name).

  2. AMD is made for frontend (when it was proposed) (while CJS backend).

  3. AMD syntax is less intuitive than CJS. I think of AMD as the exact opposite sibling of CJS.

UMD

UMD stands for Universal Module Definition and as the name stands, it runs everywhere! and this is the type of module that we used to only support at Appsmith. Here is what it may look like

(function (root, factory) {
    if (typeof define === "function" && define.amd) {
        define(["jquery", "underscore"], factory);
    } else if (typeof exports === "object") {
        module.exports = factory(require("jquery"), require("underscore"));
    } else {
        root.Requester = factory(root.$, root._);
    }
}(this, function ($, _) {
    // this is where I defined my module implementation

    var Requester = { // ... };

    return Requester;
}));
  1. Works on front and back end (hence the name universal).

  2. Unlike CJS or AMD, UMD is more like a pattern to configure several module systems. Check here for more patterns.

  3. UMD is usually used as a fallback module when using bundler like Rollup/ Webpack

ESM

ESM stands for ECMAScript Modules. It is Javascript's proposal to implement a standard module system and it's the new addition to the type of modules Appsmith supports. I am sure many of you have seen this:

import React from 'react';

Other sightings in the wild:

import {foo, bar} from './myLib';

...

export default function() {
  // your Function
};
export const function1() {...};
export const function2() {...};
  1. Works in most of the modern browsers

  2. It has the best of both worlds: CJS-like simple syntax and AMD's async

  3. Tree-shakeable, due to ES6's static module structure

  4. ESM allows bundlers like Rollup to remove unnecessary code, allowing sites to ship less codes to get faster load.

Can be called in HTML, just do:

<script type="module">
  import {func1} from 'my-lib';
  func1();
</script>

Go and start building with ESM

Now that you know what each of these modules is and the impact of this announcement, I can't wait to see what you will build integrating all kinds of modern libraries into your Appsmith apps and using it for custom logic, functionality and much more!

Let us know in the comments what's your favorite Javascript Library and how you intend to use it