Reputation: 2337
I've set up a monorepo using yarn workspaces for a typescript Node.JS project. Building the project works fine, however, I'm running into issues during local development.
I need to manually run yarn build
before running yarn dev
. Otherwise I'm receiving the following error:
Error: Cannot find module '/Users/benedikt/code/monorepo-build/node_modules/@bhirmer/utils/dist/index.js'. Please verify that the package.json has a valid "main" entry
Here's the sample repo that reproduces the issue.
Alternatively, the important files.
packages/
utils
services/
api
{
"name": "@bhirmer/monorepo",
"description": "Workspace",
"private": true,
"workspaces": [
"packages/*",
"services/*"
],
"scripts": {},
"devDependencies": {
"eslint": "~7.14.0",
"typescript": "^4.0.5"
}
}
{
"compilerOptions": {
"module": "commonjs",
"target": "ES2015",
"lib": ["ES2019", "dom"],
"types": ["node"],
"esModuleInterop": true,
"skipLibCheck": true,
"sourceMap": true,
"noEmitOnError": true,
"allowUmdGlobalAccess": true,
"allowJs": false,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": false,
"moduleResolution": "node",
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noImplicitThis": true,
"strictNullChecks": true,
"noImplicitReturns": true,
"preserveConstEnums": true,
"suppressImplicitAnyIndexErrors": true,
"composite": true,
"baseUrl": "../..",
"paths": {
"@bhirmer/*": ["packages/*/src"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
{
"name": "@bhirmer/utils",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "yarn run clean && yarn run compile",
"clean": "rimraf ./dist && rimraf ./tsconfig.buildinfo",
"compile": "tsc --build",
"test": "yarn run build"
},
"dependencies": {
"@types/node": "^14.14.12"
},
"devDependencies": {},
"sideEffects": false
}
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": "../../",
"rootDir": "./src",
"outDir": "./dist",
"composite": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
{
"name": "@bhirmer/api",
"description": "api",
"author": "Benedikt Hirmer <[email protected]",
"license": "UNLICENSED",
"private": true,
"version": "1.0.0",
"main": "server/index",
"scripts": {
"dev": "PROJECT_ID=test-dev PORT=3010 nodemon src/server/index.ts",
"clean": "rimraf ./dist",
"compile": "NODE_ENV=production tsc --build",
"build": "yarn run compile",
"start": "PROJECT_ID=test-prod NODE_ENV=production node dist/server/index.js",
},
"dependencies": {
"@bhirmer/utils": "^1.0.0",
"@types/compression": "^1.7.0",
"@types/express": "^4.17.11",
"@types/node": "^14.14.12",
"compression": "^1.7.4",
"express": "^4.17.1",
"typescript": "^4.2.4"
},
"devDependencies": {
"nodemon": "^2.0.7",
"ts-node": "^9.1.1"
}
}
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"baseUrl": "../../",
// "rootDir": "src", // Getting `TypeError: src/server/index.ts: Emit skipped` if not commented out
"composite": true
},
"include": ["src/**/*"],
"types": ["typePatches"],
"references": [{ "path": "../../packages/utils" }]
}
import { getProjectID } from '@bhirmer/utils';
...
const projectID = getProjectID();
...
Another point to note is that once I set "rootDir": "src"
in services/api/tsconfig.json
, then I'm hitting the following error:
TypeError: src/server/index.ts: Emit skipped
if not commented out
Upvotes: 5
Views: 17689
Reputation: 2533
Recently had this issue, this was the fix for us:
"ts-node": {
"require": ["tsconfig-paths/register"]
},
For ts-node to see other monorepo packages it needed this entry
Upvotes: 0
Reputation: 469
NPM workspaces still need you to run npm install
inside the root directory (where the package.json with workspaces definition/location is), in order to make relevant symlinks to local packages.
When you do that, you should end up with:
node_modules/
@bhirmer/
utils/ <-- symlink to /packages/utils/
api/ <-- symlink to /services/api/
packages/
utils/
...
services/
api/
...
package.json <-- root package.json with "workspaces"
You'll have to re-run it every time you make a new local package folder with package.json inside, that you want to access from elsewhere.
Upvotes: 1