`projectSymbols.getModules()` throws error
Cammisuli opened this issue · 6 comments
Hey!
Recently I was asked to find a way to analyze our Angular project, and I came across this project that wraps all the fun stuff that the @angular/compiler-cli
does.
So, I started, and when i tried to use projectSymbols.getModules()
I always got an error like so:
Error: Type DeviceActionsBarControl in
C:/Development/WWW/portals/console/app/controls/device-action-bar/device-actions-bar.ctrl.ts
is part of the declarations of 2 modules:
DeviceActionsBarModule in C:\Development\WWW\portals\console\app\controls\device-action-bar\device-actions-bar.module.ts and
DeviceActionsBarModule in C:/Development/WWW/portals/console/app/controls/device-action-bar/device-actions-bar.module.ts!
Please consider moving DeviceActionsBarControl in C:/Development/WWW/portals/console/app/controls/device-action-bar/device-actions-bar.ctrl.ts
to a higher module that imports DeviceActionsBarModule in C:\Development\WWW\portals\console\app\controls\device-action-bar\device-actions-bar.module.ts
and DeviceActionsBarModule in C:/Development/WWW/portals/console/app/controls/device-action-bar/device-actions-bar.module.ts.
You can also create a new NgModule that exports and includes DeviceActionsBarControl in
C:/Development/WWW/portals/console/app/controls/device-action-bar/device-actions-bar.ctrl.ts then
import that NgModule in DeviceActionsBarModule in
C:\Development\WWW\portals\console\app\controls\device-action-bar\device-actions-bar.module.ts and
DeviceActionsBarModule in
C:/Development/WWW/portals/console/app/controls/device-action-bar/device-actions-bar.module.ts.
This was the first time seeing this error being thrown, and I have never seen it while starting the actual project in JIT, or building in prod with AOT.
So I dug in. First thing I noticed is that the error is complaining that a component is in the same module. Which was just whacky. Then I noticed that the slashes were different. And me being on a Windows machine, slashes are always a pain in the butt.
I tried changing the baseUrl
in all the tsconfigs I could find, and still the same error occurred.
I then went down into the @angular/compiler-cli
and noticed this little guy:
https://github.com/angular/angular/blob/d9ae70c699c4e2969f2d3539c50e719ba47bb6a1/packages/compiler-cli/src/perform_compile.ts#L150
path.normalize
took my properly slashed paths (C:/etc/etc
) and made them Windowsy (C:\etc\etc
)
So when Angular tries to traverse some modules, the returned path was C:/etc/etc
, but the rootNames
always were C:\etc\etc
.
Now, I'm not sure if there's some property I need to set in Node, Typescript or Angular to keep those paths with forward slashes. But, I found that by replacing
Line 80 in 88f5317
with :
this.program = createProgram({
rootNames: config.rootNames.map((rootName) => rootName.replace(/\\/g, '/')),
options: config.options,
host: this.compilerHost
});
Solved my issue and I managed to get all my modules.
I'm just wondering, would this be the best solution. And if so, I'm more than happy to create a pull request with it. If not, any direction would be great.
Thanks 😄!
Thanks for sharing the issue and the solution! Maybe require('path').normalize
..?
I see. Does have you had a chance to test this on Mac or Linux?
I looked more into the problem and discovered that when trying to get the tsProgram
here:
Line 264 in 88f5317
It goes into the Angular compiler-cli here:
https://github.com/angular/angular/blob/0b1f5d21270063b2019b11a9494397916d3977d6/packages/compiler-cli/src/transformers/program.ts#L489
Which calls this._createProgramWithBasicStubs()
and then calls ts.createProgram
here:
https://github.com/angular/angular/blob/0b1f5d21270063b2019b11a9494397916d3977d6/packages/compiler-cli/src/transformers/program.ts#L554
And then TypeScript calls processRootFile
here:
https://github.com/Microsoft/TypeScript/blob/868a9ee117173a60167626131a78eec00f19b716/src/compiler/program.ts#L586
And then finally calls normalizePath
here:
https://github.com/Microsoft/TypeScript/blob/868a9ee117173a60167626131a78eec00f19b716/src/compiler/core.ts#L1986
Which effectively does: path.replace(/\\/g, "/")
, and reverses what the @angular/compiler-cli
does with path.normalize
here.
It's a long ride, but there it is.
So, getting the rootNames
to match what TypeScript is doing, would be best.
And because this library should be a friendly wrapper for the Angular compiler, I think it's good to put the replace(/\\/g, '/'))
.
Thanks!
@Cammisuli sounds good. Would you open a PR for the proposed fix? I'll after that update the dependencies of ngrev.