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

"Could not auto-detect a React renderer." when bundled with webpack #544

Closed
eps1lon opened this issue Jan 17, 2021 · 7 comments
Closed

"Could not auto-detect a React renderer." when bundled with webpack #544

eps1lon opened this issue Jan 17, 2021 · 7 comments
Labels
bug Something isn't working

Comments

@eps1lon
Copy link
Member

eps1lon commented Jan 17, 2021

  • react-hooks-testing-library version: 5.0.0
  • react-test-renderer version: 16.14.0
  • react version: 16.14.0
  • node version: 10.x
  • npm (or yarn) version: yarn 1.22

Relevant code or config:

import { renderHook } from '@testing-library/react-hooks';

What you did:

Use @testing-library/react-hooks in code bundled for the browser with webpack.

What happened:

Uncaught Error: Could not auto-detect a React renderer. Are you sure you've installed one of the following
    - react-dom
    - react-test-renderer
  at webpack:///node_modules/@testing-library/react-hooks/lib/pure.js:58:1 <- test/karma.tests.js:16233:5

Full CI error log: https://app.circleci.com/pipelines/github/mui-org/material-ui/36491/workflows/08a2e3dd-21aa-474f-86cf-6458c9dd552e/jobs/217134/steps
Bundle: https://circle-production-customer-artifacts.s3.amazonaws.com/picard/53f31667f7d05ec7d09d22f4/6004879acb28353dcdb73883-0-build/artifacts/artifact-file/test/karma.tests.js?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20210117T203410Z&X-Amz-SignedHeaders=host&X-Amz-Expires=60&X-Amz-Credential=AKIAJR3Q6CR467H7Z55A%2F20210117%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=c5763f2e26dc5cd18e317195fc40c5fe06f8e96a1d2b2c842a5edf5e393ec2ee

Reproduction:

https://github.com/eps1lon/testing-libray-hooks-dynamic-require

Problem description:

We want to run tests in a real browser i.e. an environment where React can run (using karma-mocha). Some of those tests uses @testing-library/react-hooks.

Suggested solution:

Remove dynamic require(variable). require can only be bundled by webpack if called with a string literal.

@joshuaellis
Copy link
Member

This is documented under Renderer:

Note: The auto detection function may not work if tests are bundles before execution (e.g. to be run in a browser)

I'd therefore recommend you import the function directly from either native or dom depending on which test renderer you're using - react-test-renderer or react-dom respectively.

@mpeyper
Copy link
Member

mpeyper commented Jan 17, 2021

Just to be explicit, you should update your imports to import { renderHook, act } from '@testing-library/react-hooks/dom' and ensure you have react-dom installed if you're running in the browser. If you only had react-test-renderer installed for this library, then you can remove that dependency on your project as well.

@eps1lon
Copy link
Member Author

eps1lon commented Jan 17, 2021

Note: The auto detection function may not work if tests are bundles before execution (e.g. to be run in a browser)

Could you clarify what "bundles before execution" means? This is not clear to me.

Edit: You just mean "The auto detection function may not work if tests are bundles", right? The "before execution" part doesn't make much sense to me.

From the breaking changes changelog:

Importing from renderHook and act from @testing-library/react-hooks will now auto-detect which renderer to used based on the project's dependencies

This only seems to work when not bundled. What do you think about about updating the breaking changes to document that imports need to be updated and auto-detection only works when not bundled?

@mpeyper
Copy link
Member

mpeyper commented Jan 18, 2021

Happy to add a note to the release docs about bundling.

Edit: done

@mpeyper
Copy link
Member

mpeyper commented Jan 18, 2021

Technically, we could change src/pure.ts to define the renderers with something like:

const renderers = [
  { checkDependency: () => require('react-test-renderer'), importRenderer: () => require('./native/pure'), rendererName: 'react-test-renderer' },
  { checkDependency: () => require('react-dom'), importRenderer: () => require('./dom/pure'), rendererName: 'react-dom' }
]

With this (and some other changes), webpack could bundle successfully if both react-test-renderer and react-dom are installed, but you would always get the former as the resolved renderer.

I wonder if we can detect that the code has been bundled and throw a better error about using specific imports instead of the current, misleading error that is produced? I suspect we can't for every bundler that exists but maybe just for the main players in that space? Maybe the easier approach is to adjust the error message to include wording about bundlers:

Uncaught Error: Could not auto-detect a React renderer. Are you sure you've installed one of the following
    - react-dom
    - react-test-renderer
If you are using a bundler, please update you imports to use a specific renderer.  For instructions see: https://react-hooks-testing-library.com/installation#being-specific

@joshuaellis
Copy link
Member

At this time, I think this seems slightly niche, although if more people come forward we could consider creating work arounds etc. In the meantime, I think the updated message in the console would be good enough?

@mpeyper
Copy link
Member

mpeyper commented Jan 18, 2021

Yeah agreed. Let's update the error wording and keep an ear out for more affected users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
3 participants