Setup Monorepo via Yarn workspace for Serverless Framework and Expo with Typescript
I created a universal app with Expo for native mobile and web. It works wonderfully. I think a monorepo for local code sharing should efficient than publishing to a private package to Github registry (It works like a charm though).
I thought it’s just a 5 min setup. But I was wrong… Still very easy though. In this blog, we will use monorepo to share code between the backend(Serverless framework) and frontend(Expo).
I always try my best to introduce less overhead and less dependencies to solve a problem.
Our goals
Yarn
only withoutlerna
: Less overhead. And We do not needlerna
- Yarn version:
v1.22.4
- Typescript support for all three modules
- I just want to focus on coding without worrying about building pipeline
- No no no, no Babel, that’ll introduce loads of dev-dependencies, I want a clean tree.
- I will show you how to use as well
1. Big picture
The project contains 3 parts:
- Frontend:
- Backend:
- Typescript
- AWS Lambda / Cognito
- framework: Serverless framework
- building: just
tsc
- Code sharing:
- Typescript
- building: tsdx
tsdx
is a zero config CLI for Typescript written via the author of formik, Jared Palmer.
This is the final folder structure.
1 | --monorepo |
There is no packages
as you see, because we are not using lerna
, and I am really want less nesting.
2. Setup
- Creating the
monorepo
folder - Put the following
package.json
file into the folder:
1 | { |
3. Manage the shared
modules
1 | ## from ./monorepo |
Choose template: basic
Open the ./monorepo/shared/package.json
, update the following properties
1 | { |
4. Manage the serverless
part
1 | # from ./monorepo |
In the ./monorepo/serverless/package.json
1 | { |
There is a problem with this monorepo approach, is the some packages will be hoisted to the
./monorepo
levelnode_modules
, which will cause Serverless framework not included them in the final.zip
file.serverless-plugin-monorepo
is for solving this problem without disabling the hoisting feature from Yarn workspace.
Add this to your serverless.yml
1 | plugins: |
Also in serverless.yml
, update this:
1 | functions: |
to
1 | functions: |
We will point to the final transpiled code directly.
Let’s add the ./monorepo/serverless/tsconfig.json
1 | { |
I am using Node 12, so I compile to ES2019
which has very less overheads. Change it if you are using a different node version. You can find this information from the official Typescript repo.
5. Manage the Expo
part
1 | ## from ./monorepo |
Select the [Managed] Blank Typescript
template,
give it a name universal
Update ./monorepo/universal/package.json
:
1 | { |
Update the ./monorepo/universal/app.json
:
1 | "packagerOpts": { |
Create a file named metro.config.js
under ./monorepo/universal/
1 | const { createMetroConfiguration } = require("expo-yarn-workspaces"); |
6. Tidy up
Removing all node_modules
in the 3 sub-folders if has.
1 | ## from ./monorepo |
Not everything has been setup.
You are good to go!
7. How to use
How to consume the code in shared
module
- Import code like this
import {sum} from '@monorepo/shared'
- Any updates to
@monorepo/shared
, run the commandyarn build
under that./monorepo/shared
oryarn workspace @monorepo/shared build
How to add dependencies to one of the modules
yarn workspace @monorepo/universal add BLAH
8. End.
I had a problem with one of the dependencies not get the updated version even after I running with clearing the cache expo start -c
, the solution is expo update
, but that takes too long. So I want to setup a monorepo. It turns out works pretty well.
One thing I’d like to have but do not have time to figure it out is: in @monorepo/shared/package.json
, change main
to ./src/index.ts
, then in Expo
, you can instantly get any code changes without building, which means, we are referring to the source code. But I do not know how to get it working with @monorepo/serverless
, the import {A} from '@monorepo/shared'
will be transpiled to const A = require('@monorepo/shared')
. And of course, @monorepo/shared
is not been brought and transpiled. If you know how to solve it, please let me know.
That’s all, hope it helps!
Follow me (albertgao) on twitter, if you want to hear more about my interesting ideas.