Lerna, yarn, and Typescript: Cannot find module or its corresponding type declarations
Asked Answered
S

1

15

I have a lerna + yarn workspaces monorepo, with independent versioning. I'm having trouble importing a package in its sibling.

I have two packages, one of which should depend on the other, as illustrated below:

(root)
  |--packages
       |--money
       |--money-standard-units
            |--{deps. on money}

Inside of money-standard-deps, I try to import an exported member of money but I'm unable to do so; I get the following message:

TS2307: Cannot find module 'money' or its corresponding type declarations.

I know this issue can be resolved by adding money to the paths array of money-standard-libs's tsconfig, but I want to depend on the built package as these will be published seperately. I want this to effectively work as-if it's two seperate repos.

I've created a demo repo.

Sybil answered 6/2, 2021 at 19:44 Comment(9)
As this is very common, more clarifications are needed ... maybe a small github repo?Shcherbakov
I thought that might be the case @gaitat. I've put a small example together and added the link to the question.Sybil
I cant really compile since there is no @somescope but maybe changing export * from './monetary-unit'; to export { MonetaryUnit } from './monetary-unit'; in money/src/index.tsShcherbakov
@Shcherbakov could you specify what you mean by "there's no @somescope"? If you mean this scope isn't registered on npmjs.com, then that's exactly the point; these packages should be linked to locally.Sybil
I only meant that this "dependencies": { "@somescope/money": "^0.0.0" } will not resolve.Shcherbakov
@gaitat, that's the issue I have. import statements in the money-standard-units package wont resolve. I get the error mentioned in the question.Sybil
So then this export { MonetaryUnit } from './monetary-unit'; did not work?Shcherbakov
Let us continue this discussion in chat.Sybil
its a pity the linked monorepo is removedTimetable
L
35

You will need to configure your typescript project to generate type declaration *.d.ts files if it is going to be used as a dependency of another typescript project. To do this, you will need to set the compilerOptions.declaration property of your tsconfig to true. You can do this in your tsconfig-common.json file.

For example (tsconfig-common.json):

{
  ...
  "declaration": true
  ...
}

Additionally, in the same way you specify a main property in your package.json file to identify the entry file for your package you will also need to specify a types property to specify where your type declaration file is located. You need to do this for every package in your monorepo.

For example (package.json):

{
  "name": "@somescope/money",
  ...
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  ...
}

Also, I noticed that you do a default export in your monetary-unit module, but then do a named import for it in the uses-money module.

You will need to change the monetary-unit module to use a named export on the class if you intend to refer to it using a named import.

Example (monetary-unit.ts):

// Remove the default keyword
export class MonetaryUnit {
  constructor(
    readonly value: number,
    readonly name: string,
  ) {}
}
Linettelineup answered 11/2, 2021 at 22:44 Comment(5)
Thanks for answering @JoshA. This absolutely solved the problem and the packages can now be imported correctly. Thanks for the help!Sybil
Glad I could help. If you think I was able to answer your question, it would be great if you could mark it as answered. :-)Linettelineup
Absolutely! I was busy for a few days and wanted to check this worked in practice, with a complex example. It all works fine, I've marked you as the answer (any given the bounty). Thanks again.Sybil
The solution works! But the answer is still not marked! :pSamadhi
One extra thing to check is that your package name is not the same as some public npm package. For instance, I had to change my local package name from auth to my-authVargas

© 2022 - 2024 — McMap. All rights reserved.