From 1e0bda5a71a060ddf86e10abb566d1cc75af958d Mon Sep 17 00:00:00 2001 From: Roy Ivy III Date: Mon, 28 Dec 2020 01:07:40 -0600 Subject: [PATCH] change/API! ~ add ESM module packaging (adds 'exports' to package) - adds an ESM wrapper to provide simple ESM support (as suggested in "Node Modules at War" * ref: [Node Modules at War](https://redfin.engineering/node-modules-at-war-why-commonjs-and-es-modules-cant-get-along-9617135eeca1) @@ * ref: [yargs ~ 'Road to ESM/Deno'](https://github.com/yargs/yargs/issues/1706) --- package.json | 12 ++++++++++++ src/esm-wrapper/index.js | 9 +++++++++ src/esm-wrapper/package.json | 1 + src/index.ts | 10 +++++++++- 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/esm-wrapper/index.js create mode 100644 src/esm-wrapper/package.json diff --git a/package.json b/package.json index 3725bd9..3d4fccc 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,17 @@ "main": "dist/cjs/index.js", "module": "dist/cjs/esm-wrapper/index.js", "types": "dist/types/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": [ + { + "import": "./dist/cjs/esm-wrapper/index.js", + "require": "./dist/cjs/index.js", + "types": "./dist/types/index.d.ts" + }, + "./dist/cjs/index.js" + ] + }, "keywords": [ "common", "cross-platform", @@ -44,6 +55,7 @@ "# build # build/compile package": "", "build": "run-s _:regen:build", "build:cjs": "tsc -p tsconfig/tsconfig.cjs.json", + "build:cjs/esm": "shx mkdir -p build/cjs && shx cp -r src/esm-wrapper build/cjs", "## build:esm * [2020-12-22; rivy] TS compiles to ESMs are broken due to extension mishandling (use `rollup`)": "tsc -p tsconfig/tsconfig.esm.json", "build:umd": "tsc -p tsconfig/tsconfig.umd.json", "build:tests": "tsc -p tsconfig/tsconfig.tests.json", diff --git a/src/esm-wrapper/index.js b/src/esm-wrapper/index.js new file mode 100644 index 0000000..4746195 --- /dev/null +++ b/src/esm-wrapper/index.js @@ -0,0 +1,9 @@ +/* eslint-env node */ +// # spell-checker:ignore Deno + +import _ from '../index.js'; +// note: not usable by `deno`; +// ...`deno` is unable to load (the CJS module) '../index.js' via import => `'../index.js' does not provide an export named 'default'` + +const default_ = _; +export default default_; diff --git a/src/esm-wrapper/package.json b/src/esm-wrapper/package.json new file mode 100644 index 0000000..6990891 --- /dev/null +++ b/src/esm-wrapper/package.json @@ -0,0 +1 @@ +{"type": "module"} diff --git a/src/index.ts b/src/index.ts index 307ada3..2de49bf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,15 @@ const haveModuleExports_ = typeof module === 'object' && module.exports; // ## maint ~ [2020-12-23; rivy] although tested, `nyc` is unable to instrument ESM/.mjs correctly in order show coverage for testing the *else* clause /* istanbul ignore else */ if (haveModuleExports_) { - // enables direct require from CJS (eg, `const m = require('...');`); skipped for ESM + // enables direct require from CJS (eg, `const module = require('...');`), but generally disables any other exports + // * skipped for ESM (missing `module.exports`) + // * added non-enumerable '_esm!' property (as a hack) to allow full access to all exports (for testing, ...) // eslint-disable-next-line functional/immutable-data module.exports = default_; + Object.defineProperty(module.exports, '_esm!', { + get() { + return exports; + }, + enumerable: false, + }); }