angular / vscode-ng-language-service

Angular extension for Visual Studio Code
MIT License
775 stars 116 forks source link

language service does not support re-exports in source code #457

Closed JonWallsten closed 3 years ago

JonWallsten commented 4 years ago

First, thanks for the new update and all the hard work behind it! It's really appreciated.

Describe the bug In our project we import all the material components we're using into a single shared module, that module is then imported into our app.module.ts. It seems like the new Angular Language Services is unable to detect this. The shared module is not compiled. It's just imported from another folder in our monorepo.

To Reproduce

Steps to reproduce the behavior:

  1. Import any @angular/material component into a module
  2. Import that module into your main module for the application
  3. Use said material component in any component's template
  4. See error

Expected behavior

I expect no errors since the code actually works when compiled, also it worked until latest update.

Logs

Please attach two logs:

[Info  - 06:28:08] Angular language server process ID: 14968
[Info  - 06:28:08] Using typescript v3.6.4 from c:\Users\me\.vscode-insiders\extensions\angular.ng-template-0.900.0\node_modules\typescript\lib\tsserverlibrary.js
[Info  - 06:28:08] Using @angular/language-service v9.0.0-rc.3 from c:\Users\me\.vscode-insiders\extensions\angular.ng-template-0.900.0\server\node_modules\@angular\language-service\bundles\language-service.umd.js
[Info  - 06:28:08] Log file: c:\Users\me\AppData\Roaming\Code - Insiders\logs\20191125T115615\exthost1\Angular.ng-template\nglangsvc.log
Info 0    [6:28:8.138] Format host information updated
Info 1    [6:28:8.140] reload projects.
Info 2    [6:28:8.141] Structure before ensureProjectForOpenFiles:
Info 3    [6:28:8.141] Structure after ensureProjectForOpenFiles:
Info 4    [6:28:8.141] Host file extension mappings updated
Info 5    [6:28:8.155] Search path: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/single-reference-field
Info 6    [6:28:8.158] For info: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/single-reference-field/single-reference-field.edit.component.html :: Config file name: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 7    [6:28:8.159] Opened configuration file c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 8    [6:28:8.536] Loading global plugin @angular/language-service
Info 9    [6:28:8.537] Enabling plugin @angular/language-service from candidate paths: c:/Users/me/.vscode-insiders/extensions/angular.ng-template-0.900.0/node_modules/typescript/lib/tsserverlibrary.js/../../..,c:\Users\me\.vscode-insiders\extensions\angular.ng-template-0.900.0\server\node_modules\@angular\language-service\bundles\language-service.umd.js
Info 10   [6:28:8.537] Loading @angular/language-service from c:/Users/me/.vscode-insiders/extensions/angular.ng-template-0.900.0/node_modules/typescript/lib/tsserverlibrary.js/../../.. (resolved to c:/Users/me/.vscode-insiders/extensions/angular.ng-template-0.900.0/node_modules/node_modules)
Info 11   [6:28:8.551] Loading @angular/language-service from c:\Users\me\.vscode-insiders\extensions\angular.ng-template-0.900.0\server\node_modules\@angular\language-service\bundles\language-service.umd.js (resolved to c:/Users/me/.vscode-insiders/extensions/angular.ng-template-0.900.0/server/node_modules/@angular/language-service/bundles/language-service.umd.js/node_modules)
Info 12   [6:28:8.622] Plugin validation succeded
Info 13   [6:28:8.944] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 14   [6:28:22.7] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 1 structureChanged: true Elapsed: 13063ms
Info 15   [6:28:22.7] Project 'c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json' (Configured) 
Info 16   [6:28:22.7]   Files (1287)

Info 17   [6:28:22.7] -----------------------------------------------
Info 18   [6:28:22.13] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 19   [6:28:22.86] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 2 structureChanged: false Elapsed: 73ms
Info 20   [6:28:22.86] Different program with same set of files:: oldProgram.structureIsReused:: 2
Info 21   [6:28:22.731] Search path: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/single-reference-field
Info 22   [6:28:22.732] For info: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/single-reference-field/single-reference-field.component.ts :: Config file name: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 23   [6:29:0.358] Search path: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/base
Info 24   [6:29:0.359] For info: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/base/component-base.ts :: Config file name: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 25   [6:29:0.447] Search path: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/base
Info 26   [6:29:0.447] For info: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/base/component-base.ts :: Config file name: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 27   [6:29:0.548] Search path: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/base
Info 28   [6:29:0.549] For info: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/base/component-base.ts :: Config file name: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 29   [6:29:0.650] Search path: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/base
Info 30   [6:29:0.650] For info: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/components/row-type-components/base/component-base.ts :: Config file name: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 31   [6:30:7.35] Search path: c:/Users/me/repo/project-web/packages/web-app-edit/node_modules/@fortawesome/angular-fontawesome/icon
Info 32   [6:30:7.36] For info: c:/Users/me/repo/project-web/packages/web-app-edit/node_modules/@fortawesome/angular-fontawesome/icon/icon.component.d.ts :: Config file name: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 33   [6:30:10.68] Search path: c:/Users/me/repo/project-web/packages/web-app-edit/node_modules/@fortawesome/angular-fontawesome/icon
Info 34   [6:30:10.69] For info: c:/Users/me/repo/project-web/packages/web-app-edit/node_modules/@fortawesome/angular-fontawesome/icon/icon.component.d.ts :: Config file name: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 35   [6:30:10.348] Search path: c:/Users/me/repo/project-web/packages/web-app-edit/node_modules/@fortawesome/angular-fontawesome/icon
Info 36   [6:30:10.349] For info: c:/Users/me/repo/project-web/packages/web-app-edit/node_modules/@fortawesome/angular-fontawesome/icon/icon.component.d.ts :: Config file name: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 37   [6:31:18.599] Search path: c:/Users/me/repo/project-web/packages/web-app-edit/src/app
Info 38   [6:31:18.599] For info: c:/Users/me/repo/project-web/packages/web-app-edit/src/app/app.module.ts :: Config file name: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 39   [6:31:23.608] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 40   [6:31:23.816] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 3 structureChanged: false Elapsed: 208ms
Info 41   [6:31:23.817] Different program with same set of files:: oldProgram.structureIsReused:: 2
Info 42   [6:31:24.205] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 43   [6:31:24.342] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 4 structureChanged: false Elapsed: 137ms
Info 44   [6:31:24.342] Different program with same set of files:: oldProgram.structureIsReused:: 2
Info 45   [6:31:24.660] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 46   [6:31:24.779] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 5 structureChanged: false Elapsed: 119ms
Info 47   [6:31:24.779] Different program with same set of files:: oldProgram.structureIsReused:: 2
Info 48   [6:31:25.526] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 49   [6:31:25.625] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 6 structureChanged: false Elapsed: 99ms
Info 50   [6:31:25.625] Different program with same set of files:: oldProgram.structureIsReused:: 2
Info 51   [6:31:26.966] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 52   [6:31:27.195] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 7 structureChanged: true Elapsed: 229ms
Info 53   [6:31:27.195] Different program with same set of files:: oldProgram.structureIsReused:: 1
Info 54   [6:31:31.291] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 55   [6:31:31.399] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 8 structureChanged: false Elapsed: 107ms
Info 56   [6:31:31.400] Different program with same set of files:: oldProgram.structureIsReused:: 2
Info 57   [6:31:33.261] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 58   [6:31:33.648] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 9 structureChanged: true Elapsed: 387ms
Info 59   [6:31:33.648] Different program with same set of files:: oldProgram.structureIsReused:: 1
Info 60   [6:31:33.981] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 61   [6:31:34.71] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 10 structureChanged: false Elapsed: 90ms
Info 62   [6:31:34.71] Different program with same set of files:: oldProgram.structureIsReused:: 2
Info 63   [6:31:34.593] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json
Info 64   [6:31:34.751] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-app-edit/tsconfig.json Version: 11 structureChanged: false Elapsed: 158ms
Info 65   [6:31:34.751] Different program with same set of files:: oldProgram.structureIsReused:: 2
Info 66   [6:31:42.107] Search path: c:/Users/me/repo/project-web/packages/web-lib-angular/src
Info 67   [6:31:42.108] For info: c:/Users/me/repo/project-web/packages/web-lib-angular/src/web-lib-angular.module.ts :: Config file name: c:/Users/me/repo/project-web/packages/web-lib-angular/tsconfig.json
Info 68   [6:31:42.109] Opened configuration file c:/Users/me/repo/project-web/packages/web-lib-angular/tsconfig.json
Info 69   [6:31:42.175] Loading global plugin @angular/language-service
Info 70   [6:31:42.176] Enabling plugin @angular/language-service from candidate paths: c:/Users/me/.vscode-insiders/extensions/angular.ng-template-0.900.0/node_modules/typescript/lib/tsserverlibrary.js/../../..,c:\Users\me\.vscode-insiders\extensions\angular.ng-template-0.900.0\server\node_modules\@angular\language-service\bundles\language-service.umd.js
Info 71   [6:31:42.176] Loading @angular/language-service from c:/Users/me/.vscode-insiders/extensions/angular.ng-template-0.900.0/node_modules/typescript/lib/tsserverlibrary.js/../../.. (resolved to c:/Users/me/.vscode-insiders/extensions/angular.ng-template-0.900.0/node_modules/node_modules)
Info 72   [6:31:42.179] Loading @angular/language-service from c:\Users\me\.vscode-insiders\extensions\angular.ng-template-0.900.0\server\node_modules\@angular\language-service\bundles\language-service.umd.js (resolved to c:/Users/me/.vscode-insiders/extensions/angular.ng-template-0.900.0/server/node_modules/@angular/language-service/bundles/language-service.umd.js/node_modules)
Info 73   [6:31:42.181] Plugin validation succeded
Info 74   [6:31:42.223] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-lib-angular/tsconfig.json
Info 75   [6:31:49.344] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-lib-angular/tsconfig.json Version: 1 structureChanged: true Elapsed: 7121ms
Info 76   [6:31:49.344] Project 'c:/Users/me/repo/project-web/packages/web-lib-angular/tsconfig.json' (Configured) 
Info 77   [6:31:49.344]     Files (864)

Info 78   [6:31:49.344] -----------------------------------------------
Info 79   [6:31:49.349] Starting updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-lib-angular/tsconfig.json
Info 80   [6:31:49.377] Finishing updateGraphWorker: Project: c:/Users/me/repo/project-web/packages/web-lib-angular/tsconfig.json Version: 2 structureChanged: false Elapsed: 28ms
Info 81   [6:31:49.377] Different program with same set of files:: oldProgram.structureIsReused:: 2

Screenshots

image Additional context

ayazhafiz commented 4 years ago

@kyliau is this because we only retrieve diagnostics for the currently-open file? I imagine it wouldn't be, but you know more about this than I do :)

FWIW the unknown element diagnostics were introduced in https://github.com/angular/angular/pull/33064 (Angular 9.0.0-next.11).

@JonWallsten do you remember the last version of the language service plugin you used where this diagnostic did not appear?

JonWallsten commented 4 years ago

@ayazhafiz: That would probably be v0.802.3. Since we still have compiling issues with IVY we're still on Angular 8. I wasn't actually expecting this extension since we haven't upgraded to Angular 9.

ayazhafiz commented 4 years ago

@JonWallsten can you confirm that the example here compiles with the AOT compilation strategy (ng build --aot if you're using the CLI)? For me, it only compiles if I re-export the material component from the wrapper module it was imported in.

kyliau commented 4 years ago

I think this might be similar to https://github.com/angular/vscode-ng-language-service/issues/458 @JonWallsten Could you please confirm that your shared NgModule is exported? We only look for @Component and @NgModule that are exported (that could totally be a bug on our side).

kyliau commented 4 years ago

I followed the steps mentioned above, but was unable to reproduce the error.

  1. import MatButtonModule from @angular/material app-module

  2. Add MatButtonModule to imports

  3. Use mat-button in template app-template

JonWallsten commented 4 years ago

@kyliau: I'm using Webpack/AOT. When I think about it the material components are inside a ngModule called MaterialModule, which is imported in our WebLibAngular module, which is then imported in our AppModule. I actually have a skeleton repo for our project that I use for Angular bugs. Amongst other this one: https://github.com/angular/angular/issues/34027. Not sure it they are related though even though they cover some common ground.

I think this bug should be reproducible in this repo: https://github.com/JonWallsten/monorepo-old

I added you as a collaborator.

I'm not at work at the moment. But I'll check tomorrow.

kyliau commented 4 years ago

I finally got to the bottom of this.

tldr; Language service does not support re-exports in source code.

In this case, I investigated the package web-app-prime.

  1. When libraries are imported from node_modules, the language service expects that it is compiled code, not source code. This means the language service expects the presence of metadata.json to tell it about re-exports.
  2. web-app-prime has a root AppModule, and it imports WebLibAngularModule from @aos/web-lib-angular.
  3. Even though @aos/web-lib-angular is in node_modules, it is not actually compiled code. When the language service resolves this module, it only sees src/index.ts. There is no src/index.metadata.json.
  4. Language service effectively ignored the entire module since it could not find any relevant Angular information.

Solutions:

Short term: Compile any dependencies / libraries instead of copying the source into node_modules. This will generate proper metadata.json files.

Long term: With Ivy integration, we'll completely remove the requirement for metadata.json, and instead just get all information from either the .ts or .d.ts file. This will inherently solve the problem with re-exports.

kyliau commented 4 years ago

For comparison, @angular/material for example, provides index.metadata.json. That's why the language service is able to resolve it correctly even though it re-exports symbols from other files. https://unpkg.com/browse/@angular/material@8.2.3/button/

JonWallsten commented 4 years ago

@kyliau: Cool! Thanks for looking into it. I'm locking to 0.802.3 until we're ready for IVY.

vaindil commented 4 years ago

I'm having a similar problem but I'm not sure if it's the same. I'm on 0.900.3 of the extension, and my app is on the latest RC of Angular 9 (with Ivy). The language service can't find a single component/pipe/directive in our codebase, whether it's from an external library or something in our code itself despite building correctly.

JonWallsten commented 4 years ago

@kyliau: I have finally upgraded out project to IVY. I also compile web-lib-angular with ng-packagr now. But the problem unfortunately still exists. Both components and re-exported Material-stuff in the module fails in the template.

lincolnthree commented 3 years ago

Still having this problem here as well.

JonWallsten commented 3 years ago

@lincolnthree: Hopefully it might be fixed in Angular 11: https://github.com/angular/vscode-ng-language-service/issues/335#issuecomment-693545000

lincolnthree commented 3 years ago

@JonWallsten I just updated to the 11.0.x beta branch of the language service and the problem persists there :/

lincolnthree commented 3 years ago

@angular/language-service": "^11.0.0-next.6 is the version I tried.

JonWallsten commented 3 years ago

@kyliau: Have you had any time to look at this problem while upgrading the language service to support Ivy?

lincolnthree commented 3 years ago

Still not working with the latest rc.2 updates.

lincolnthree commented 3 years ago

Still not working with the latest rc.3 update. Was hopeful because I saw some work was done on a fix for the compiler doing redundant execution on pipes.

lincolnthree commented 3 years ago

Just in case this helps someone who ends up here. If you only have a handful of components that suffer from this issue, you can potentially do something like this, where you extend and re-export the component (a pipe in this case), making sure to exactly mirror the interface/angular annotations/declarations.

While this definitely suffers some brittleness if the API of your dependency changes, it does at least prevent copying the entire source file into your repo...

import { Pipe, PipeTransform } from '@angular/core';
import { PushPipe } from '@rx-angular/template';

@Pipe({ name: 'push', pure: false })
export class PushPipeFacade<T> extends PushPipe<T> implements PipeTransform {
}

And export it in your app.module.ts:

@NgModule({
  declarations: [PushPipeFacade],
  imports: [
    PushModule
  ],
  providers: [],
  exports: [PushPipeFacade]
})

It's definitely not pretty, but it will resolve the sea of red in your IDE when editing templates.

(The pipe we are re-exporting, for clarity: https://github.com/rx-angular/rx-angular/blob/master/libs/template/src/lib/push/push.pipe.ts)

kyliau commented 3 years ago

@lincolnthree The situation I explained earlier is inherently a limitation with View Engine, the current backend for the vscode extension. By switching to Ivy, I meant the backend of the extension, not the user project. It is too big of a change to fix this in View Engine, and it's probably not worthwhile since View Engine will be deprecated soon. I understand this is inconvenient, but please bear with us. We are close to releasing the Ivy version of language service, which will be a lot more powerful than the View Engine version, and it'll fix architectural issues like this one.

lincolnthree commented 3 years ago

@kyliau Ah! Thank you for clearing up that issue. I didn't realize that the language service actually still used ViewEngine. This makes sense. I'm looking forward to the update :)

As an added benefit, I'm assuming it should also reduce overhead since it shouldn't be required to build both with Ivy for ng-serve and V.E. in the IDE/tools. But I digress.

Thanks for the update. I'll stop bugging you :)

KostblLb commented 3 years ago

I also experience troubles with library imports: I have a library built NOT with ivy (enableIvy was set to false in tsconfig) with this bundle index:

/**
 * Generated bundle index. Do not edit.
 */
export * from './public-api';
export { XComponent as ɵa } from './lib/x.component';
export { YComponent as ɵb } from './lib/y.component';

when I import something from this bundle in my code, the language service breaks immediately, and restores once I remove the imports

kyliau commented 3 years ago

This has been fixed by the new Ivy-native language service, released in v11.1.0.

angular-automatic-lock-bot[bot] commented 3 years ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.