typescriptimportes6-modulescommonjsdynamic-import

Dynamically load ESM module in CJS package in TypeScript


I am trying to load a single ESM module in my TypeScript CJS project. All examples I find are for JavaScript.

// example.ts
export const example = async () => {
  const module = await import("esm-module");
  return module.func
}

My issue is that TSC transpiles the import function to a require which breaks everything.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.example = void 0;
const example = async () => {
    const module = await Promise.resolve().then(() => require("esm-module")); // Not desired
    return module.func;
};
exports.example = example

Solution

  • I stumbled across this comment - Not sure if there is currently a better way. At least the eval is used with a constant string so I don't see any linting issues.

    // example.ts
    type EsmModule = typeof import("esm-module");
    
    export const example = async () => {
      const module = await (eval('import("esm-module")') as Promise<EsmModule>);
      return module.func
    }
    

    Most other solutions complicate the basic premise and either try to mess with the tsconfig.json or package.json, or don't correctly account for TypeScript transpilation.