Felipe
Felipe

Reputation: 3149

Isomorphic import of CommonJS modules

I've written a small library that's meant to run both in the browser and on the server. The library in turn uses npm libraries published as CommonJS modules (e.g. lodash.isequal).

I'd like to compile the library two different ways:

  1. Using tsc, generating commonjs modules for use on the server
  2. Through webpack, using the awesome-typescript-loader, generating es6 modules for webpack to bundle

Per the docs, the correct way of importing CommonJS libraries which override module.exports is as follows:

import isEqual = require('lodash.isequal');

However for the second compilation case, typescript complains that

error TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.

I've managed to get code generation to work properly by importing it as:

import * as isEqual from 'lodash.isequal';

but that requires disabling typechecks, since otherwise typescript complains with errors like the following:

error TS2497: Module '"/home/user/ts-mod-test/node_modules/@types/lodash.isequal/index"' resolves to a non-module entity and cannot be imported using this construct.

Upvotes: 2

Views: 835

Answers (1)

Felipe
Felipe

Reputation: 3149

Since TypeScript 2.7, this issue can be resolved by using synthetic default imports. Using the esModuleInterop flag, isEqual (and similar modules) can be imported like in babel and webpack:

import isEqual from 'lodash.isequal';

For webpack with the module option set to es6, the import will be left as-is, and webpack itself will handle the synthetic default. For node, with module set to CommonJS, the corresponding emit will be const lodash_isequal_1 = __importDefault(require("lodash.isequal"));, where the __importDefault handles the non-es module case like Babel

Upvotes: 0

Related Questions