ReactiveX/rxjs

TypeScript: Workaround to `npm link`

david-driscoll opened this issue · 14 comments

RxJS version:
N/A

Code to reproduce:
npm link one project that is using rxjs with another project.

Expected behavior:
TypeScript Compiler should not throw errors

Actual behavior:
TypeScript Compiler does throw errors

Additional information:
There are problems when using rxjs with tools like npm link that cause the compiler to fail to resolve types properly and create lots of compiler errors, as it sees two copies of the same class, and they are not compatible.

Workaround
I've found a workaround when using TS 2.0+ that appears to solve this problem, and it's fairly easy to configure.

Based on this information, we can use the new path based mapping to solve the problem.

Adding the following to your tsconfig will make the issue go away, assuming your using the new TS 2.0 beta or the nightlys.

    "compilerOptions": {
        "baseUrl": "",
        "paths": {
            "rxjs": ["node_modules/rxjs"]
        }
    }

Related Issues
microsoft/TypeScript#6496
microsoft/TypeScript#7755
#1744

cc @Blesh @robwormald @kwonoj @staltz

cc @mhegazy @ahejlsberg - maybe this can be fixed easily in the compiler? 🙏

While this work around works, it's fairly painful that we have to make these changes, and post these work arounds.

Are there other simpler fixes? Can the compiler emit an identifier in the .d.ts files that so that it knows "hey this module is equal to this other module"?

Is this something we should add to https://github.com/ReactiveX/rxjs/blob/897fe3b16a957b8808089379dfabdfd80b00509a/doc/installation.md or something else?

I'm not sure this is an issue with RxJS. Sounds like a TypeScript issue from the description

as expressed my opinion on #1744, I also think this is mostly compiler behavior and not to be handled in RxJS code implementation (or documentation). Someone might use those as tips but wouldn't to be included in repo. what do you think, @david-driscoll ?

npm link should work in TS 2.0.3 (see the change in microsoft/TypeScript#8486). there are other issues with symlinks in general that we plan on addressing for TS 2.1 namely (microsoft/TypeScript#11613, microsoft/TypeScript#11107, microsoft/TypeScript#10364, microsoft/TypeScript#9552, and microsoft/TypeScript#9091).

Can you share some repro steps to get to the issue described above, these are probably bugs that need to be fixed.

microsoft/TypeScript#6496 (and its predecessor microsoft/TypeScript#7755) are not about sym links, they are about treating diffrent versions of the same library as the same for assignment compat purposed for privarte/protected properties. i do not think there is an argument when they are exactly the same file on disk.

@mhegazy I'm still having problems with TS 2.0.3. Where I used to get this error, now the compiler hangs for a long time and then crashes with a CALL_AND_RETRY_LAST Allocation failed error. Does TS 2.0.3 resolve this issue for anybody else? Maybe there is some other issue with my environment.

@david-driscoll, your fix seems to have addressed the issue I'm having. Thanks! I'll need to try more things to be sure, but for sure it solves the crash I described in my previous comment to @mhegazy.

@xogeny can you share a project i can look at?

@mhegazy I tried to create a simple case. So far, no luck. It builds just fine for the simple case. I understand that without a reproducible case, there isn't much you can do. I wonder if @david-driscoll might have one?

Given my experience with the simple case, I'll try to figure out what is different between that case and the case that shows the issue. But I'll have to work it into my other work. But I'm 100% sure that with 2.0.3, the compiler crashed but then worked if I did the fix above.

yeah, i could not get this to repro locally, so i assumed it is working :)

if you can not share a sample, a directory structure + tsc --diagnostics output might be helpful. also try running tsc --listFiles and see if there are files that should not be there, then we can work backwards from there and see how/why they were including using tsc --traceResolution.

@mhegazy So I tried these suggestions. The --diagnostics and --listFiles simply do not work because the compiler goes into some kind of infinite recursion or something and crashes before generating any output. However, the advantage of --traceResolution is that it provides continuous output (before crashing).

I did a --traceResolution with and without the paths fix above. There is a lot of output to sift through there, but I did a diff of the output across both cases. As you might expect, the one with the paths setting in tsconfig.json doesn't do much "searching" for rxjs. The other includes lots of additional output about searching for rxjs related files.

Apart from resolving the rxjs stuff differently (and they both do resolve it), they seem to be identical. But one thing to note is that the "crash" of the compiler does not occur during this resolution phase, but later (no output during that phase, so I'm not sure what the compiler is doing then).

One thing to note. If I use npm link EXTERNAL_MODULE, I see this issue. If, however, I do an npm install PATH_TO/EXTERNAL_MODULE, everything works fine (no crash). One thing I cannot help but notice is that with npm link, there exists a node_modules/EXTERNAL_MODULE/node_modules/rxjs directory. But with npm install, it isn't there. Furthermore, I can see that with --traceResolution, it is crawling through those files.

So the workaround works for me for now. I may even switch to npm install in the future (not sure) just to avoid the workaround. If you ever want to have a Skype session to explore this case more thoroughly and try and track it down further, just let me know.

@xogeny can you share a repro project?

@mhegazy Unfortunately, I cannot. This is work for a client, not an open source project. As I mentioned above, I tried to recreate the issue by creating other projects to mimic the structure of the repo that is showing this issue. But that doesn't reproduce the problem. After trying these CLI options, I still don't understand what it is that is special about this project. I'm keeping my eyes open for things that might allow me to reproduce this in a simpler case. But so far, no luck.

I'm closing this for now, as shared I don't feel this need to be handled in plain use case documentation scenario.

lock commented

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.