Yarn Workspaces - Monorepo Approach
Tags: react, reactnative, vue, angular
Published: 2021-07-16 04:03:29

See how Yarn Workspaces allow developers to develop [mobile](https://www.kpiteng.com/services/mobile-app-development) & [web applications](http://www.kpiteng.com/services/web-development) using monorepo approach, helps to split and share code between multiple packages.

Projects grow over time and some pieces of code can be useful elsewhere in other projects. Also we need to share code between projects like Redux, [ApolloClient](https://www.kpiteng.com/blogs/react-native-apollo-graphql), [MobX](https://www.kpiteng.com/blogs/mobx-state-tree) - State Management Library, Common Utilities, etc same for both React Native, React.js or other technologies.

>Download full source code from [KPITENG - Github](https://github.com/kpiteng/yarn-workspaces)

###Monorepos
Many of us tried splitting a code into multiple packages knowing how difficult it is to manage across multiple packages at one time. To make this easier, we adopted a monorepo approach, or multiple packages repositories, which reduce the burden of writing code across packages.

Many projects used by JavaScript developers are managed as monorepos like, Babel, [React](https://www.kpiteng.com/services/mobile-app-development/react-native-app-development), Jest, Vue, Angular.

###What is Yarn Workspaces?
[Yarn Workspaces](https://classic.yarnpkg.com/blog/2017/08/02/introducing-workspaces/) is a feature that allows users to install dependencies from multiple package.json files in subfolders of a single root package.json file. Let’s say you have React.js & React Native Application and both using Redux, instead of installing Redux into React Native Project and React.js Project, Yarn installs it to root node_modules to reduce the size of project, making it simpler for developers.

###Step By Step Integration


#####Set Up Yarn Workspaces -
Let’s create Project Folder Name - **YarnWorkspaces**

Create a file named package.json, Specify two things
```
{
   “private”: true,
   “workspaces”: [“common“, “app”, “web”, “server”]
}
```
Now, let's create folder directory
```
mkdir common
mkdir app
mkdir web
mkdir server
```
Now, let's jump into common folder
```
cd common
yarn init -y
```
Same way let’s go to server directory
```
cd server
yarn init -y
```
Go to common folder, Create file index.js
```
module.exports = () => {
   console.log("Hello from KPITENG");
}
```
Here, I have an export function which prints logs.

Now, let’s go to Server folder and create file index.js and paste following code,

```
const commonFunction = require('common');
commonFunction();
```
Now, let’s run this, but it will break because server doesn’t know common exists, to tell server we need to add dependency in server’s package.json
```
"dependencies": {
   "common": “1.0.0”
}
```
Now, let's do yarn install to link directory, Go to server directory and trigger,
```
yarn install
```
Now, let’s check our dependency are properly mapped, Go to root directory do,
```
> ls // It will print following folder hierarchy
common node_modules package.json server yarn.lock server

> ls node_modules // you can see common server directly inside it
common server
```
So, our dependency property links with workspaces, not let’s try our server/index.js
```
> node server/index.js // It will print following
Hello from KPITENG
```
If you want to change any message in common/index.js then it will automatically reflect using symlink

Let’s change common/index.js
```
module.exports = () => {
   console.log("Welcome to KPITENG");
}
```
And trigger,
```
> node server/index.js // It will print following
Welcome to KPITENG
```
#####Update Package Name - @sharecode
Till everything seems fine, Not it’s time to give a proper naming convention, Generally we prefer to append ProjectName/PackageName, In our case, lets change package name of common,

Go To - common/package.json

```
{
  - "name": "common",
  + "name": "@sharecode/common",
}    

```
Go To - common/package.json
```
{
    - "name": "server",
    + "name": "@sharecode/server"
      "dependencies": {
        - "common": "1.0.0"
        + "@sharecode/common": "1.0.0"
      }
}
```
Go To - server/index.js
```
- const commonFunction = require(“common”)
+ const commonFunction = require(“@sharecode/common”)
```
Now, let's do yarn install to update package
```
> yarn install
> node server/index.js // it will log following
Welcome to KPITENG
```
#####Managing Folder Structure / Hierarchy -
Now, you see our common server packages are inside main directory, Let’s shift it to folder packages, let’s create folder packages inside ReactShareCode,
```
> mkdir packages
```
And move common and server packages inside it.
```
mv common/ packages/commom/
mv server/ packages/server/
mv app/ packages/app/
```
We also need to change our package.json from main folder
```
{
  - "workspaces": ["common", "server"]
  + "workspaces": ["packages/**"]
}    
```
So, package will be changed, so let's rm node_modules and install again
```
> rm -rf node_modules
> cd packages/server
> rm -rf node_modules
> yarn install
```
It will install dependency again with update packages directory

Now, you can try,
```
> node packages/server/index.js // It will log following
Welcome to KPITENG
```
Now, If you want to install any dependency for your server packages
```
> cd packages/server
> yarn add graphql
```
It will install dependency in root node_modules and it will be added as dependency in server/package.json, It means node_module installed common / root node_modules. Let’s cross check it, Go to root directory
```
> ls
package.json node_modules
> ls node_modules // It will show graphql dependency
@sharecode graphql
```
It means there is one graphql package that will work for whole workspaces which is very nice in workspaces concept.

>Download full source code from [KPITENG - Github](https://github.com/kpiteng/yarn-workspaces)

###What Next?
Learn, [Share code between React Native & React.js using Yarn Workspace.](https://dev.to/kpiteng/share-code-between-react-native-and-react-js-50bj)

**Thanks for reading Blog!**

KPITENG | DIGITAL TRANSFORMATION
www.kpiteng.com/blogs | hello@kpiteng.com
Connect | Follow Us On - [Linkedin](https://www.linkedin.com/company/kpiteng/) | [Facebook](https://www.facebook.com/kpiteng) | [Instagram] (https://www.instagram.com/kpiteng)