Skip to content

Instantly share code, notes, and snippets.

@gusalbukrk
Last active January 31, 2022 22:18
Show Gist options
  • Save gusalbukrk/ec8b0c0557e78c40a75d8ec1bc50ad57 to your computer and use it in GitHub Desktop.
Save gusalbukrk/ec8b0c0557e78c40a75d8ec1bc50ad57 to your computer and use it in GitHub Desktop.
#module #commonjs #require #export #import

CommonJS

Require

name vs path

  • npm modules inside node_modules use just the name, for local modules use path

entire module

  • const myModule = require('./my-module.js')

destructuring

  • const { f1, f2 } = require('./my-module.js')

Export

exports vs module.exports

  • export and module.exports initially points to the same empty object
  • however, if you want to return anything other than an object, you must reassign module.exports
exports.a = 5;
exports.log = inp => console.log(inp);

// equivalent to
module.exports = {
  a: 5,
  log: inp => console.log(inp),
}

UMD (Universal Module Definition)

How to import an UMD file

<script src="add.umd.js"></script>

<script>

  // use imported function(s) as if they were declared globally
  console.log(add(7, 3));

</script>

UMD under the hood

// IIFE
(function(root, factory) {

  // format will be commonjs, AMD (RequireJS) or a global
  if (typeof exports === 'object' && typeof module !== 'undefined') {
    module.exports = factory();
  } else if (typeof define === 'function' && define.amd) {
    define(factory);
  } else {
    root.myLibrary = factory();
  }

// invoking IIFE
}(this, function() {

    // Your module code will reside here
}));

ES6 modules

Import

everything

  • import * as myModule from './modules/my-module.js';

destructuring

  • import {myExport} from './modules/my-module.js';

default

  • import myDef from "/src/a";
  • import myDef, { fn1, fn2 } from "/src/a"; = import default and others

Export

individual

  • export const log = inp => console.log(inp);

list

  • export { log, add as sum };

default

  • export default expression;
  • export { name1 as default, … };

Interoperability between both standards

  • in Node:
    • ES modules support became stable in version 15
    • "type": "module" in package.json to treat every module as a ESM module
    • for esm apps:
      • interoperability (for both default and named CJS exports) is very good, read more
    • for cjs apps:
      • not recommended import esm modules, here
  • in Babel:
    • is done out-of-the-box
  • in Typescript:
    • enabled with allowSyntheticDefaultImports (recommended) or esModuleInterop option

export default to commonjs

  • esm's export default is treated as a regular named export in commonjs
  • export default 3; becomes in commonjs exports.default = 3;

ES Modules directly in the browser

  • es module is a js file that contains import and/or export
  • to be able to use modules in the browser, you need to add type="module" to script tag.

Method 1: src

<script type="module" src="index.js"></script>

Method 2: Inline script

<script type="module">

  import xlorem from './xlorem.esm.js';

  (async function() {
    const filler = await xlorem('harry potter', {
      format: 'html',
    });

    console.log(filler);
    document.body.innerHTML = `<h1>${filler.title}</h1>`;
    document.body.innerHTML += filler.body;
  })()

</script>

Hybrid package (supports both ESM & CommonJS)

read more here and here

  • configure you bundler to output 2 bundles, one esm and the other cjs (e.g. bundle.cjs.js & bundle.ems.js)
  • package.json config:
{
  "type": "module",

  // NOTE: because `type` = `module`, every file is treated as esm
  // to force a file be handled as commonjs, filename must've `.cjs` extension

  "main": "./dist/bundle.cjs", // "main" field defines the script that is used when the package directory is loaded via require()

  // use conditional exports within "exports" to define different package entry points per environment
  // including whether the package is referenced via require or via import
  "exports": {
    "import": "./dist/bundle.js",
    "require": "./dist/bundle.cjs"
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment