Rxjs: "Cannot find module" errors with 5.5.0-beta.0

Created on 24 Sep 2017  路  15Comments  路  Source: ReactiveX/rxjs

I've encountered a problem that seems to be related to the new package structure in 5.5.0-beta.0.

After updating to the beta (the only change made) my CI build is failing. For some reason, TSLint is failing when performing type-checked linting of a project that uses the beta, claiming that it cannot find numerous modules.

Strangely, this only seems to happen on Linux. The linting and tests are fine on my Windows and Mac computers.

Whether this is a TSLint issue or an RxJS beta issue is, at the moment, unclear.

RxJS version: 5.5.0-beta.0

Code to reproduce:

The TSLint command used to lint the project is:

tslint --project tsconfig.json --type-check source/**/*.ts

Expected behavior:

I would expect no errors to be effected.

Actual behavior:

See this Travis log. Errors like the following are effected:

Error at source/let/debounceAfter.ts:8:24: Cannot find module 'rxjs/observable/concat'.
needs info bug

All 15 comments

This seems somewhat related with https://github.com/ReactiveX/rxjs/pull/2853.

I talked with @benlesh around this kind issues this morning, trying to isolate root cause for this.

@kwonoj Thanks for the fast response. I'm going to have a closer look at this later today. Hopefully, it won't be too hard to find the problem.

It's because there is no operator directory in the distribution. The actual directory name has an uppercase O. Changing this to a lowercase o fixes the operator-related errors.

However, there is also a problem with the Observable directory that is not as easily fixed. That directory is used with a lowercase o for imports like:

import { concat } from "rxjs/observable/concat";

But it's also used with an uppercase O for imports like:

import { Observable } from "rxjs/Observable";

The latter import is resolved via rxjs/Observable/package.json file in the distribution - previously, the uppercase import was an actual file.

Clearly, renaming the Observable directory to observable will break the latter (on case-sensitive file systems).

There is similar problem with the Scheduler directory in the beta. In the previous distribution, it was a file with an uppercase S and a directory with a lowercase s.

Short of using a postinstall script to create lowercase copies of the uppercase Observable and Scheduler directories, I don't see how this change to the distribution could be made non-breaking.

@kwonoj

It is reason 5.5 has released as beta, instead of public to avoid breaking public release without major semver. Does any of in-range public update automatically upgrades into 5.5b?

I understand that it's a beta and that's fine. The process is working as it should.

I would not expect any consumers to be automatically upgraded to the beta, as the semver is a pre-release. I've certainly not seen any automatic upgrades.

My comment was referring to whether it would be possible for the new packaging mechanism to be used in a non-breaking 5.5 non-beta release. And without using a postinstall script on case-sensitive file systems, I don't think it would be. Whether or not you would countenance such a thing, I don't know.

yeah, I actually deleted the comment as I came to think I misunderstood question 馃槗 apologize.

My comment was referring to whether it would be possible for the new packaging mechanism to be used in a non-breaking 5.5 non-beta release.

Is there specific reason you're thinking it is not possible? I may not be able to fully answer this question though.

No worries.

I don't think it's possible as there will be existing code with imports like this:

import { Observable } from "rxjs/Observable";
import { Scheduler } from "rxjs/Scheduler";

and like this:

import { timer } from "rxjs/observable/timer";
import { async } from "rxjs/scheduler/async";

With the first group of imports, the directories have an uppercase initial letter and, with the second, a lowercase initial letter. So, on case-sensitive file systems, there will need to be two directories. (It's the second group of imports that break in the beta, as there is no observable directory, etc.)

Unless it's possible to prepare an npm package that includes directories that differ only in case, the only non-breaking solution I can see would be to use a postinstall script that creates lowercase copies of the directories on case-sensitive file systems. Which sounds ... unpleasant.

This wasn't a problem in the previous release because the uppercase imports mapped to .d.ts files and the lowercase imports mapped to directories. But with the new mechanism, both are directories.

Yeah. this was part of an attempt to get better tree-shaking and bundling with webpack and/or rollup. It might be that we have to roll this change back and punt until a 6.0 release, as it might require breaking changes. :\

i've been unable to reproduce this issue thus far, but I was a little worried this might happen. cc @jasonaden @IgorMinar

My hypothesis based on what I see in logs/npm: both Windows and Mac has it's default filesystem to be case-insensitive (but case preserving), whereas Linux is by default case-sensitive.

This means that resolving rxjs/observable/of will fail on Linux if the of static helper is located in rxjs/Observable/ofdirectory as is the case today. The errors are coming from the typescript compiler while it's resolving the module paths, which makes me believe that the files are actually there, but they are in a directory with the wrong case (rxjs/Observable rather than rxjs/observable)

As long as we want to support importing from both rxjs/Observable and rxjs/observable/*, we'll need to have two directories with different case present on the filesystem on linux, but on other case-insensitive filesystems the two directories would have to be merged into one.

@jasonaden said that he felt like we worked around all these issues because the rxjs test suite was passing after he made some adjustments due to this problem, but I think we missed something and should double check how this stuff is actually tested within the rxjs test suite.

I'm testing this a bit more. TypeScript isn't resolving modules referenced as rxjs/observable/* to our /Observable directory. And it does appear to be a casing issue as I created a symlink from /observable to /Observable (and the same for Observer) and the Angular build that was previously failing now works.

Looking into this more, there seems to be a solution that works. A few options were discussed before coming to this solution:

  • Using a symlink in Linux as mentioned above. This is a bit of an ugly solution and may not work with tools such as unpkg.com.
  • Copying files to the right place (case-sensitive directory names) after install. This is also not a good solution as it modifies the directory after install (not allowed for some corporations) and wouldn't work with unpkg.com.

Since neither of these solutions will work, I tried running the build on a case-sensitive operating system, then publishing from there to NPM. Here is my test I published showing that unpkg.com will work. I npm installed on Linux, Mac and Windows. On Linux we get the case sensitive directory names and builds against Rx work. On Mac and Windows the directories are merged, and everything works.

So I think the solution, if we want to get this packaging update out, is to build on a case sensitive OS and publish from there. I would like to at least push out a beta.1 this way and see if that fixes the current issues we're having testing the beta.

I didn't want to say anything before beta.1 but didn't want to not say nothing either in case it's not related :) But with beta.0 I'm also getting errors from ng about the inability to find modules even with the uppercased O:

ERROR in /Sites/angular-cli-blue/node_modules/@angular/router/src/router.d.ts (10,28): Cannot find module 'rxjs/Observable'.
ERROR in /Sites/angular-cli-blue/node_modules/@angular/core/src/event_emitter.d.ts (8,25): Cannot find module 'rxjs/Subject'.

Not sure I was getting this yesterday as it was mostly errors about o -> O after deploying to Heroku (I'm on OSX locally and getting the above errors now locally)

node: 8.5.0
npm: 5.3.0
tsc: 2.6.0-dev.20170926
ng: 5.0.0-beta.7
cli: 1.5.0-beta.1

https://github.com/intellix/angular-cli-red
https://github.com/intellix/angular-cli-blue (depends on angular-cli-red)

With 5.5.0-beta.1 and 5.5.0-beta.2, my Travis builds are now fine. Thanks.

The bundle size gets significantly larger 57kb -> 119kb!, maybe related to #2812 ?

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Zzzen picture Zzzen  路  3Comments

cartant picture cartant  路  3Comments

matthewwithanm picture matthewwithanm  路  4Comments

unao picture unao  路  4Comments

benlesh picture benlesh  路  3Comments