loading...
Cover image for How to insert an Expo project in a Monorepo
Expo Lovers ♥️

How to insert an Expo project in a Monorepo

mauriciord profile image Maurício R Duarte Updated on ・3 min read

Introduction

In this post, I'll cover about adding an Expo project inside a Monorepo project. I found on the internet so many people trying to do this, asking in some forums, or commenting something like "+1" at the Github issues. So, the purpose of this post is not to teach how to create a monorepo, is how to insert your Expo application inside a Monorepo.

Of course, you could help me by liking "+1" in this post.

Monorepo

I won't go deep in Monorepo's explanation, but basically, is an architectural concept. Instead of a lot of individual repositories, you keep all your isolated code parts inside one repository. It's very different from the monolithic repo.

Good examples and inspirations with Monorepo are:

After you understand the main monorepo structure, you start to see a lot of famous libraries that you or your team use that is Monorepo.

https://media.giphy.com/media/lJ0JGfNBrRWJVCRChd/giphy.gif

Let's get to work

First of all, you must create an Expo project (of course, if you haven't already created one) in some folder. To do this is simple like:

    # Install the command line tools
    # npm install --global expo-cli or
    # yarn global add expo-cli

    # ~/workspace

    # Create a new project
    expo init my-project

More info: https://docs.expo.io/versions/v37.0.0/

You can overwrite my-project with your the name of your choice (mine is expo-app), then select Blank Template (Managed).

So, move this Expo project folder inside the Monorepo folder:

    # ~/workspace
    mv expo-app monorepo/packages/expo-app

Now, the Expo project is inside the Monorepo. But, we need to adjust some things to be able to run Expo inside this Monorepo.

We need to set the package name at Expo project package.json :

    // ~/workspace/monorepo/packages/expo-app/package.json
    {
      "name": "@monorepo/expo-app",
      "main": "__generated__/AppEntry.js",
      // ...
    }

The "main" key is a special configuration from Expo, so we really need to set that.

After that, let's add two essential libraries to make our Expo project work. At the monorepo root folder, run this command:

    yarn workspace @monorepo/expo-app add expo-yarn-workspaces metro-config -D -W

Flags:

  • -W: Adds the libraries on the root
  • -D: The same as —-dev to add as devDependencies

Metro config

Let's configure our Metro, so create a file metro.config.js at monorepo/packages/expo-app:

    // ~/workspace/monorepo/packages/expo-app/metro.config.js

    const { createMetroConfiguration } = require('expo-yarn-workspaces');

    module.exports = createMetroConfiguration(__dirname);

So, we need to set insert some scripts at package.json again:

    // ~/workspace/monorepo/packages/expo-app/package.json

    {
      "name": "@monorepo/expo-app",
      "main": "__generated__/AppEntry.js",
      // ...
      "scripts": {
        // ...
        "postinstall": "expo-yarn-workspaces postinstall",
      },
    }

Extra configuration :: Typescript

If you don't want to add Typescript, you can skip this section.

Probably your monorepo root folder should contain a tsconfig.json, so let's add one to the Expo App package and extend the configuration on the root.

    // ~/workspace/monorepo/packages/expo-app/tsconfig.json

    {
      "extends": "../../tsconfig.json",
      "compilerOptions": {
        "allowSyntheticDefaultImports": true,
        "esModuleInterop": true,
        "experimentalDecorators": true,
        "forceConsistentCasingInFileNames": true,
        "importHelpers": true,
        "jsx": "react-native",
        "lib": ["dom", "esnext"],
        "moduleResolution": "node",
        "noFallthroughCasesInSwitch": true,
        "noEmit": true,
        "noEmitHelpers": true,
        "noImplicitReturns": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "skipLibCheck": true,
        "strict": true,
        "target": "esnext",
        "allowJs": true,
        "baseUrl": ".",
        // autocomplete paths
        "paths": {
          "*": ["src/*", "assets/*"],
          "assets/*": ["assets/*"]
        },
        "removeComments": true,
        "typeRoots": ["node_modules/@types", "./src/@types"]
      },
      "include": ["src"],
      "exclude": [
        "node_modules",
        "./node_modules",
        "./node_modules/*"
      ]
    }

You don't need to use "extends" key if your monorepeo doesn't contain a TS config yet.

Last step

To start building your product, you should clean/reset your monorepo project, because of the "postinstall" script inside the expo app package.

You can remove all node_modules or something like yarn --force on the root folder.

After that, you should run yarn install again, and you'll be able to develop & build your great product using Expo universal Apps :-]

References

You can look at my merged PR inserting an Expo Managed Workflow inside a Monorepo here.

Whats next?

  • Expo - Bare Workflow inside a Monorepo
  • Relay Client to use GraphQL
  • Or you can comment something to do with Expo

Thank you. \o/

Discussion

pic
Editor guide
Collapse
vpicone profile image
Vince Picone

This was super helpful thank you! One point of confusion for the dependencies. If you're adding it to the root, you shouldn't need to specify a workspace right? Also I don't the the metro-config dep is necessary.

So this:

 yarn workspace @monorepo/expo-app add expo-yarn-workspaces metro-config -D -W

Could be:

   yarn workspace add -D -W expo-yarn-workspaces
Collapse
albertgao profile image
AlbertGao

AlbertGao@Albert-LottoNZ-Laptop monorepo % pwd
/Users/AlbertGao/codes/teamingCloud/workspace/monorepo
AlbertGao@Albert-LottoNZ-Laptop monorepo % yarn workspace @monorepo/universal add expo-yarn-workspaces metro-config -D -W
yarn workspace v1.22.4
error Cannot find the root of your workspace - are you sure you're currently in a workspace?
info Visit yarnpkg.com/en/docs/cli/workspace for documentation about this command.
AlbertGao@Albert-LottoNZ-Laptop monorepo %

Thanks for the post!
Stuck at the 1st step... Anything I am missing?

Collapse
mauriciord profile image
Maurício R Duarte Author

As the error says, are you in a workspace?

// /Users/AlbertGao/codes/teamingCloud/workspace/monorepo/package.json

{
  "name": "monorepo",
   // ...
  "workspaces": {
    "packages": [
      "packages/*"
    ]
  },
Collapse
albertgao profile image
AlbertGao

Thanks! I wondered why there is no such creating step in the blog, then I thought yarn might magic figure it out, haha was wrong.

I ended up following the official yarn doc to create a workspace, and make sure it is working, then I followed the 2nd part of this blog to add the expo support, all good now!

Thanks! :)

Thread Thread
mauriciord profile image
Maurício R Duarte Author

Thank you! I'll edit this post and write a link how to config an monorepo.

Collapse
jeloagnasin profile image
jeloagnasin

How do we setup for a bare workflow?