reactjs - React Native: plattformspesifikk import


Fikk denne rare situasjonen. Bygger for React Native og bruker en native pakke fra Intercom. Å importere den fungerer fint på Android eller iOS. Men for web (eller Node Jest) gir det en feil. Så må gjøre noen face-mønster "hacking" som dette

utilities/Intercom/index.ios.ts

export { default } from '@intercom/intercom-react-native'

utilities/Intercom/index.web.ts

export default function Intercom() {}

en fil som bruker Intercom

// @ts-ignore
import Intercom from '~/utilities/Intercom' // Cannot find module '~/utilities/Intercom' or its corresponding type declarations.ts(2307)

...

Intercom.logout() // no TS support

Ikke bare klager TS, men jeg mister også alle typer 😭

Finnes det noen annen måte å gjøre plattformspesifikk import på og beholde de native typene?


Feilen i jest (node) er Cannot read property 'UNREAD_CHANGE_NOTIFICATION' of undefined som også er beskrevet i deres dokumentasjon. Problemet er at jeg ikke kan mocke det når jeg bruker react-native-web som følger med expo.

Svar #1

Jeg tror dette er det du leter etter https://stackoverflow.com/a/43531355/1868008

I din utilities-mappe, opprett en fil som heter Intercom.d.ts og plasser følgende der

import DefaultIos from "./Intercom/index.ios";
import * as ios from "./Intercom/index.ios";
import DefaultWeb from "./Intercom/index.web";
import * as web from "./Intercom/index.web";

declare var _test: typeof ios;
declare var _test: typeof web;

declare var _testDefault: typeof DefaultIos;
declare var _testDefault: typeof DefaultWeb;

export * from "./Intercom/index.ios";
export default DefaultIos;

Ikke sikker på hva alle de er. Kanskje noe som brukes i TypeScript-interne funksjoner.

Og for testene ser det ut til at du må lage en mock for hver metode du bruker i koden du tester, f.eks. i denne App-komponenten; jeg bruker logEvent-metoden, så jeg returnerer den i mock-objektet til biblioteket

import React from "react";
import renderer from "react-test-renderer";

import App from "./App";
jest.mock("@intercom/intercom-react-native", () => ({ logEvent: jest.fn() }));

describe("<App />", () => {
  it("has 1 child", () => {
    const tree = renderer.create(<App />).toJSON();
    expect(tree.children.length).toBe(1);
  });
});

App.tsx

...
import Intercom from "./utilities/Intercom";

export default function App() {
  Intercom.logEvent("test", {});
   ...
}

For webimplementeringen kan du importere typen for å sikre samsvar med biblioteksgrensesnittet

import type { IntercomType } from "@intercom/intercom-react-native";

const webImplementation: IntercomType = {
  // here implement all methods
};

export default webImplementation;

https://github.com/diedu89/expo-isomorphic-import-ts

Relaterte artikler