Skip to content

Commit

Permalink
maint/build ~ CJS+ESM packaging + deno support
Browse files Browse the repository at this point in the history
- ref: [Node Modules at War](https://redfin.engineering/node-modules-at-war-why-commonjs-and-es-modules-cant-get-along-9617135eeca1) @@ <https://archive.is/zl0qg>
- ref: [yargs ~ 'Road to ESM/Deno'](yargs/yargs#1706)

## discussion

As suggested in "Node Modules at War", an ESM wrapper is used to provide basic ESM
support. However, `deno` is unable to use that ESM module, failing to load the
transitive CJS module with `'../index.js' does not provide an export named 'default'`.
So, `deno` is instead referred to a full ESM transpile.

As `deno` is it's own animal, there is no issue with CJS and ESM referring to differing
modules, either for installation or creating subtle code issues.
  • Loading branch information
rivy committed Dec 25, 2020
1 parent b1eac89 commit ac9e5a5
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 11 deletions.
31 changes: 21 additions & 10 deletions package.json
Expand Up @@ -14,14 +14,24 @@
"files": [
"build/cjs",
"build/esm",
"build/umd",
"build/types",
"CHANGELOG.mkd",
"LICENSE",
"README.md"
],
"main": "build/cjs/index.js",
"types": "build/types/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": [
{
"deno": "./src/mod.deno.ts",
"import": "./build/cjs/esm-wrapper/index.js",
"require": "./build/cjs/index.js"
},
"./build/cjs/index.js"
]
},
"keywords": [
"common",
"cross-platform",
Expand All @@ -43,6 +53,7 @@
"# build # build/compile package": "",
"build": "run-s _: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:esm": "rollup -c",
"build:umd": "tsc -p tsconfig/tsconfig.umd.json",
Expand All @@ -51,7 +62,7 @@
"# clean # remove build artifacts": "",
"clean": "rimraf build dist",
"# coverage # calcuate and display (or send) code coverage [alias: 'cov']": "",
"coverage": "run-s --silent _:max-node-8 && echo-cli \"[coverage] WARN Code coverage skipped [for NodeJS < v10]\" 1>&2 || run-s _:coverage",
"coverage": "run-s --silent _:max-node-8 && shx echo \"[coverage] WARN Code coverage skipped [for NodeJS < v10]\" 1>&2 || run-s _:coverage",
"cov": "run-s coverage",
"cov:html": "nyc report --reporter=html",
"cov:send": "nyc report --reporter=text-lcov | codecov --disable=gcov --pipe",
Expand All @@ -66,7 +77,7 @@
"# help # display help": "",
"help": "< package.json node -e \"s = {p:'',e:'npm'}; if (new String(process.env.npm_execpath).match(/yarn.js$/)) { s = {p:'\\n',e:'yarn'}; }; console.log('%susage: \\`%s run TARGET [TARGET..]\\`\\n\\nTARGETs:\\n', s.p, s.e); re = /^.*?\\x22(?:\\W+\\s*)([^#\\x22]+)\\s+#+\\s+([^#\\x22]+?)(\\s+#+)?\\x22.*$/; require('readline').createInterface({ input: process.stdin, output: process.stdout, terminal: false }).on('line', function(line){ if (match = re.exec(line)) { console.log('%s %s', match[1].padEnd(19), match[2]); } });\"",
"# lint # check for package code 'lint'": "",
"lint": "run-s --silent _:max-node-8 && echo-cli \"[lint] WARN Lint checks skipped [for NodeJS < v10]\" 1>&2 || run-p lint:*",
"lint": "run-s --silent _:max-node-8 && shx echo \"[lint] WARN Lint checks skipped [for NodeJS < v10]\" 1>&2 || run-p lint:*",
"# lint:lint # check for code 'lint' (using `eslint`)": "",
"lint:lint": "eslint .",
"# lint:spell # check for spelling errors (using `cspell`)": "",
Expand All @@ -86,19 +97,19 @@
"# test:types # check for type declaration errors (using `tsd`)": "",
"test:types": "tsd",
"# update:changelog # update CHANGELOG (using `git changelog ...`)": "",
"update:changelog": "run-s --silent _:update:changelog && echo-cli \"[update] info CHANGELOG updated\"",
"update:changelog": "run-s --silent _:update:changelog && shx echo \"[update] info CHANGELOG updated\"",
"_:build": "exec-if-updated --source package.json --source tsconfig.json --source \"tsconfig/**\" --source rollup.config.js --source \"src/**\" --target \"build/**\" run-p \"build:*\"",
"_:build+test:code": "exec-if-updated --source package.json --source tsconfig.json --source \"tsconfig/**\" --source rollup.config.js --source \"src/**\" --target \"build/**\" run-p \"build:*\" && run-s test:code",
"_:coverage": "run-s _:build+test:code && is-ci && run-s cov:send || run-s cov:view",
"_:exists:git-changelog": "node -e \"if (!require('command-exists').sync('git-changelog')){process.exit(1);};\" || (echo-cli \"WARN `git-changelog` missing (try `go get -u github.com/rivy-go/git-changelog/cmd/git-changelog`)\" & exit 1)",
"_:exists:git-changelog": "node -e \"if (!require('command-exists').sync('git-changelog')){process.exit(1);};\" || (shx echo \"WARN `git-changelog` missing (try `go get -u github.com/rivy-go/git-changelog/cmd/git-changelog`)\" & exit 1)",
"_:max-node-8": "is-node-not-modern 10",
"_:min-node-10": "is-node-modern 10",
"_:vcs-clean": "git diff --quiet",
"_:vcs-clean-err": "run-s --silent _:vcs-clean || (echo-cli \"[vcs] ERR! Uncommitted changes\" 1>&2 & exit 1)",
"_:vcs-clean-err": "run-s --silent _:vcs-clean || (shx echo \"[vcs] ERR! Uncommitted changes\" 1>&2 & exit 1)",
"_:vcs-strictly-clean": "git status --porcelain | node -e \"process.stdin.on('data',function(_){process.exit(1);});\"",
"_:vcs-strictly-clean-err": "run-s --silent _:vcs-strictly-clean || (echo-cli \"[vcs] ERR! Uncommitted changes and/or untracked files\" 1>&2 & exit 1)",
"_:update:changelog": "run-s --silent _:exists:git-changelog && git changelog > CHANGELOG.mkd || echo-cli \"[update] info CHANGELOG not updated\" 1>&2",
"_:version:update:changelog": "run-s --silent _:exists:git-changelog && node -e \"v=require('./package.json').version; result=require('child_process').spawnSync('git changelog --next-tag v'+v,{shell:true,encoding:'utf-8'}); if (result.status != 0) {console.error('ERR! '+result.stderr); process.exit(1);} else {require('fs').writeFileSync('CHANGELOG.mkd',result.stdout);};\" || echo-cli \"[version] WARN CHANGELOG not updated\" 1>&2",
"_:vcs-strictly-clean-err": "run-s --silent _:vcs-strictly-clean || (shx echo \"[vcs] ERR! Uncommitted changes and/or untracked files\" 1>&2 & exit 1)",
"_:update:changelog": "run-s --silent _:exists:git-changelog && git changelog > CHANGELOG.mkd || shx echo \"[update] info CHANGELOG not updated\" 1>&2",
"_:version:update:changelog": "run-s --silent _:exists:git-changelog && node -e \"v=require('./package.json').version; result=require('child_process').spawnSync('git changelog --next-tag v'+v,{shell:true,encoding:'utf-8'}); if (result.status != 0) {console.error('ERR! '+result.stderr); process.exit(1);} else {require('fs').writeFileSync('CHANGELOG.mkd',result.stdout);};\" || shx echo \"[version] WARN CHANGELOG not updated\" 1>&2",
"prepublishOnly": "run-s update:* test _:vcs-strictly-clean-err",
"preversion": "run-s test",
"version": "run-s _:version:update:changelog lint:spell && git add CHANGELOG.mkd"
Expand All @@ -118,7 +129,6 @@
"coveralls": "^3.0.5",
"cross-spawn": "^6.0.5",
"cspell": "^4.1.2",
"echo-cli": "^1.0.8",
"eslint": "^7.11.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-comments": "^3.2.0",
Expand All @@ -134,6 +144,7 @@
"rimraf": "^3.0.2",
"rollup": "^2.35.1",
"rollup-plugin-typescript2": "^0.29.0",
"shx": "^0.3.3",
"ts-node": "^9.0.0",
"tsd": "^0.13.1",
"typescript": "^4.1.3"
Expand Down
10 changes: 10 additions & 0 deletions src/esm-wrapper/index.js
@@ -0,0 +1,10 @@
// # spell-checker:ignore Deno
import _ from '../index.js';
// note: not usable by `deno`;
// ...`deno` is unable to (the CJS module) '../index.js' via import => `'../index.js' does not provide an export named 'default'`

// export const OSPathsWithAdaption = _['_esm!'].OSPathsWithAdaption;
// const default_ = _['_esm!'].default;
// export default default_;
const default_ = _;
export default default_;
1 change: 1 addition & 0 deletions src/esm-wrapper/package.json
@@ -0,0 +1 @@
{"type": "module"}
2 changes: 1 addition & 1 deletion src/index.ts
Expand Up @@ -2,7 +2,7 @@
import { default as OSPathsWithAdaption } from './lib/OSPaths';
import adapter from './platform-shims/node';

export * from './lib/OSPaths';
// export * from './lib/OSPaths';

const default_ = OSPathsWithAdaption(adapter);
export default default_;
Expand Down

0 comments on commit ac9e5a5

Please sign in to comment.