Skip to content

Instantly share code, notes, and snippets.

@paulmillr
Last active February 10, 2024 17:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulmillr/cf5f8441c93dfef87c814af18a06d166 to your computer and use it in GitHub Desktop.
Save paulmillr/cf5f8441c93dfef87c814af18a06d166 to your computer and use it in GitHub Desktop.
Why writing hybrid Common.js + ESM NPM packages is hard
  • BigInt literals (15n) are not supported in some environments
    • Must use BigInt('15') instead
    • It was not supported in React Native 0.70. Need to test in new versions
  • Must use hybrid ESM-Common.js package
    • ESM (ECMAScript modules) are not supported in Electron, Jest
      • Electron needs pre-compilation step aka bundler
      • Jest has experimental esm flag, also can be replaced with micro-should
    • Common.js modules (legacy node.js modules) are not supported in browsers, Deno
      • Browsers can be worked around with UMD wrapper
      • Doesn’t play well with ESM in-browser imports
  • Must use full extensions inside of library imports
    • file a.ts imports b.ts
      • .ts imports are not allowed in js/node/browser
    • file a.ts imports b.js
      • js/node/browser works, deno doesn’t
  • (Fixed in React Native 0.72) Can’t place compiled files in “lib” (or any other) directory, need to place in root
    • Example: can’t do lib/hash.js, need to place in hash.js
    • Otherwise React Native will fail: facebook/metro#670
    • package.json modules can’t solve it
  • Cryptography imports need import maps
    • Can’t use globalThis.crypto in node.js older than v19
    • Can’t use node.js require(‘crypto’) in browsers or bundlers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment