react-native-test-app
Version:
react-native-test-app provides a test app for all supported platforms as a package
135 lines (122 loc) • 4.48 kB
JavaScript
// @ts-check
const { createRunOncePlugin } = require("@expo/config-plugins");
const {
mergeContents,
} = require("@expo/config-plugins/build/utils/generateCode");
const { getPackageVersion, toVersionNumber, v } = require("../scripts/helpers");
const { withReactNativeHost } = require("./index");
/** @import { ExportedConfig } from "@expo/config-plugins" */
const NAME = "react-native-reanimated";
/**
* Adds specified contents to an existing file with a generated header.
* @param {string} tag Tag used to generate a unique header
* @param {string} src Contents of the source file
* @param {string} newSrc Contents to be added
* @param {RegExp} anchor `RegExp` providing the position at which contents is added
* @returns {string} The merged content
*/
function addContents(tag, src, newSrc, anchor) {
return mergeContents({
tag: `${NAME}-${tag}`,
src,
newSrc,
anchor,
offset: 1,
comment: "//",
}).contents;
}
/**
* Returns the code that initializes Reanimated.
* @param {number} version
* @param {string} indent
* @returns {[string, string]}
*/
function installerFor(version, indent = " ") {
const minor = v(0, 1, 0);
const minorVersion = Math.trunc(version / minor) % minor;
if (version > 0 && version < v(0, 72, 0)) {
const header = [
"#if !USE_FABRIC",
"#pragma clang diagnostic push",
'#pragma clang diagnostic ignored "-Wnullability-completeness"',
"",
`#define REACT_NATIVE_MINOR_VERSION ${minorVersion}`,
"#import <RNReanimated/REAInitializer.h>",
"",
"#if __has_include(<reacthermes/HermesExecutorFactory.h>)",
"#import <reacthermes/HermesExecutorFactory.h>",
"using ExecutorFactory = facebook::react::HermesExecutorFactory;",
"#elif __has_include(<React/HermesExecutorFactory.h>)",
"#import <React/HermesExecutorFactory.h>",
"using ExecutorFactory = facebook::react::HermesExecutorFactory;",
"#else",
"#import <React/JSCExecutorFactory.h>",
"using ExecutorFactory = facebook::react::JSCExecutorFactory;",
"#endif",
"",
"#pragma clang diagnostic pop",
"#endif // !USE_FABRIC",
].join("\n");
const installer = [
`${indent}const auto installer = reanimated::REAJSIExecutorRuntimeInstaller(bridge, nullptr);`,
`${indent}auto installBindings = facebook::react::RCTJSIExecutorRuntimeInstaller(installer);`,
`${indent}return std::make_unique<ExecutorFactory>(installBindings);`,
].join("\n");
return [header, installer];
} else {
// As of React Native 0.72, we need to call `REAInitializer` instead. See
// https://github.com/software-mansion/react-native-reanimated/commit/a8206f383e51251e144cb9fd5293e15d06896df0.
const header = [
"#if !USE_FABRIC",
`#define REACT_NATIVE_MINOR_VERSION ${minorVersion}`,
"#import <RNReanimated/REAInitializer.h>",
"#endif // !USE_FABRIC",
].join("\n");
return [header, `${indent}reanimated::REAInitializer(bridge);`];
}
}
/**
* Plugin to inject Reanimated's JSI executor in the React bridge delegate.
*
* Only applies to iOS.
*
* @param {ExportedConfig} config Exported config
* @returns {ExportedConfig} Modified config
*/
function withReanimatedExecutor(config) {
// As of 3.4.0, manual initialization is no longer necessary:
// https://github.com/software-mansion/react-native-reanimated/commit/6f19a367f4939cbbc82f3de6668fd896c695a2ac
const reanimated = getPackageVersion("react-native-reanimated");
if (toVersionNumber(reanimated) >= v(3, 4, 0)) {
return config;
}
return withReactNativeHost(config, (config) => {
if (config.modResults.language !== "objcpp") {
throw new Error(
"`ReactNativeHost` is not in Objective-C++ (did that change recently?)"
);
}
const rnVersion = toVersionNumber(getPackageVersion("react-native"));
const [header, installer] = installerFor(rnVersion);
// Add Reanimated headers
config.modResults.contents = addContents(
"header",
config.modResults.contents,
header,
/#import "ReactNativeHost\.h"/
);
// Install Reanimated's JSI executor runtime
config.modResults.contents = addContents(
"installer",
config.modResults.contents,
installer,
/\/\/ jsExecutorFactoryForBridge: \(USE_FABRIC=0\)/
);
return config;
});
}
module.exports = createRunOncePlugin(
withReanimatedExecutor,
NAME,
"UNVERSIONED"
);