Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getExportedDeclarations not working with yarn PnP #1168

Open
AlCalzone opened this issue Jun 27, 2021 · 5 comments
Open

getExportedDeclarations not working with yarn PnP #1168

AlCalzone opened this issue Jun 27, 2021 · 5 comments

Comments

@AlCalzone
Copy link

AlCalzone commented Jun 27, 2021

Describe the bug

Version: 11.0.0

I'm in the process of migrating a project to Yarn v3, including the Plug'n'Play functionality.

My project is structured as a TypeScript monorepo. The documentation is generated using ts-morph. Since the switch, that is failing, because getExportedDeclarations() is returning an empty array for re-exported types from another package of the monorepo. Many other types have become any.

I suspect this is because ts-morph is not compatible with Yarn PnP out of the box, but I'm not sure how to make it work to be honest.

To Reproduce

This is somewhat tricky to reproduce, but you can use my repo to do so.

  1. clone https://github.com/zwave-js/node-zwave-js
  2. check out commit eb20fcb
  3. run yarn add --dev ts-morph (so yarn PnP doesn't barf at you)
  4. create a file repro.ts with the following content in the root:
import { Project } from "ts-morph";

import { tsConfigFilePath } from "./packages/maintenance/src/tsAPITools";

const program = new Project({ tsConfigFilePath });

const file = program.getSourceFile("packages/zwave-js/src/index.ts");
const identifier = "ValueID";
const decl = file?.getExportedDeclarations().get(identifier);
debugger;
  1. run this in a debugging console: yarn node -r ts-node/register repro.ts

Expected behavior

decl should be an array with length 1, including the original symbol for ValueID.

@AlCalzone AlCalzone changed the title getExportedDeclarations not including re-exported types from external modules getExportedDeclarations not working with yarn PnP Jun 28, 2021
@AlCalzone
Copy link
Author

I was able to work around this for now by using yarn's patch protocol to require typescript from within ts-morph with the PnP API enabled:
5085a05 (#2913)

@sschultze
Copy link

I have this problem too after upgrading Yarn to the latest version and switching to the default PnP mode. @dsherret Is there an official solution on the horizon?

@sschultze
Copy link

It looks like this popular package can help. https://www.npmjs.com/package/ts-pnp

I wasn't able to figure out yet how to set ts-morphs Project.resolutionHost property to make use of this.

@jwoo0122
Copy link

jwoo0122 commented Jul 4, 2022

It seems like the way ts-morph imports typescript cannot be effected by yarn PnP api. From this comment ts-morph decided to include typescript bundle as hard-copy. Because yarn enables PnP by patching typescript, including typescript like this way (not by using package json - dependencies) ts-morph cannot be compatible with yarn pnp.

So patching @ts-morph/common is one of the fast workarounds. Just fix import statement(this is similar to what @AlCalzone did, details can be changed). You can use yarn patch, patch-package, or anything else.

// in ts-morph-common.js
const ts = require('./typescript') // this one point out hard-copied typescript
// change to
const ts = require('typescript') //

I'm not sure if ts-morph should change this behavior, to support yarn pnp. Anyway this kind of bundle process (hard copy typescript dist file) is not regular way as I know, so we should think about it (although the comment said there was a hell when ts-morph serves typescript as dependency)...? @dsherret

@SagnikPradhan
Copy link

Yeah like @jwoo0122 and @AlCalzone said, yarn patch protocol + redirecting the import works.
  1. Run yarn patch @ts-morph/common
  2. In <directory>/dist/ts-morph-common.js change
- var ts = require('./typescript');
+ var ts = require('typescript');
  1. Run yarn patch-commit -s <directory>
  2. In .yarnrc.yml add
packageExtensions:
+  "@ts-morph/common@*":
+    peerDependencies:
+      typescript: "*"
+  "ts-morph@*":
+    peerDependencies:
+      typescript: "*"
  1. Run yarn

You could change a few things, like patching the package.json directly in @ts-morph/common, but you get the idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants