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:
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!
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.
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.
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.
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.
I got it working. 'yarn workspace client add utils' made the trick.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With