monorepo-utils icon indicating copy to clipboard operation
monorepo-utils copied to clipboard

`workspaces-to-typescript-project-references` does not handle references to config files correctly

Open suin opened this issue 8 months ago • 2 comments

The path property of each reference in a TypeScript project can point to a directory containing a tsconfig.json file or directly to the config file itself (which may have any name).

The path property of each reference can point to a directory containing a tsconfig.json file, or to the config file itself (which may have any name). -- TypeScript Handbook

I am reporting an issue where workspaces-to-typescript-project-references does not work as expected in this context.

Consider a monorepo with the following structure:

.
├── package.json
└── packages
    ├── a
    │   ├── package.json
    │   ├── tsconfig.json
    │   └── tsconfig.types.json
    ├── b
    │   ├── package.json
    │   ├── tsconfig.json
    │   └── tsconfig.types.json
    └── c
        ├── package.json
        ├── tsconfig.json
        └── tsconfig.types.json

Focusing on the a package:

packages/a/tsconfig.json:

{
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "lib"
  },
  "references": [
    {
      "path": "./tsconfig.types.json"
    }
  ]
}

This configuration file emits JavaScript code to the lib directory.

packages/a/tsconfig.types.json:

{
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "types",
    "composite": true,
    "emitDeclarationOnly": true
  }
}

This configuration file emits TypeScript declaration files to the types directory.

The relationship between these two files is expressed using project references:

graph LR;
tsconfig.json -->|references| tsconfig.types.json;

Therefore, running tsc -b in the a package should compile both tsconfig.json and the referenced tsconfig.types.json, emitting files to the lib and types directories, respectively.

While specifying the config file in the path property may not be common, tools like moonrepo consider this approach as a valid use case, as described here.

For the entire monorepo, the relationship between the config files is as follows:

graph TB;
subgraph /packages/a
a/tsconfig.json("tsconfig.json")
a/tsconfig.types.json("tsconfig.types.json")
end
subgraph /packages/b
b/tsconfig.json("tsconfig.json")
b/tsconfig.types.json("tsconfig.types.json")
end
subgraph /packages/c
c/tsconfig.json("tsconfig.json")
c/tsconfig.types.json("tsconfig.types.json")
end
a/tsconfig.json -->|references| a/tsconfig.types.json;
b/tsconfig.json -->|references| /packages/a;
b/tsconfig.json -->|references| b/tsconfig.types.json;
c/tsconfig.json -->|references| /packages/a;
c/tsconfig.json -->|references| /packages/b;
c/tsconfig.json -->|references| c/tsconfig.types.json;

For the complete code, please refer to this repository: https://github.com/suinplayground/monorepo-utils-1/tree/master/packages/%40monorepo-utils/workspaces-to-typescript-project-references/test/fixtures/yarn-workspaces-pointing-to-config-file

In this monorepo structure, I found that using workspaces-to-typescript-project-references results in references to tsconfig.types.json being removed:

 Error: [packages/a] Expected values to be strictly deep-equal:
 + actual - expected
+ [
+   {
+     path: './tsconfig.types.json'
+   }
+ ]

 Error: [packages/b] Expected values to be strictly deep-equal:
 + actual - expected
    [
    {
        path: '../a'
+   },
+   {
+     path: './tsconfig.types.json'
    }
    ]

 Error: [packages/c] Expected values to be strictly deep-equal:
 + actual - expected ... Lines skipped
    [
    {
...
    {
        path: '../b'
+   },
+   {
+     path: './tsconfig.types.json'
    }

 workspaces-to-typescript-project-references found 3 errors.
 Please update your tsconfig.json via following command.
 $ workspaces-to-typescript-project-references

See the full error log here: https://github.com/suinplayground/monorepo-utils-1/actions/runs/9474724661/job/26104870429#step:6:60

The expected outcome is that references to tsconfig.types.json within the same package remain intact, while only inter-package references are managed.

I would appreciate it if this issue could be resolved. Thank you for your attention to this matter.

suin avatar Jun 12 '24 01:06 suin