Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues importing @generouted/react-router/client in jest #145

Closed
alexander7161 opened this issue Jan 16, 2024 · 8 comments
Closed

Issues importing @generouted/react-router/client in jest #145

alexander7161 opened this issue Jan 16, 2024 · 8 comments

Comments

@alexander7161
Copy link

Describe the Bug

Everything is working fine with generouted. However when I try to run jest tests that import a file that imports generouted client hooks I get the following error: Cannot find module '@generouted/react-router/client' from 'src/router.ts'

Seems to be related to https://stackoverflow.com/questions/53466859/jest-cannot-find-module-from-node-modules/75595580#75595580
Perhaps exporting a cjs version of client would fix it? See

Generouted Version

1.18.2

Your Example Website or App or Reproduction

N/A

Steps to Reproduce the Bug or Issue

  1. Create a vite project using jest for testing
  2. import generouted router.ts in a file that has tests
  3. The import fails with error Cannot find module '@generouted/react-router/client' from 'src/router.ts'

Expected Behavior

Generouted client should import correctly in commonJS environment

Screenshots or Videos

No response

Platform

  • OS: macOS

Additional context

No response

@oedotme
Copy link
Owner

oedotme commented Jan 17, 2024

Hey @alexander7161, could you provide a Stack blitz example?

I'm also wondering why do you need to import generouted at Jest test? As this file only contains type related exports, and some type-safe react-router-dom exports.

@alexander7161
Copy link
Author

Thanks for the response!

Here's a minimal reproduction: https://stackblitz.com/edit/vitejs-vite-qsba6t?file=src%2Fmain.test.tsx

If you run jest in the console you will see an error importing generouted:
image

I'm not importing generouted directly, I'm testing a file that imports src/router which imports generouted

@oedotme
Copy link
Owner

oedotme commented Jan 18, 2024

Hey @alexander7161, I tried with vitest but it fails as well. I've encountered errors related to import.meta.glob resolving which is a Vite browser API that's used to scan the modules. I don't expect it to work out well tbh.

Could you try playwright instead of jest|vitest to test out the rendering? as it provides a real browser environment. After installing and setting up playwright using yarn create playwright, that would be an equivalent test:

// tests/rendering.test.ts

import { expect, test } from '@playwright/test'

test('rendering', async ({ page }) => {
  await page.goto('/')
  await expect(page.getByRole('heading', { name: 'Home' })).toBeVisible()
})

@alexander7161
Copy link
Author

But src/router only imports @generouted/react-router/client, which looking at the source code doesn't use import.meta.glob at all and only imports methods from react-router-dom

The original use case I had was a jest unit test on a ProtectedRoute component (e.g https://www.robinwieruch.de/react-router-private-routes/) that imports Navigate from src/router. Ideally I'd be able to test this with jest only and not need playwright

@alexander7161
Copy link
Author

alexander7161 commented Jan 22, 2024

I did some more debugging and added a "require": "./dist/client/index.js" to the @generouted/react-router ./client export in my node_modules, here: https://github.com/oedotme/generouted/blob/8939c9dc0012c73b08b0b4a0ff2c334e6c0859c9/packages/react-router/package.json#L48C8-L48C14

Now I get a different error:

Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    /frontend/node_modules/@generouted/react-router/dist/client/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import {
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

I believe if generouted had a cjs export for react-router/client then it would work correctly.

See https://stackoverflow.com/questions/53466859/jest-cannot-find-module-from-node-modules

@oedotme
Copy link
Owner

oedotme commented Jan 22, 2024

@alexander7161 If you need to test the rendering as the example you provided — then you'd need to import the Routes component which is imported from @generouted/react-router which uses import.meta.glob to scan the routes.

When I tried to add the cjs format to @generouted/react-router, I got an error related to the import.meta.glob which is expected. Here's a related comment on this issue.

If you actually need to use imports from the src/router.ts generated file — you can skip src/router.ts and @generouted/react-router/client all together and import the components/hooks/utils directly from react-router-dom to test out what you need, as src/router.ts only adds some type narrowing to react-router-dom exports.

Hope that helps, please let me know if you have more questions.

@alexander7161
Copy link
Author

The thing is I want to use src/router.ts so I can benefit from the type safety of generouted in my components. I want to keep using jest for testing them. It's a shame that generouted doesn't export a cjs version as that would solve this issue.

I found a workaround if anyone is running into the same issue.

Add these to your jest.config.js:

{
  "transformIgnorePatterns": [
    "node_modules/(?!@@generouted)"
  ],
  "moduleNameMapper": {
    "@generouted/react-router/client": "<rootDir>/node_modules/@generouted/react-router/dist/client"
  }
}

This tells jest not to transform generouted (since it's already ESM) and maps @generouted/react-router/client to the ESM client dist folder

@oedotme
Copy link
Owner

oedotme commented May 13, 2024

Glad you had it working with this config. Thanks for sharing the workaround.

@oedotme oedotme closed this as completed May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants