js-ethereum-cryptography icon indicating copy to clipboard operation
js-ethereum-cryptography copied to clipboard

Include ESM version of code in the package

Open frangio opened this issue 3 years ago • 6 comments

Using ethereum-cryptography with a SvelteKit app, I ran into some issues due to current bugs in the treatment of CommonJS modules by either SvelteKit or Vite. While this is a bug in those tools, it would be avoided if the package included ESM modules. What do you think about including that? It looks like it would also play well with ESM modules in Node.js.

frangio avatar Nov 20 '21 03:11 frangio

What about sub-dependencies? Do they also need to be esm?

What is the benefit of esm?

Can esm be dynamically imported? We have a few imports in noble-hashes

paulmillr avatar Nov 20 '21 03:11 paulmillr

For reference: we also have a similar issue open here https://github.com/ethereumjs/ethereumjs-monorepo/issues/1468

holgerd77 avatar Nov 22 '21 10:11 holgerd77

See https://github.com/paulmillr/noble-ed25519/pull/17

There are no dynamic imports so this won't work for us

paulmillr avatar Nov 22 '21 14:11 paulmillr

This should be delayed until node.js drops support for v14, which is 2023+.

paulmillr avatar Nov 23 '21 04:11 paulmillr

Update: noble-hashes and noble-secp256k1 support ESM now. micro-base (third dep) doesn't. And we'll need to test js-e-c itself thoroughly for ESM builds.

paulmillr avatar Dec 24 '21 18:12 paulmillr

All deps besides @scure/bip39 now support ESM. bip39 compiles to a code which can be reused between ESM and commonjs, so it should also be fine. esModuleInterop got also removed.

Now, we need to figure out what's the flow to compile everything into .esm and how to test it.

paulmillr avatar Jun 15 '22 10:06 paulmillr

Actually I noticed that this package has no default entry point, which is technically not an issue. But by using it with the ESM syntax and following the readme.md examples, one might find this error message not super helpful:

node src/index.mjs
/Users/timdaub/Projects/replica/node_modules/ethereum-cryptography/index.js:2
throw new Error("This package has no entry-point. Please consult the README.md to learn how to
use it.");

The reason is that before ESM, people were used to e.g. importing actual .js files by specifying them without the file type in the import declaration. It's as it's being done in the readme, e.g.

const { sha256 } = require("ethereum-cryptography/sha256");

But with ESM, it's now mandatory to always include a file type extension in the import path too, so when we e.g. want to import ethereum-cryptography/sha256 using ESM, and we naively assume that we can do it without defining the filetype path, our script will error:

node src/index.mjs
internal/process/esm_loader.js:74
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/timdaub/Projects/replica/node_modules/
ethereum-cryptography/keccak' imported from /Users/timdaub/Projects/replica/src/index.mjs
Did you mean to import ethereum-cryptography/keccak.js?

The solution is to export in ESM always WITH the file type extension. So here's the equivalent that works in node 14

import { keccak256 } from "ethereum-cryptography/keccak.js";

If u want I can send a PR for the readme to that.

TimDaub avatar Jan 14 '23 15:01 TimDaub

Thanks for the explanation, @TimDaub! I agree with you, the readme should include the extensions. Happy to receive a PR :)

alcuadrado avatar Jan 16 '23 23:01 alcuadrado

Done! 2.1.2

paulmillr avatar Jul 12 '23 18:07 paulmillr