Skip to content

flycrum/expo-yarn-monorepo-minimal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

minimal-expo-yarn-monorepo

The goal of this monorepo is to provide an unopinionated, zero-config monorepo setup for the Expo app template generated by yarn create expo so you can get started up and running as quickly as possible!

Why yarn?!

With first-class support from Expo, starting with Expo SDK 48, yarn is arguably the easiest way to manage a super simple monorepo, play around with Expo, and graduate to a more complex monorepo setup later.

Getting started

yarn install
yarn start

And beyond...

From this point on, the rest of the documentation found below is dedicated to additional context, references, recreation steps, and issues you may encounter. Good luck!

Docs

Step-by-step approach

In this example, we will set up a monorepo using Yarn workspaces without the nohoist option.

  1. Make sure you have yarn 1.x installed.

    yarn --version

    Install it if you don't have it.

    npm install --global yarn
  2. Initialize yarn project. Run yarn init, or create the package.json manually. It should look something like this:

    Note: All Yarn monorepos should have a "root" package.json file.

    {
      "name": "monorepo",
      "version": "1.0.0"
    }
  3. Set up yarn workspaces. Yarn and other tooling have a concept called "workspaces". Every package and app in our repository has its own workspace. Before we can use them, we have to instruct Yarn where to find these workspaces. We can do that by setting the workspaces property using glob patterns, within package.json:

    Note: Yarn workspaces require the root package.json to be private.

    {
      "name": "monorepo",
      "version": "1.0.0",
      "workspaces": ["apps/*", "packages/*"],
      "private": true
    }
  4. Create our first app.

    a. Create the app directory.

    mkdir apps/cool-app
    cd apps/cool-app

    b. Create the Expo app with its default tabs template using Expo Router.

    yarn create expo apps/cool-app

    c. Make sure to move the .gitignore file to the root of the monorepo.

    mv apps/cool-app/.gitignore ./
  5. Now test the app! When running the npx expo start command, use the EXPO_USE_METRO_WORKSPACE_ROOT environment variable. It enables the auto server root detection for Metro. This variable can also be defined inside a .env file. After testing, it appears that this isn't always necessary.

    Note: If you are not using Expo Router, you can change the default entrypoint.

    a. When testing the app, you should see the following message:

    ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
    █ ▄▄▄▄▄ █▀▄█▀ ▄█ ▄█ ▄▄▄▄▄ █
    █ █   █ █▀▄▀   ▀▀▄ ▄▄ █▀█▄█
    █ █▄▄▄█ █▀▀▄  ▀ █  █▄  ▄█▄█
    █▄▄▄▄▄▄▄█▄▄▄▄▄█▄█▄███▄▄█▄▄█
    
    › Metro waiting on exp://192.168.1.19:8082
    › Scan the QR code above with Expo Go (Android) or the Camera app (iOS)
    
    › Web is waiting on http://localhost:8082
    
    › Using Expo Go
    › Press s │ switch to development build
    
    › Press a │ open Android
    › Press i │ open iOS simulator
    › Press w │ open web
    

    b. Make certain live reload is working as expected by testing both the web (w) and native (i | a) apps. You can do this by starting those apps and making changes to the HomeScreen component defined within index.tsx. Changes should immediate.

  6. Create a package.

    a. From within the root of the monorepo, create the package directory and initialize it with yarn.

    mkdir -p packages/cool-package
    cd packages/cool-package
    yarn init

    b. Add a simple index.js file to the package.

    echo "export const greeting = 'Hello!';" > index.js
  7. Add the package to the app.

    a. Add cool-package to apps/cool-app/package.json so we can use it within our Expo app.

    yarn add cool-package

    Note: Like standard packages, we need to add our cool-package as a dependency to our cool-app. The main difference between a standard package, and one from the monorepo, is you'll always want to use the "current state of the package" instead of a version. Let's add cool-package to our app by adding "cool-package": "*" to our app package.json file.

    b. After adding the package as a dependency, run yarn install to install or link the dependency to your app.

    yarn install

    c. You should now be able to use the package inside your app! To test this, let's edit the HomeScreen component defined within index.tsx again:

    import { greeting } from "cool-package";
    
    // ...
    
    <ThemedView style={styles.titleContainer}>
      <ThemedText type="title">{greeting}</ThemedText>
      <HelloWave />
    </ThemedView>;
    
    // ...

    d. When running the apps, you should now see Hello! displayed instead of Welcome!.

  8. Make life easier by adding some root package scripts.

    a. Add the following to the package.json file:

    "scripts": {
      "start": "yarn workspace cool-app start",
      "start:android": "yarn workspace cool-app android",
      "start:ios": "yarn workspace cool-app ios",
      "start:web": "yarn workspace cool-app web"
    }

    b. Run with:

    yarn start
    
    # or
    yarn start:android
    yarn start:ios
    yarn start:web

Issues

Error: Unable to resolve "../../App" from "node_modules/expo/AppEntry.js"  

Note: as seen when running npx expo start

Problem: you're likely trying to run the app from the wrong location (e.g. the root of the monorepo).

Solution: run the command from the apps/cool-app directory instead.

More details:

  • With an Expo monorepo comes added complexity and issues you'll need to solve along the way, so proceed with caution and patience.
  • Expo SDK 50 and higher has improved support for more complete node_modules patterns, such as isolated modules. Unfortunately, React Native can still cause issues when installing multiple versions inside a single monorepo. Because of that, it's recommended to only use a single version of React Native. You can check if your monorepo has multiple React Native versions and why they are installed through the package manager you use.
    yarn why react-native

Structure

We will assume some familiar names, but you can fully customize them. After this guide, our basic structure should look like this:

  • apps - Contains multiple projects, including React Native apps.
  • packages - Contains different packages used by our apps.
  • package.json - Root package file, containing Yarn workspaces config.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published