— nodejs — 2 min read
Your dependencies can be linked together, which means that your workspaces can depend on one another while always using the most up-to-date code available. This is also a better mechanism than yarn link since it only affects your workspace tree rather than your whole system.
It allows you to setup multiple packages in such a way that you only need to run yarn install once to install all of them in a single pass.
I couldn't have phrased it better than the official documentation
Introduction video and hands on example https://youtu.be/C5j7TyzDfgo
Workspace facilitates using monorepo, there by allowing easy linking of dependency during development time.
I hope this tutorial serves as concise tutorial on yarn workspace as well as yarn cheatsheet.
Let's say you are building an application with a Web service (REST or something) and Web UI (React etc.). If both Web Service and Web UI have some common code, like email, phone validation, validating token etc. then we can abstract it as a library, but maintaining it across as a separate project is a development nightmare. Yarn workspace eases this out but allowing you to manage all the code in a single code repo. Let's see how.
To start off with a simple example, we create a utility project which has some util function like email validation, and getting current date. If we want to use this common utility across frontend as well as backend. We can abstract it as a separate library.
For this demo, in root example
folder
we add myutil
, web
and api
as sub-folder
1mkdir -p example/{myutil,api}2cd example
Next up initialize nodejs project.
1yarn init -y
Update package.json
with following
1"private": true,2"workspaces": ["myutil", "api", "web"]
Next up run yarn init -y
in myutil
and api
this should create package.json
in both the folders
At this point of time tree
should look like
1.2├── api3│ └── package.json4├── package.json5├── myutil6│ ├── index.js7│ └── package.json8└── yarn.lock
Follow this up by creating a simple function to
validate email in myutil
, since this is a utility
project that we want to share across multiple app.
1const emailRegex = new RegExp("[a-z0-9]+@[a-z]+.[a-z]{2,3}");2
3function validateEmail(email) {4 return emailRegex.test(email);5}6
7exports.validateEmail = validateEmail;
Since we would use validateEmail
in api
let's add
this as a dependency in api
This would update api/package.json
with myutil
as a dependency
1--- a/api/package.json2+++ b/api/package.json3@@ -2,5 +2,8 @@4 "name": "api",5 "version": "1.0.0",6 "main": "index.js",7- "license": "MIT"8+ "license": "MIT",9+ "dependencies": {10+ "myutil": "1.0.0"11+ }12 }
Now let's add express as a dependency to api
1yarn workspace api add express
Add api/index.js
and build a simple Express app
1const express = require("express");2const app = express();3
4const { validateEmail } = require("myutil");5
6const port = process.env.PORT || 3000;7
8app.get("/validateEmail", (req, res) => {9 const { email } = req.query;10 res.json({ valid: validateEmail(email) });11});12
13app.listen(port, () => {14 console.log(`Listening at ${port}`);15});
Start API server
1yarn workspace api start
This finishes basic workspace setup but let's take it a step further by creating a react front end.
in packages
folder
1yarn create react-app web
1import "./App.css";2
3import { validateEmail } from "myutil";4import { useState } from "react";5
6function App() {7 const [valid, setValid] = useState(false);8 return (9 <div className="App">10 <header>11 <h1>Demo App</h1>12 </header>13 <main>14 <hr />15 <h3>Enter Email</h3>16 <input17 placeholder="enter email"18 onChange={(e) => {19 setValid(validateEmail(e.currentTarget.value));20 }}21 />22 {valid && <h3>Email is valid</h3>}23 </main>24 </div>25 );26}27
28export default App;
If possible have projects in a single folder and glob them.
For example use packages/*
So have projects in packages
folder
1mkdir -p example_2/packages/{myutil,api}
and configure root package.json
as below
1"workspaces": ["packages/*"],
add api/index.js
and myutil/index.js
1mkdir -p packages/mycomponents2cd packages/mycomponents3yarn init -y4yarn workspace mycomponents add -D react typescript @types/react