I was working on deploying ponder's native app to TestFlight using Expo EAS when I found some interesting undocumented EAS feature flags that I think folks should know. These are especially useful if you have a monorepo.
First, I just wanted to say thank you to the Expo team for making native deployment a breeze. And the fact that their source code is open really help resource-constrained team (like mine) to solve our own problem and get stuffs done without having to wait for their next release.
When using eas build
, the eas-cli
first create an artifact of the project's source code, before pushing to the cloud for remote building. The default behavior is to use git as a source of truth to generate the latest source code artifact.
However, if the monorepo contains server-side module or any code unrelated to the expo project, it would also be included in the uploaded artifact. This results in an additional security risk - i.e if expo's artifact storage were to be compromised, our internal business logic will be exposed.
At the moment, the default git workflow does not provide a way to ignore file during the artifact creation process (since it's just invoking git internally). Thankfully, as of Expo SDK 43, a new flag EAS_NO_VCS=1
was introduced to opt-out of using git or any VCS to create the artifact using shallow file copy. With this flag, EAS then read from an .easignore
file to determine which file it should not copy into the cloud build artifact. The syntax for the .easignore
file is the same as a .gitignore
file:
# add any modules in your monorepo that is unrelated to EAS
service-a/
server-b/
socket-c/
However, there's one issue: monorepo
. In git workflow, expo can simply rely on git to get the project structure. With the plain workflow, expo can now only see the current directory it is running in. Thankfully, the expo team had implemented a solution for this, albeit undocumented.
I found this solution while reading through eas-cli
source code, looking for a way to patch it. Apparently, eas-cli
also read another flag in the environment called EAS_PROJECT_ROOT
: source. This variable is used by the EAS shallow copy method to create the complete project artifact.
To use this flag, first I move my .easignore
file to the root of my monorepo. Then, I run EAS like this:
cross-env EAS_NO_VCS=1 EAS_PROJECT_ROOT=.. eas build
And voila - everything worked. Now instead of uploading a whooping 160MB artifact, our deployment upload a measly 2.6MB artifact of front-end specific code!
Top comments (1)
Your post is the only one on the internet bringing EAS_PROJECT_ROOT to the surface, thanks a bunch for that.
We were drawn to your post because we tried
eas build -p ios
and were getting an error:We then tried
EAS_NO_VCS=1 eas build -p ios
and no longer had that error, but because we are in a mono-repo, our build failed during the expo build on the Install dependencies step. We had apostinstall
script in ourpackage.json
that used a sibling directory to our app. This failed because the the sibling folder was not there, as described in your article.We then tried
EAS_NO_VCS=1 EAS_PROJECT_ROOT=.. eas build -p ios
. This got us past the error in "Install Dependencies" but we now had a new error in our "Install Pods" step.Feeling a bit defeated, we came across another article (sorry couldn't find link) that said we needed to set
cli.requireCommit
totrue
in oureas.json
🎉.We tried this and were able to get through the full process after adding it and making a commit with it using just this command.
eas build -p ios
Hope this helps someone else on the internet!