[autolinking] Maintain hierarchical order when linking isolated modules (#24351)# Why My previous fix for isolated modules (https://github.com/expo/expo/pull/23867) is not fully correct. The ol
[autolinking] Maintain hierarchical order when linking isolated modules (#24351)# Why My previous fix for isolated modules (https://github.com/expo/expo/pull/23867) is not fully correct. The old fix basically discovers _every dependency_ within the pnpm store folder. - This works, but might also link modules that are unrelated to the Expo project (e.g. when using monorepos). - It also loses the hierarchical structure, e.g. nested dependencies from `expo` (like `expo-application`) are added as being on the same level as direct project dependencies. # How This new fix attempts to keep these nested dependencies hierarchy as much as possible. Instead of looking up the pnpm store, it tries to detect if isolated modules are used. If it's detected, it looks up every individual "group of isolated modules" by expanding the `searchPaths`. The detection is done by the following check: - If the current "realpath" of the package being linked has a parent `node_modules` folder ... - ... and that `node_modules` folder is not "searched" yet (not added to `searchPaths` yet) ... - add this parent `node_modules` folder to the `searchPaths` to also link dependencies in those folders > ⚠️ This _**should**_ work, without checking on `.pnpm` store name, since linked modules should never have a direct `node_modules` parent. That only happens when using isolated modules. # Test Plan ~~We probably need to add dedicated pnpm tests to autolinking, but for now, it's manually testable with the following steps:~~ Added the two test cases below, as unit tests (lots of mocking). Probably need to add e2e tests and use pnpm too. You can still test it manually with the following steps: - Create a basic Expo project anywhere - `yarn create expo -t tabs ./test-pnpm-autolinking` - `cd ./test-pnpm-autolinking` - Create a dump of autolinking data, to compare it with pnpm - `yarn expo-modules-autolinking resolve --platform android > autolinking-yarn.json` - Reinstall with pnpm - `rm -rf node_modules yarn.lock` - `pnpm install` - Create a new dump of autolinking data, to compare it with yarn - `node <expo/expo>/packages/expo-modules-autolinking/bin/expo-modules-autolinking resolve --platform android > autolinking-pnpm.json` - Check if both `autolinking-yarn.json` and `autolinking-pnpm.json` is identical Then also check what happens if a different version of `expo-application` is installed as project dependency. It should take priority over the `expo > expo-application` version in both pnpm and yarn autolinking. I've used vscode launch for this to also check what exactly is going on inside autolinking. For that, you'll need to add `.vscode/launch.json` to your expo/expo repo, and update the paths. See snippet below: <details><summary><code>.vscode/launch.json</code> file</summary> ```jsonc { "configurations": [ { "type": "node", "request": "launch", "name": "Expo Autolinking: resolve", "program": "${workspaceFolder}/packages/expo-modules-autolinking/bin/expo-modules-autolinking", "args": [ "resolve", "--platform", "android" ], "console": "integratedTerminal", // Update the path below to your Expo project installed with pnpm "cwd": "/Users/cedric/Desktop/test-sdk-50/expo-pnpm" } ] } ``` </details> # Checklist <!-- Please check the appropriate items below if they apply to your diff. This is required for changes to Expo modules. --> - [ ] Documentation is up to date to reflect these changes (eg: https://docs.expo.dev and README.md). - [ ] Conforms with the [Documentation Writing Style Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md) - [ ] This diff will work correctly for `npx expo prebuild` & EAS Build (eg: updated a module plugin).
show more ...
[ios][autolinking] Fix missed react import patches (#23923)Directives with leading or trailing whitespace on their line would not previously be patched # Why Noticed this in a project using a
[ios][autolinking] Fix missed react import patches (#23923)Directives with leading or trailing whitespace on their line would not previously be patched # Why Noticed this in a project using a native module with `#import` blocks like this: ```objective-c #if __has_include(<React/RCTBridgeModule.h>) #import <React/RCTBridgeModule.h> #elif __has_include("React/RCTBridgeModule.h") #import "React/RCTBridgeModule.h" #else #import "RCTBridgeModule.h" #endif ``` The very first clean build after `pod install` would work but all subsequent builds would fail with `Declaration of 'RCTBridgeModule' must be imported from module 'React.RCTBridge' before it is required`. Eventually surmised that it was because this code block was only being half-patched by `expo_patch_react_imports!`. I think it was because the first build had no modulemap yet so went into one of the patched directives. Subsequent builds have a modulemap from the first build so ended up in the unpatched else instead? # How Updates the regexps to account for whitespace before or after the directives that are being looked for. Did it as a positive lookbehind and lookahead so existing indentation/trailing whitespace is left as-is once the patch is in place (seemed safer).
[autolinking] add some unit tests for findModules in workspace (#17425)# Why it's not clear how the transitive packages are linked in expo-modules-autolinking # How add some unit tests for
[autolinking] add some unit tests for findModules in workspace (#17425)# Why it's not clear how the transitive packages are linked in expo-modules-autolinking # How add some unit tests for `findModulesAsync`. hopefully to increase test coverage as well as write down use cases we supported. # Test Plan ``` PASS src/autolinking/__tests__/findModules-test.ts findModulesAsync ✓ should link hoisted package in workspace (1 ms) ✓ should not link hoisted package which are not in app project dependencies ✓ should link packages which are in app project transitive dependencies (1 ms) ✓ should not link packages which are not in app project transitive dependencies (1 ms) ✓ should link non-hoisted package first if there are multiple versions ```
[autolinking] Support multiple podspecs and gradle projects in a package (#16511)# Why - support the case where a package has multiple podspecs, e.g. [react-native-maps](https://github.com/reac
[autolinking] Support multiple podspecs and gradle projects in a package (#16511)# Why - support the case where a package has multiple podspecs, e.g. [react-native-maps](https://github.com/react-native-maps/react-native-maps/blob/master/docs/installation.md#enabling-google-maps) - being less intrusive to 3rd party libraries when we proposing expo integration. for example, current integration to [reanimated add one line to existing code](https://github.com/software-mansion/react-native-reanimated/blob/a870aa28092322b627695f8cf2ea0dce4db34a53/android-npm/build.gradle#L111) and [turn reanimated gradle project to a different form](https://github.com/software-mansion/react-native-reanimated/blob/a870aa28092322b627695f8cf2ea0dce4db34a53/android-npm/expo/linking.gradle#L15-L45). - expo reanimated integration had introduced some issues as following. based on this, i think we should have a dedicated gradle project. - https://github.com/software-mansion/react-native-reanimated/issues/2711 - https://github.com/software-mansion/react-native-reanimated/pull/2713#issuecomment-1024341773 # How - support multiple podspec linking - `*/*.podspec` - support multiple build.gradle linking - `*/build.gradle` - ~introduce special expo adapter integration where we can put all stuffs including `expo-module.config.json` in `expo/` folder in this case, rn-cli's autolinking will link `RNThirdParty.podspec` and `android/build.gradle`. expo autolinking will link `RNThirdPartyExpoAdapter.podspec` and `expo/android/build.gradle`~ - add expo-module.config.js `android.gradlePath` support to specify custom gradle file paths. # Test Plan ## Unit Tests ``` PASS src/platforms/__tests__/android-test.ts resolveModuleAsync ✓ should resolve android/build.gradle (2 ms) ✓ should resolve multiple gradle files (1 ms) convertPackageNameToProjectName ✓ should strip invalid characters (1 ms) ✓ should convert scoped package name to dash ✓ should have differentiated name for multiple projects ✓ should support expo adapter name PASS src/autolinking/__tests__/findModules-test.ts findModulesAsync ✓ should link top level package (2 ms) ✓ should link scoped level package (1 ms) PASS src/platforms/__tests__/ios-test.ts resolveModuleAsync ✓ should resolve podspec in ios/ folder ✓ should resolve multiple podspecs (1 ms) ``` ## Integration Tests - create extra `ios2/EXApplication2.podspec` in expo-application - create extra `android2/build.gradle` in expo-application - check rn-cli autolinking and expo autolinking co-existence compatibility - move `use_native_modules!` before `use_expo_modules!` in Podfile - create extra `ios2/RNReanimated2.podspec` in reanimated and check whether it's linked. Co-authored-by: Tomasz Sapeta <[email protected]>
[autolinking] Add react-native 0.66 support for ReactImportsPatcher (#15724)# Why in react-native 0.66, the `#if __has_include("RCTBridge.h")` also leads to build errors. feedback from https://g
[autolinking] Add react-native 0.66 support for ReactImportsPatcher (#15724)# Why in react-native 0.66, the `#if __has_include("RCTBridge.h")` also leads to build errors. feedback from https://github.com/expo/expo/issues/15622#issuecomment-999815962 # How transform `#if __has_include("RCTBridge.h")` to `#if __has_include(<React/RCTBridge.h>)` # Test Plan ```sh $ npx react-native init RN066 --version 0.66 $ cd RN066 $ npx install-expo-modules $ yarn add [email protected] $ npx pod-install $ yarn ios ```
[autolinking] Introduce patcher for double-quoted import issue (#15655)# Why systematic workaround for #15622 # How transform all double-quoted react imports from all cocoapods linked proj
[autolinking] Introduce patcher for double-quoted import issue (#15655)# Why systematic workaround for #15622 # How transform all double-quoted react imports from all cocoapods linked project # Test Plan ## Integration Test - bare-expo CI build passed - from a sdk 44 project ``` expo init sdk44 # select bare yarn add react-native-get-random-values yarn add file:/path/to/expo/packages/expo yarn add file:/path/to/expo/packages/expo-modules-autolinking # add the block to ios/Podfile post_integrate do |installer| expo_patch_react_imports!(installer) end expo run:ios ``` ## Unit Test ``` PASS src/__tests__/ReactImportsPatcher-test.ts patchFileAsync ✓ should transform double-quoted import (1 ms) ✓ should not transform React-Core headers (1 ms) ✓ should not write changes when `dryRun` is true ``` Co-authored-by: James Ide <[email protected]> Co-authored-by: Tomasz Sapeta <[email protected]>