Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing typescript code between two projects in a monorepo with yarn 2 workspaces

I want to set up a project with a client part (react-app), a server part (express) and a shared library (utils) in typescript. I use yarn 2 workspaces and wanted to avoid using larna (if possible). Unfortunately, I have not been able to make it work since few days (and a lot of googling...). When trying to run the client app I receive the error:

Cannot find module 'utils' or its corresponding type declarations. TS2307

Does anybody know what I am doing wrong?

This is my project structure:

  • .yarn
  • packages
    • client (created with create-react-app)
    • utils (created with yarn tsc --init)
    • server
  • .pnp.js
  • .yarnrc.yml
  • package.json
  • yarn.lock

package.json (root):

{
  "private": true,
  "name": "monorepo with shared library and yarn 2 workspaces",
  "workspaces": [
    "packages/*"
  ],
  "scripts": {
    "client": "yarn workspace client start",
    "server": "yarn workspace server start",
    "prepare": "yarn workspace utils build"
  }
}

utils/package.json:

{
    "name": "utils",
    "private": true,
    "version": "1.0.0",
    "main": "dist/index.js",
    "types": "dist/index.d.ts",
    "files": [
        "dist"
    ],
    "devDependencies": {
        "@types/node": "^14.14.22",
        "@typescript-eslint/eslint-plugin": "^4.14.0",
        "@typescript-eslint/parser": "^4.14.0",
        "eslint": "^7.18.0",
        "eslint-config-prettier": "^7.2.0",
        "eslint-plugin-prettier": "^3.3.1",
        "prettier": "^2.2.1",
        "typescript": "^4.1.3"
    },
    "scripts": {
        "build": "tsc -b --verbose"
    }
}

utils/src/index.ts:

function test() {
    console.log("this is a function from the shared library ");
}

export = {
    test
}

client/package.json

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "@types/jest": "^26.0.15",
    "@types/node": "^12.0.0",
    "@types/react": "^16.9.53",
    "@types/react-dom": "^16.9.8",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-refresh": "^0.9.0",
    "react-scripts": "4.0.1",
    "typescript": "^4.0.3",
    "utils": "1.0.0",                 // also tried "utils": "workspace:packages/utils"
    "web-vitals": "^0.2.4"
  },
  "scripts": {
    "start": "react-scripts start --verbose",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "eslint-config-react-app": "^6.0.0"
  }
}

I added a simple import in the client/src/App.tsx for testing:

import React from "react";
import logo from "./logo.svg";
import "./App.css";
import shared from "utils";

...

Thank you!

like image 667
Thomas Dunkel Avatar asked Jan 25 '21 21:01

Thomas Dunkel


People also ask

What is a monorepo in JavaScript?

A monorepo refers to a project, in this case, a JavaScript project, that has more than one section of the code base. For example, you may have the following set up: Your JavaScript server has source code, but there’s an additional front end application that will be built and made available to users separately.

How do I run a yarn script from a specific project?

Yarn workspace must set private to true. In workspaces field you either explicitly list the path of projects or put all projects under a directory (said packages) then write as packages/* in workspaces field. You don't need cd into each project to run a script, simply run yarn workspace 'workspacename' 'scriptname' in project's root.

How to organize serveral highly coupled projects using yarn?

When you have serveral highly coupled projects which you want to organize them together, you can consider a monorepo. Yarn (1.x) provide the workspace feature to help you organize monorepo project. Hoist same dependecies to top level to avoid duplicate install. Upgrade dependencies is much more easier. Easy to run a same script for all projects.

What is yarn 2 and how does it work?

Yarn is a package manager that also provides developers a project management toolset. Now, Yarn 2 is now officially supported by Heroku, and Heroku developers are able to take advantage of leveraging zero-installs during their Node.js builds.


Video Answer


1 Answers

I got it working. 'yarn workspace client add utils' made the trick.

like image 97
Thomas Dunkel Avatar answered Oct 23 '22 05:10

Thomas Dunkel