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

Add globalObject: 'global' for react native webpack config #1738

Merged
merged 1 commit into from Apr 17, 2024

Conversation

VeskeR
Copy link
Contributor

@VeskeR VeskeR commented Apr 16, 2024

When running Jest tests with the 'react-native' preset (the default preset used when app is created with react-native init), tests are run in a Node.js environment (from docs). There are some slight differences, such as the this global variable being an empty object, and the 'window' global variable is present.

When running Jest tests with the 'react-native' preset, it supports the exports field in the package.json file. It resolves libraries with an exports field using the react-native condition.

Our react-native exports condition exports an ably-reactnative.js bundle, which is built using webpack v5. By default, webpack v5 sets the globalObject to self. In Node.js environments, the self global property does not exist, so our React Native bundle fails with a ReferenceError: self is not defined when we try to run Jest tests.

This issue does not occur for ably-js v1 because we don't use exports in the package.json file, and Jest, for some reason, doesn't recognize the root react-native field in package.json. So, instead, when running Jest tests for React Native with ably-js v1, it uses our Node.js bundle, which has global for its globalObject.

To fix the ReferenceError: self is not defined error for ably-js v2, we should change the globalObject to something supported both in Node.js environments when running Jest tests for React Native and in React Native itself. In ably-js v1, our bundles used the following global objects:

  • ably-node used 'global'
  • ably-reactnative used 'window'

Based on my tests, window === global both when running Jest tests for React Native and when running a React Native app. So, we can use globalObject: 'global' for our React Native bundle in ably-js v2.


NOTE
Even though this resolves the ReferenceError: self is not defined error for Jest tests, they will still fail with other errors like ReferenceError: WebSocket is not defined. This is because Jest with 'react-native' preset is using a node environment, which doesn't load any DOM or browser APIs, but our ably-reactnative.js bundle expects certain browser APIs like WebSocket to be available in the global scope.
This is not something we can resolve directly, so users would need to either mock the Ably client or provide mocks for such browser APIs when running Jest tests (example here), or force Jest to use the ably-js node.js bundle by adding the following config to their jest.config.js:

moduleNameMapper: {
    ably: require.resolve('ably'),
},

Or users can force Jest to resolve the exports field using the node condition for all bundles (although this is the least ideal solution):

testEnvironmentOptions: {
    customExportConditions: ['node'],
},

Copy link
Member

@owenpearson owenpearson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks for the detailed description 👍

@VeskeR VeskeR merged commit 60faa30 into main Apr 17, 2024
11 of 12 checks passed
@VeskeR VeskeR deleted the 1729/fix-react-native-bundle-for-jest branch April 17, 2024 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants