TypeScript: Error: Cannot find module when using paths

Aaron Nebbs picture Aaron Nebbs · Jul 18, 2019 · Viewed 7.2k times · Source

I have a monorepo containing the Back-end(NodeJS), Front-end(Angular) and Shared directory (container models shared by the front-end and back-end.)

preagree-mono/
   preagree-api/
   preagree-app/
   preagree-shared/

The angular app is working perfectly and being build correctly using the shared types, after adding the folder into the paths

preagree-app/tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "src",
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "lib": ["es2018", "dom"],
    "module": "es2015",
    "moduleResolution": "node",
    "outDir": "./dist/out-tsc",
    "paths": {
      "@preagree/*": ["@preagree/*"],
      "@preagree-shared/*": ["../../preagree-shared/*"]
    },
    "sourceMap": true,
    "strictNullChecks": false,
    "target": "es6",
    "typeRoots": ["../node_modules/@types"],
    "types": ["node"]
  }
}

However the API is not compiling correctly. PHPStorm is picking up the types correctly and importing them from the shared folder, but when i go to build i get...

$ tsc && PRODUCTION=false node ./build/preagree-api/app/app.js
internal/modules/cjs/loader.js:613
    throw err;
    ^

Error: Cannot find module '@preagree-shared/models/preagree-http'
Require stack:
- /home/nebbsie/preagree-mono/preagree-api/build/preagree-api/app/utils/responses/generic/error-response.js
- /home/nebbsie/preagree-mono/preagree-api/build/preagree-api/app/utils/responses/index.js
- /home/nebbsie/preagree-mono/preagree-api/build/preagree-api/app/preagree/users/users.route.js
- /home/nebbsie/preagree-mono/preagree-api/build/preagree-api/app/preagree/users/index.js
- /home/nebbsie/preagree-mono/preagree-api/build/preagree-api/app/routes/index.js
- /home/nebbsie/preagree-mono/preagree-api/build/preagree-api/app/app.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:610:15)
    at Function.Module._load (internal/modules/cjs/loader.js:526:27)
    at Module.require (internal/modules/cjs/loader.js:666:19)
    at require (internal/modules/cjs/helpers.js:16:16)
    at Object.<anonymous> (/home/nebbsie/preagree-mono/preagree-api/build/preagree-api/app/utils/responses/generic/error-response.js:4:25)
    at Module._compile (internal/modules/cjs/loader.js:759:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:770:10)
    at Module.load (internal/modules/cjs/loader.js:628:32)
    at Function.Module._load (internal/modules/cjs/loader.js:555:12)
    at Module.require (internal/modules/cjs/loader.js:666:19)
error Command failed with exit code 1.

Here is the tsconfig for the API. preagree-api/tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./app",
    "module": "commonjs",
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": false,
    "moduleResolution": "node",
    "outDir": "build",
    "noResolve": false,
    "paths": {
      "@preagree/*": ["@preagree/*"],
      "@preagree-shared/*": ["../../preagree-shared/*"]
    },
    "target": "es6",
    "types": ["node"],
    "typeRoots": ["../node_modules/@types"]
  },
  "exclude": ["node_modules", ".vscode"],
  "include": ["app/**/*"]
}

The strange thing is i created a quick test file that imports from the shared file (in the same folder as the API). This build and runs.

import { UsersUpdatePayload } from '@preagree-shared/models/users';

const users: UsersUpdatePayload = { lastName: 'Aaron' };

console.log(users);

Answer

Aaron Nebbs picture Aaron Nebbs · Jul 18, 2019

Right i carried on looking into this and i found a way to fix my issue. Here is the link, it explains it well too.

https://dev.to/larswaechter/path-aliases-with-typescript-in-nodejs-4353