kwhitley / itty-router

A little router.
MIT License
1.75k stars 78 forks source link

Jest fails with "SyntaxError: The requested module 'itty-router' does not provide an export named 'Router'" #74

Closed ptim closed 2 years ago

ptim commented 2 years ago

Loving itty-router, thanks!

This one has me stumped… I'm using https://github.com/mrbbot/miniflare-typescript-esbuild-jest, which is working really well with itty-router in miniflare and when deployed to Cloudflare, but a basic test fails with:

SyntaxError: The requested module 'itty-router' does not provide an export named 'Router'

I went way down the rabbit hole trying to understand why (cos stepping through my miniflare + itty-router project works a treat), and I can see node_modules/itty-router/dist/itty-router.min.js getting evaluated…

I understand that this may be an issue with the ts-jest configuration, but through I'd mentioned it any way (and tag it 'question') in case the solution is self-evident to someone else…

Here's a minimal repro: https://github.com/ptim/miniflare-typescript-esbuild-jest/commit/371a788e7b7e18cdaba293447f5918c2bf0840e5

Thanks for your work 🙏

ptim commented 2 years ago

I have a workaround for now - I've vendored itty-router in directly; tests pass, and are debuggable in vscode-jest 🎉

https://github.com/ptim/miniflare-typescript-esbuild-jest/commit/d63c8c0f22a409163d130dac0dac02f5d1299f33

kwhitley commented 2 years ago

Anyone else know what this is about? I definitely have never seen this issue before and import itty all over the place (including jest via the built-in tests).

You definitely should not have to manually path to itty... this is super weird.

ptim commented 2 years ago

Still working through my build / Jest / itty issues - logged some related tickets, and updated my repro for this issue. Note that the updated repo is update to miniflare rc4, and my repo builds, but errors on serving requests...

Ugh… just thought I'd try removing itty from that repro, and:

Double ugh… I can't get get back to a known good state, despite closing all browser windows, quitting vscode, checking out the known good, setting package.json deps to pinned versions (no ^), standing on one leg and:

rm -rf node_modules .mf dist && npm prune && npm install && npm run build && npm test; npm run dev

Time to turn off the lappie and head outside :)

Related issues:

mrbbot commented 2 years ago

Commented at miniflare (https://github.com/cloudflare/miniflare/issues/131#issuecomment-1003439235), but I'll copy it here too.


It looks like Jest isn't able to identify named exports in CommonJS modules when importing them as ES modules, if they use arrow functions. 🙃 As an example, I created a new project, installed jest, set "type": "module" in my package.json, added the following 2 files...

// index.spec.js
import { Router } from "./router.cjs";

test("logs", () => {
  console.log(Router);
});
// router.cjs
module.exports = {
  Router: () => {},
};

...then ran NODE_OPTIONS=--experimental-vm-modules npx jest. This gives exactly the same error:

SyntaxError: The requested module './router.cjs' does not provide an export named 'Router'

Changing Router: () => {} to Router: function() {} causes the test to pass. 😅

Unfortunately, itty-router's dist/itty-router.min.js file starts like this...

module.exports={Router:({base:t="",routes:l=[]}={})=>({...})}

...hence the issue.

If you do the export destructing yourself though from the default export, everything works:

import itty from "itty-router";
const { Router } = itty;
kwhitley commented 2 years ago

Stand by - 2.5.2 has switched to old-school function declaration style to solve this... would love someone to test once it's live :)

ptim commented 2 years ago

Thanks very much @kwhitley and @mrbbot - works well for me in my repro: https://github.com/ptim/miniflare-typescript-esbuild-jest/pull/1/commits/ce22fcfe83538c7186e2c6ca6553ced054def415 🙏