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

[Do Not Merge] => feat(expo): Migrate app to Expo #280

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

damassi
Copy link
Member

@damassi damassi commented Nov 14, 2024

Description

Similar to the Folio Expo migration this spikes on migrating palette mobile over as well.

TLDR: The toolchain is legit! I'm honestly kinda amazed by all of the things that are packed into npx expo start, and impressed at how easy it was to get all of the deps fully configured with npx expo-doctor.

Given the abundant docs, I took a couple right turns initially, but then started over and everything worked very painlessly and was able to set up from scratch and run it in the iOS simulator in about 15 minutes.

Here are the steps I took:

  • Install and auto-configure Expo: npx install-expo-modules@latest
  • Run npx expo-doctor. Noticed there were a few package versions that weren't aligned with expo, a few minor versions away
  • Run npx expo install --check. Installed everything, automatically updated package.json
  • Update metro config with expo-centric settings
const { getDefaultConfig } = require("@expo/metro-config")
const config = getDefaultConfig(__dirname)
module.exports = config
  • Remove main entry in package.json. This really stumped me initially before I bailed on trying to work around it. Expo reads this as the entrypoint for the app and it is not negotiable! There is no more entryPoint on app.json. Previously this pointed at the dist/index.js, the npm-publish friendly (compiled) version of our consumable @artsy/palette-mobile lib. Need to test whether lib still works in consumers without main. I think its fine.
  • Compile and boot iOS: npx expo run:ios
  • Compile and android: npx expo run:android
  • Errors using existing android folder, so delete it and let expo generate everything from scratch. Rerun.
  • Compiles good!
  • Update getMainComponentName to match app name: "PaletteMobile"
  • Start in dev mode: npx expo start
  • App boots and runs great

Final steps involve things like CI and fastlane and updating commands for prod / beta builds (though i'm not sure we even need to do this; all this app is is a local storybooks for developing components. No reason we need to do anything at all but send out npm version via CI).

@damassi damassi self-assigned this Nov 14, 2024
@artsy-peril artsy-peril bot added the Version: Minor A deploy for new features label Nov 14, 2024
@artsy-peril
Copy link

artsy-peril bot commented Nov 14, 2024

eslint-plugin-ft-flow

Author: Unknown

Description: Flowtype linting rules for ESLint by flow-typed

Homepage: https://github.com/flow-typed/eslint-plugin-ft-flow#readme

Createdalmost 3 years ago
Last Updated4 months ago
LicenseMIT
Maintainers1
Releases25
Direct Dependencieslodash and string-natural-compare
Keywordseslint, eslintplugin, plugin, flow, flow-bin, flowtype and flow-typed
This README is too long to show.

react-native

Author: Unknown

Description: A framework for building native apps using React

Homepage: https://reactnative.dev/

Createdalmost 10 years ago
Last Updatedabout 4 hours ago
LicenseMIT
Maintainers7
Releases1962
Direct Dependenciesws, glob, anser, chalk, yargs, mkdirp, semver, promise, base64-js, commander, invariant, scheduler, ansi-regex, babel-jest, nullthrows, jsc-android, memoize-one, whatwg-fetch, metro-runtime, pretty-format, react-refresh, abort-controller, metro-source-map, event-target-shim, stacktrace-parser, flow-enums-runtime, react-devtools-core, regenerator-runtime, @react-native/codegen, jest-environment-node, @react-native/js-polyfills, @react-native/gradle-plugin, @react-native/assets-registry, @react-native/normalize-colors, @jest/create-cache-key-function, @react-native/virtualized-lists, babel-plugin-syntax-hermes-parser and @react-native/community-cli-plugin
Keywordsreact, react-native, android, ios, mobile, cross-platform, app-framework and mobile-development

react

Author: Unknown

Description: React is a JavaScript library for building user interfaces.

Homepage: https://reactjs.org/

Createdabout 13 years ago
Last Updatedabout 15 hours ago
LicenseMIT
Maintainers4
Releases2051
Direct Dependenciesloose-envify
Keywordsreact

expo-dev-client

Author: 650 Industries, Inc.

Description: Expo Development Client

Homepage: https://docs.expo.dev/versions/latest/sdk/dev-client/

Createdover 3 years ago
Last Updated1 day ago
LicenseMIT
Maintainers28
Releases172
Direct Dependenciesexpo-dev-menu, expo-manifests, expo-dev-launcher, expo-updates-interface and expo-dev-menu-interface
Keywordsreact-native, expo and expo-dev-client

expo

Author: Expo

Description: The Expo SDK

Homepage: https://github.com/expo/expo/tree/main/packages/expo

Createdover 11 years ago
Last Updatedabout 5 hours ago
LicenseMIT
Maintainers29
Releases622
Direct Dependencies@expo/cli, expo-font, fbemitter, expo-asset, @expo/config, @babel/runtime, expo-constants, expo-keep-awake, expo-file-system, @expo/fingerprint, babel-preset-expo, expo-modules-core, @expo/metro-config, @expo/vector-icons, @expo/config-plugins, web-streams-polyfill, expo-modules-autolinking and whatwg-url-without-unicode
Keywordsexpo

New dependencies added: expo, expo-dev-client, react, react-native and eslint-plugin-ft-flow.

Generated by 🚫 dangerJS against 3fbe6be

@damassi damassi added Version: Major A deploy for breaking changes to clients and removed Version: Minor A deploy for new features labels Nov 14, 2024
Copy link
Contributor

@araujobarret araujobarret left a comment

Choose a reason for hiding this comment

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

It really looks great!

Final steps involve things like CI and fastlane and updating commands for prod / beta builds (though i'm not sure we even need to do this; all this app is is a local storybooks for developing components. No reason we need to do anything at all but send out npm version via CI).

I think here it's used as a sanity check if something is breaking the build process of the app. We could experiment Expo's tooling instead of fastlane as part of the spike.

"react-native-reanimated": "3.16.1",
"react-native-safe-area-context": "4.11.1",
"react-native-svg": "14.1.0",
"react-native-reanimated": "~3.10.1",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that's the necessary evil 🫠

Copy link
Member Author

Choose a reason for hiding this comment

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

I completely agree!

<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
<string>E174.1</string>
<string>85F4.1</string>
Copy link
Contributor

Choose a reason for hiding this comment

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

this is maybe just because palette-mobiles privacy manifest wasn't accurate? but it might also be a side effect of pulling in expo which is a bit unfortunate, these show up on our privacy report card in App Store so adding extra keys is not ideal. Not the end of the world but not great.

Copy link
Member Author

Choose a reason for hiding this comment

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

I bet we can tweak this -- these were added when expo ran the first pass auto-fix via

npx install-expo-modules@latest

I didn't take this PR all the way to completion (notably things like assets and the like configure via app.json), so reminder this was just a first pass to determine ease and to get a feel for the process.

If we want to proceed I'd want to take it one step further:

  • free plan EAS builds
  • delete ios and android directories
  • Finish all of the static configuration so that we don't have to worry about asset configuration (splash, etc)

Copy link
Contributor

Choose a reason for hiding this comment

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

eigen has more in here so really only matters if there is a diff between what is there now and what we get by bringing in expo but something to look out for

Copy link
Contributor

@brainbicycle brainbicycle Nov 18, 2024

Choose a reason for hiding this comment

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

btw these comments are me trying to get more of a read on what this would take in Eigen than a typical PR review so nothing in stone just my thoughts

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh totally understand. Just clarifying that what's seen here is technically incomplete 👍

@@ -472,7 +515,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
Copy link
Contributor

Choose a reason for hiding this comment

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

i wonder if we have control over this? we are currently higher in eigen. not a deal breaker but something to look out for as these little keys have big consequences.

</style>
<style name="Theme.App.SplashScreen" parent="AppTheme">
<item name="android:windowBackground">@drawable/splashscreen</item>
</style>
Copy link
Contributor

Choose a reason for hiding this comment

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

does expo replace react-native-bootsplash in eigen's case?

override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG

override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
Copy link
Contributor

Choose a reason for hiding this comment

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

not important for palette but a call out if we do move to eigen we have customization in these native files for configuring some deps, I think Braze is one. We should try to understand what we have to do to either keep a custom version or generate a custom version or probably a lot of libraries have migration instructions.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Copy link
Contributor

Choose a reason for hiding this comment

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

seems to have added a bunch of permissions, not a concern for palette-mobile, probably not a concern for eigen unless they differ from what is already there? but we should look out for it

<intent>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https"/>
Copy link
Contributor

Choose a reason for hiding this comment

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

have some custom domains in eigen for deeplinking, would be good to understand how that works in expo

@@ -7,4 +7,8 @@
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# react-native-reanimated
-keep class com.swmansion.reanimated.** { *; }
-keep class com.facebook.react.turbomodule.** { *; }
Copy link
Contributor

Choose a reason for hiding this comment

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

oh nice maybe this makes proguard adoption easier?

"react-dom": "18.2.0",
"react-native": "0.75.4",
"react-native": "0.74.5",
Copy link
Contributor

Choose a reason for hiding this comment

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

this is one of my bigger concerns, locking us to specific dependencies. we fairly often have to upgrade things to workround issues and from what I can see here:

downgraded packages

  • react native downgraded to 0.74.5 from 0.75.4
  • react native reanimated to 3.10.1 from 3.16.1
  • react from 18.2.0 to 18.3.1
  • react-native-safe-area-context from 4.11.1 to 4.10.5
  • @shopify/flash-list from 1.7.1 to 1.6.4
  • react-native-pager-view from 6.5.0 to 6.3.0

upgraded packages:

  • react-native-svg from 14.1.0 to 15.2.0
  • typescript from 5.0.4 to 5.3.3
  • @react-native-async-storage/async-storage 1.19.8 to 1.23.1

Copy link
Contributor

Choose a reason for hiding this comment

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

if we have a major bug that we need to upgrade for it would be good to understand what our options are, does that mean we have to eject? or patching is our only option?

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe I will check also how often this is actually true we fairly often have to upgrade things to workround issues I feel like it is true but should be able to see in pr history

Copy link
Member

Choose a reason for hiding this comment

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

fwiw, we can still keep the packages to the versions we want to and we don't have to be locked to what expo --fix suggests. The upgrades/downgrades are just suggestions we can ignore if we want to.

@gkartalis
Copy link
Member

@MounirDhahri @damassi a thing that I noticed in the community for react native libraries that use expo:

Seems like people are leaving expo outside the main library but they use it on an example app for running the library as an example there and the experience is pretty awesome and really fast + easy to contribute:

seems like we might need to treat palette-mobile a bit differently when it comes to an expo migration and treat it as a dependency and maybe have an example app that includes expo to be able to run it and develop on it taking the advantages of expo while at the same time not bloating the actual library code with extra deps.

Happy to hear your thoughts on this.

@MounirDhahri
Copy link
Member

@gkartalis - yes, that's a good point. I don't have an idea yet how we can migrate palette-mobile, and still keep it working across two apps. I managed to get it only to work on Energy but as you mentioned we need to be careful with this migration to keep palette working for both repos.
For the sake of migrating Energy, I did some updates #273 but those would break it in Eigen.

@damassi
Copy link
Member Author

damassi commented Nov 20, 2024

@gkartalis - I'm down with this manner of working on things! My take is that palette-mobile is somewhat trivial in the sense that its just a collection of components published to NPM, and a storybooks app to run.

We'd want to (ideally) run yarn expo-doctor on it to keep things within bounds lib wise, but once that's in place, I think its largely safe to keep things as they are.

But better would be to just have it all be on expo, delete ios and android folders, and keep it slim as possible. I'm not opinionated really; mostly think that Energy and Eigen would be the ones to benefit.

@gkartalis
Copy link
Member

@damassi note that also the libraries that I did mention do not include any android + ios folders since they are js only react native libraries but they do not include expo as a dep on their package.json.

We could have something similar - like keeping the components on the src folder or something and have an example app - which can be an expo app and from there we can run an expo storybook app (or even a normal app without storybook with component examples)

"styled-system": "^5.1.5"
"styled-system": "^5.1.5",
"react": "18.2.0",
"react-native": "0.74.5"
Copy link
Contributor

Choose a reason for hiding this comment

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

related to George's comment, I think one issue here is that moving these deps to hard versions in package.json presents a problem for consumers, ie. now Eigen needs to be on this specific RN version and same true for other libs. (I could be wrong not as familiar with nodes packaging) So we could either take George's approach of having an example app with the expo dependencies and keep the lib itself slim or find another way.

Copy link
Member Author

@damassi damassi Nov 20, 2024

Choose a reason for hiding this comment

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

I think in this instance react-native would be a peerDep and that would address the issue (assuming there's not other issues that would arise). Same with other libs that are shared from consumers of the app, keeping the dependencies array slender and scoped to (only) what palette-mobile might need when published and installed via npm. Would that work?

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah it sounds like it should!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Version: Major A deploy for breaking changes to clients
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants