bitcoinjs / tiny-secp256k1

A tiny secp256k1 native/JS wrapper
MIT License
92 stars 55 forks source link

Cannot use import statement outside a module when importing this package using Jest #73

Closed Robin-Hoodie closed 2 years ago

Robin-Hoodie commented 2 years ago

This results in the following error

({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { compare } from "uint8array-tools";

SyntaxError: Cannot use import statement outside a module

import { pointMultiply, pointAdd } from "tiny-secp256k1";
^

It seems the compare import from "uint8array-tools" is the culprit here

Downgrading to version 1.1.6 resolves the issue

Happy to create a repro or help out if necessary

junderw commented 2 years ago

This is a jest configuration issue.

Both this package and uint8array-tools are set to use require for node environments and import for browser environments.

Most likely setting your jest environment to node should fix the issue.

junderw commented 2 years ago

Jest ESM support is a separate issue. Right now it's bundling the MJS code as a CJS.

junderw commented 2 years ago

Or maybe it's a babel issue. Assuming you followed that website directions exactly.

junderw commented 2 years ago

I work on a private project that uses ts-jest instead of babel and everything works fine, btw.

Robin-Hoodie commented 2 years ago

I've tried running files through the ts-jest transformer now, with the same result.

Let me see if I can create a repro for this

Robin-Hoodie commented 2 years ago

@junderw Here's a repro https://github.com/Robin-hoodie/tiny-secp256k1-repro

bufo24 commented 2 years ago

I am having the same issue

junderw commented 2 years ago

This issue is not with this library. We have used the official NodeJS methods for providing cjs backwards compatibility.

Please follow the issue on the jest repository.

junderw commented 2 years ago

https://github.com/facebook/jest/issues/9771#issuecomment-776681032

Try using a custom resolver.

looks like babel also has the same issue.

Robin-Hoodie commented 2 years ago

Thanks for the input @junderw , I've been able to "resolve" (pun intended) this now

For anyone experiencing the same problem, here's the TLDR:

Jest currently does not support the package.json#exports field (see https://github.com/facebook/jest/issues/9771). Currently Jest plans to add support for it in v28. In case v28 has been released when you're reading this, I'd try just upgrading Jest and see if that resolves the issue.

If v28 has not been released yet or v28 also does not resolve this issue, you can use the suggestion mentioned here I've implemented this as follows:

// jest.config.js
module.exports = {
  resolver: "<rootDir>/jest-resolver.js"
  // any other options go here
}

// ./jest-resolver.js
const enhancedResolve = require("enhanced-resolve");

const resolver = enhancedResolve.create.sync({
  conditionNames: ["require", "node", "default", "import"],
  extensions: [".js", ".json", ".node", ".ts"],
});

module.exports = (request, options) => resolver(options.basedir, request);

@junderw As I understood, adding a package.json#main field would also resolve the issue. Is there a specific reason this has not been added? If you just haven't gotten around to it, let me know and I can create a PR for it.