Skip to content

Compatibility with @react-navigation #6

@JohanObrink

Description

@JohanObrink

The plugin doesn't work with @react-navigation. I have found a few places where it breaks and possible ways to fix them but wanted to get your input first on how to proceed.

So far I have only edited code directly in the installed package.

Repro code

App.tsx

import { NavigationContainer } from '@react-navigation/native'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import { View } from 'react-native'

const Home = () => (<View />)
const Profile = () => (<View />)
const Navigator = createBottomTabNavigator()

export const App = () => (
  <NavigationContainer>
    <Navigator.Navigator >
        <Navigator.Screen name="Home" component={Home} />
        <Navigator.Screen name="Profile" component={Profile} />
      </Navigator.Navigator>
  </NavigationContainer>
)

App.spec.tsx

import { test, expect } from 'vitest'
import { render } from '@testing-library/react-native'
import { App } from './App'

test('it works', () => {
  const app = render(<App />)
  expect(app).toBeTruthy()
})

Requiring binaries

Running the test fails due to:

SyntaxError: Invalid or unexpected token
 ❯ Object.newLoader [as .js] ../../node_modules/pirates/lib/index.js:121:43
 ❯ Object.<anonymous> ../../node_modules/@react-navigation/elements/src/index.tsx:20:3

This because @react-navigation loads some binary assets:

export const Assets = [
  // eslint-disable-next-line import/no-commonjs
  require('./assets/back-icon.png'),
  // eslint-disable-next-line import/no-commonjs
  require('./assets/back-icon-mask.png'),
];

Quick and dirty solution:

if (!filename.endsWith('.png')) oldLoader(mod, filename);

Maybe all required binaries should just be ignored? Or replaced with Blobs? Also I am unfamiliar with pirates

  • how can this be done?

document and history are missing from global

After adding the quickfix for the pngs, the next error is:

ReferenceError: document is not defined
 ❯ ../../node_modules/@react-navigation/native/src/useDocumentTitle.tsx:32:7

...and after fixing that:

TypeError: Cannot read properties of undefined (reading 'state')
 ❯ Object.index ../../node_modules/@react-navigation/native/src/createMemoryHistory.tsx:35:33

Solution: add them

Object.defineProperties(globalThis, {
  // ...
  document: {
    configurable: true,
    enumerable: true,
    value: {},
    writable: true,
  },
  history: {
    configurable: true,
    enumerable: true,
    value: {},
    writable: true,
  },
})

window is not an event emitter

The next error is:

TypeError: window.addEventListener is not a function
 ❯ Object.listen ../../node_modules/@react-navigation/native/src/createMemoryHistory.tsx:217:14

...and this is where I ran out of quick and dirties. It seems the entire window object,
(represented as globalThis) should be augmented to work like it does in React Native.

I am happy to work on this but I think it needs your involvment to go in the direction you intended.

@sheremet-va What are your thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions