I'm having some trouble with nodemon
in a yarn monorepo structure. I can't use nodemon src/index.ts
in my api
package, because it requires functions, enums, and the prisma instance from the orm
package, whose package.json
points to a dist/index.js
file using the main
field of its package.json
.
I have the following repo structure:
packages/
api
cli
orm
api
is an Express.js REST API application.cli
is a CLI toolorm
is a prisma wrapper for communicating with the dbThe error message I'm getting is the following:
repo-name/node_modules/ts-node/src/index.ts:859
return new TSError(diagnosticText, diagnosticCodes, diagnostics);
^
TSError: ⨯ Unable to compile TypeScript:
src/controllers/_common/auth.controller.ts:13:3 - error TS2305: Module '"@project/orm"' has no exported member 'logActivity'.
13 logActivity,
~~~~~~~~~~~
src/controllers/_common/auth.controller.ts:14:3 - error TS2305: Module '"@project/orm"' has no exported member 'comparePasswords'.
14 comparePasswords,
~~~~~~~~~~~~~~~~
src/controllers/_common/auth.controller.ts:15:3 - error TS2305: Module '"@project/orm"' has no exported member 'SysActionsEnum'.
15 SysActionsEnum,
~~~~~~~~~~~~~~
src/controllers/_common/auth.controller.ts:16:3 - error TS2305: Module '"@project/orm"' has no exported member 'SysResourcesEnum'.
16 SysResourcesEnum,
~~~~~~~~~~~~~~~~
at createTSError (/repo-name/node_modules/ts-node/src/index.ts:859:12)
at reportTSError (/repo-name/node_modules/ts-node/src/index.ts:863:19)
at getOutput (/repo-name/node_modules/ts-node/src/index.ts:1077:36)
at Object.compile (/repo-name/node_modules/ts-node/src/index.ts:1433:41)
at Module.m._compile (/repo-name/node_modules/ts-node/src/index.ts:1617:30)
at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
at Object.require.extensions.<computed> [as .ts] (/repo-name/node_modules/ts-node/src/index.ts:1621:12)
at Module.load (node:internal/modules/cjs/loader:1117:32)
at Function.Module._load (node:internal/modules/cjs/loader:958:12)
at Module.require (node:internal/modules/cjs/loader:1141:19) {
diagnosticCodes: [ 2305, 2305, 2305, 2305 ]
When I change the main
field of the orm
package.json
to src/index.ts
it works, because nodemon is able to handle .ts
files. Is there any way I can configure nodemon so it automatically uses the ts files in the required package instead of the compiled JavaScript?
Additional info:
packages/api/package.json
:
{
"name": "@project/api",
"version": "0.6.0",
"description": "Project API",
"license": "MIT",
"main": "src/app.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node dist/app.js",
"build": "tsc --project tsconfig.json",
"dev": "nodemon src/app.ts",
"prod": "set NODE_ENV=production&node dist/app.js"
},
"dependencies": {
...
},
"devDependencies":
"ts-node": "^10.9.1",
"typescript": "^5.0.4"
...
}
}
packages/api/tsconfig.json:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"rootDir": "./src",
"moduleResolution": "NodeNext",
"baseUrl": "./src",
"resolveJsonModule": true,
"allowJs": true,
"outDir": "./dist",
"removeComments": true,
"isolatedModules": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": false,
"skipLibCheck": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
packages/orm/package.json
:
{
"name": "@project/orm",
"version": "0.1.0",
"description": "project ORM",
"license": "MIT",
"main": "dist/index.js",
"scripts": {
"build": "tsc --project tsconfig.json",
"dev": "nodemon src/index.ts",
"studio": "dotenv -e ../../.env prisma studio",
"db:pull": "dotenv -e ../../.env prisma db pull",
"db:push": "dotenv -e ../../.env prisma db push",
"db:seed": "dotenv -e ../../.env prisma db seed",
"db:execute": "dotenv -e ../../.env prisma db execute",
"migrate:dev": "dotenv -e ../../.env prisma migrate dev",
"migrate:diff": "dotenv -e ../../.env prisma migrate diff",
"migrate:reset": "dotenv -e ../../.env prisma migrate reset",
"migrate:reset:force": "dotenv -e ../../.env prisma migrate reset -- --force",
"migrate:deploy": "dotenv -e ../../.env prisma migrate deploy",
"migrate:status": "dotenv -e ../../.env prisma migrate status",
"generate": "dotenv -e ../../.env prisma generate"
},
"dependencies": {
...
},
"devDependencies": {
...
"ts-node": "^10.9.1",
"typescript": "^5.0.4"
},
"prisma": {
"schema": "src/prisma/schema.prisma",
"seed": "ts-node src/prisma/seed.ts"
}
}
packages/orm/tsconfig.json:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"rootDir": "./src",
"moduleResolution": "NodeNext",
"baseUrl": "./src",
"resolveJsonModule": true,
"allowJs": false,
"outDir": "./dist",
"removeComments": true,
"isolatedModules": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": false,"skipLibCheck": true
},
"include": ["src/*.ts", "src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
Found the solution:
tsconfig-paths
and ts-node
as dev dependencies in all of my workspaces.{
"compilerOptions": {
"target": "ES6",
"module": "CommonJS",
"moduleResolution": "Node",
"esModuleInterop": true,
"removeComments": true,
"strict": false,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"@project/cli": ["./packages/cli/src/project.ts"],
"@project/orm": ["./packages/orm/src/index.ts"]
}
}
}
api
and orm
package:packages/api/tsconfig.json:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"baseUrl": "./src",
"outDir": "./dist",
"resolveJsonModule": true,
"isolatedModules": true
},
"include": ["src/*.ts", "src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
packages/orm/tsconfig.json:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"baseUrl": "./src",
"outDir": "./dist",
"declaration": true
},
"include": ["src/*.ts", "src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
They're both very similar and don't do much except set up the dirs.
"dev": "nodemon --exec ts-node --require tsconfig-paths/register packages/api/src/app.ts",
And that's it! Now the dev
script of the root package.json runs and uses the ts files of the orm package. It also restarts the process if I make changes to ts files of the orm package.