Whenever you are ready to write a new project, have you ever thought about whether you need to manage the front and back-end code with different git repositories, or whether you need to split some relatively low-level code into a separate git repository, so that when the low-level code is stable, you can directly release it as a separate npm package for the project.

So wouldn’t this be a straightforward way to manage the project with a different git repository? It’s true, but if different projects are in different git repositories, it’s not particularly convenient when I have to look up some code in another project, so I’d like to have all the relevant packages in one git repository.

I’ve often struggled with this before and have looked up a lot of information about it. Today, I’m documenting a way I often manage my code - yarn workspace.

What is yarn workspace?

yarn workspace allows a single git repository to contain multiple packages; for example, if you have a front-end project and a back-end project, you can manage both packages through yarn workspace.

The packages are independent of each other, and can be a complete standalone project even if they are separated from the main repository.

React makes use of the yarn workspace mechanism.

Practice

  1. Create project files

    Create a new folder example-monorepo.

    1
    
    $ mkdir example-monorepo
    

    Create package.json in the example-monorepo folder.

    1
    2
    
    $ cd example-monorepo
    $ touch package.json
    

    Type the following in package.json.

    1
    2
    3
    4
    5
    6
    
    {
    "private": true,
    "name": "example-monorepo",
    "workspaces": [],
    "scripts": {}
    }
    
  2. Create a react project and add it to the workspace list

    Create a packages folder in the project to store the different subprojects.

    1
    
    $ mkdir packages
    

    Create the react project.

    1
    
    $ yarn create-react-app packages/client
    

    Tell Yarn to treat client as workspace. We just need to add client to the list of workspaces in the package.json file.

    1
    2
    3
    4
    5
    6
    
    {
    "private": true,
    "name": "example-monorepo",
    "workspaces": ["client"],
    "scripts": {}
    }
    
  3. Create an express project and add it to the workspace list

    After creating the front-end project, let’s create an express back-end project, first installing express-generator.

    1
    
    $ yarn global add express-generator --prefix /usr/local
    

    Create an express project using express-generator.

    1
    
    $ express --view=pug packages/server
    

    Also add server to the workspace.

    1
    2
    3
    4
    5
    6
    
    {
    "private": true,
    "name": "example-monorepo",
    "workspaces": ["client", "server"],
    "scripts": {}
    }
    
  4. Installing dependencies

    To install the dependencies needed to run, we just need to execute the yarn install command in the root of the project and yarn will automatically install the dependencies for all packages.

    1
    
    $ yarn install
    

    This command generates a yarn.lock file that contains all the dependency information for running the project. This file is generated automatically and should not be modified manually.

  5. Use (*) to import all packages

    The workspace supports * to match packages of any name, so you can change the workspace to the following.

    1
    2
    3
    4
    5
    6
    
    {
    "private": true,
    "name": "example-monorepo",
    "workspaces": ["packages/*"],
    "scripts": {}
    }
    
  6. Run all packages

    Use concurrently to run multiple script commands in parallel.

    1
    
    yarn add -W concurrently
    

    Change the package.json to the following.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    {
    "private": true,
    "name": "example-monorepo",
    "workspaces": ["packages/*"],
    "scripts": {
        "client": "yarn workspace client start",
        "server": "yarn workspace server start",
        "start": "concurrently --kill-others-on-fail \"yarn server\"  \"yarn client\"
    }
    }
    

    The commands in the package can be executed via the yarn workspace <package> <script>.

    Finally run the project.

    1
    
    $ yarn start
    

Ref

  • https://pengfeixc.com/blogs/javascript/yarn-workspace