Shared library in yarn workspaces
Tags: react, javascript, yarn
Published: 2021-08-24 11:03:33

##Introduction

Recently, I wrote and article about setting up yarn workspaces and adding Docker support to it for orchestration. 
> You can read it here [Docker setup for yarn workspaces](https://dev.to/sidv93/docker-setup-for-yarn-workspaces-4pnj)

I thought we can extend this setup to include a library as well. Shared libraries are fairly common in any organisation, so we'll be adding a component library based on React to our workspace.

To go over our setup, we have an `apps` folder where all our apps live in. We have two apps called `admin` and `product`. We are going to be adding a component library to this setup and this library will be used by both of our apps. Let's get started.

## Adding a library
I'm going to be using [Vite](https://vitejs.dev/) as our build tool. It has a nice cli which lets us scaffold an application easily. 
To create a vite project in our `apps`directory,

```
cd apps
yarn create vite lib --template react
```
Our `lib` folder would look something like this now
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lgowzzcen0vl70hc8wb8.png)


The next step is to update our dependencies by running `yarn install` from the root of our workspace.

### Adding components to our library

If we open the `src` folder in `lib`, we can see that it is an ideal setup for an application, not a library. So, we'll remove all the files from `src` and `index.html` and add our own.

First, we'll add an entry file called `index.js` in `src`. This will be the starting point file in our bundling process.

Next, we'll create a folder called `components` which would house all our components, and add an `index.js` file to it as well. We'll export all our component from this index file.

Our project should look like this now.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rgf0vr5msy779hbh30fm.png)


#### Adding a button component
Great! We have our directory setup nailed down. We can finally start adding components. We can add a simple button component. I'm going to create a directory called `Button` in `components` directory, which would contain three files. `Button.jsx`, `Button.css` and an `index.js`.
Let's add the contents of each of these files

`Button.jsx`
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qjba15gapkoa6vk21s3n.png)

`Button.css`
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/798umb3993ka4bdinmtn.png)

`index.js`
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/34crjymbhlf11r9yvf9x.png)

This is a very simple component with not a lot of emphasis on styling and attributes. You can customise this component to your liking.

We have a component exported from our `Button` directory. We need to export this component from our `components` directory as well. We'll add this export like this

`src/components/index.js`
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wqvhl7ec6336pjpy2nu.png)

The next step is to export the components from our `src`.
`src/index.js`
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/agp521u55msosv1ruepm.png)
 

This would export all our exports from `components` directory. If we add more components, all of them would be exported from here. 

Our `lib` folder should look like this now
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hjtrbor42wf8c1h6yws5.png)

####Finetuning Vite config

Before we can start using our library in applications, we need to modify our `vite.config.js` to let vite know this is a library and should be bundled as one.
The documentation for this can be found [here](https://vitejs.dev/guide/build.html#library-mode)
We'll be adding the following config to `vite.config.js`

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0rl84kv097xygov0n0hk.png)

We also need to add some options to our lib's `package.json`.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yv3khe3u7qr7u5ta3ozl.png)

The `peerDependencies` option tells the bundler not to add these dependencies in our final bundle. 
The `main`, `module` and `exports` options are needed for the application's bundler to figure out where the files are for `umd` and `esm` formats.  

Great! Let's now move on to using library in our apps.

### Using our library in apps

Adding a local library as a dependency is as simple as adding any other dependency.
```
yarn workspace admin add lib@0.1.0
```
This command would add `lib` as a dependency to `admin`. Notice we've mentioned the version of lib as well. This version must be the same as the `version` property in `package.json` in `lib`.

Another way is to simply add `lib: 0.1.0` entry to the `dependencies` section of `package.json` in admin.

### Testing it out

We are now in a position to use our `Button` component from lib. We'll do that in `App.jsx` in admin

`admin/src/App.js`
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3uo8ud73c60rssir92is.png)


Next step is to alter our scripts in `package.json` to make sure our library is compiled when we run our applications.
We'll add a few scripts to do this

`package.json` 

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3kutau29l56d6ulvqyq5.png)

Awesome! We're almost done. Only thing left to do is to check our admin app.

```
yarn start:admin
```
If we open `http://localhost:3000` on our browser, we can see our `Button` component in red color as per our `type` prop.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/phpfrvy8pe5tgiaeic11.png)

We can repeat the same process to use the library in any other application in the workspace.
 

##Conclusion

Awesome! We have a yarn workspace with two applications and a component library in React. We can extend this idea and even add multiple libraries into this workspace.

> If you are interested in setting up a React-Typescrippt component library from scratch, check out my article here [Component library setup with React, TypeScript and Rollup](https://dev.to/sidv93/component-library-setup-with-react-typescript-and-rollup-onj)

The source code for this can be found [here](https://github.com/sidv93/yarn-worspace-docker)

Cheers!