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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular language service doesn't see components from library built with Ivy. #645

Closed
denis-manokhin opened this issue Dec 5, 2019 · 24 comments
Assignees
Labels
bug ivy Feature / enhancement / bug fix in Ivy

Comments

@denis-manokhin
Copy link

馃悶 bug report

Affected Package

The issue is caused by package @angular/language-service

Description

Angular language service doesn't see components from library built with Ivy.
Application is built correctly.

Error


'lib-component' is not a known element:
1. If 'lib-component' is an Angular component, then verify that it is part of this module.
2. If 'lib-component' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.ng(0)

Environment


Editor: VisualStudio Code
Editor extension: angular.ng-template v0.900.0

Angular CLI: 9.0.0-rc.5
Node: 10.17.0
OS: darwin x64

Angular: 9.0.0-rc.5
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.900.0-rc.5
@angular-devkit/build-angular      0.900.0-rc.5
@angular-devkit/build-ng-packagr   0.900.0-rc.5
@angular-devkit/build-optimizer    0.900.0-rc.5
@angular-devkit/build-webpack      0.900.0-rc.5
@angular-devkit/core               9.0.0-rc.5
@angular-devkit/schematics         9.0.0-rc.5
@angular/cdk                       9.0.0-rc.4
@ngtools/webpack                   9.0.0-rc.5
@schematics/angular                9.0.0-rc.5
@schematics/update                 0.900.0-rc.5
ng-packagr                         9.0.0-rc.3
rxjs                               6.5.3
typescript                         3.6.4
webpack                            4.41.2
@denis-manokhin
Copy link
Author

Update. Ivy compiler doesn't create file lib-name.metadata.json in project_root/dist/lib-name.
Could this be the problem?

@julienvonoetinger-eaton

+1 I have the same issue

@kyliau
Copy link
Contributor

kyliau commented Jan 13, 2020

Post version 9, we are going to switch the language service internals to use the Ivy compiler. Until then, the language service would need to rely on metadata.json to retrieve additional information about a directive.

@kyliau kyliau self-assigned this Jan 13, 2020
@jiverson
Copy link

jiverson commented Feb 18, 2020

Yes this is the issue. To resolve for the time being, you will need to build the prod version of your library which has "enableIvy": false in tsconfig. This then generates the metadata file needed in the dist folder.

ie ng build lib-component --prod

But you also need to make sure to Restart Angular Language service after each build in vs-code.

All this information is not easily found between the vs-code plugin and angular itself. Just a heads up for anyone else experiencing this same issue.

My assumption that

@kyliau kyliau transferred this issue from angular/angular Feb 18, 2020
@kyliau kyliau transferred this issue from angular/angular-cli Feb 18, 2020
@kyliau kyliau added bug ivy Feature / enhancement / bug fix in Ivy labels Feb 18, 2020
@vicatcu
Copy link

vicatcu commented Mar 1, 2020

@jiverson regarding your workaround ng build lib-component --prod for me yields an error An unhandled exception occurred: Configuration 'production' is not set in the workspace. and I've seen evidence elsewhere that the --prod flag for libraries is no longer relevant. I'm using @angular/cli v8.3.25 though... so while this issue has been referred to as a possible duplicate for #665, I'm not so sure it is. Any thoughts? /cc @ayazhafiz

@ximikavt
Copy link

ximikavt commented May 8, 2020

Any updates on this? We have our own libraries developed and published in ivy even in prod.

@ayazhafiz
Copy link
Member

Work is underway to move the language service to an Ivy backend!

@nprasovict
Copy link

I can confirm that if you do:

  • build library with ng build my-library --prod and
  • ctrl+shift+p and then select "Restart Angular Language server"

the error(s) of the type "'xyz' is not a known element" will be gone from the library's parent project.

As I understood it this is because --prod will (among other things) generate my-library.metadata.json file in dist folder which will then be used by the language server to i.e. recognize component selectors defined in my-library.

Now, one would expect that if I npm publish library built with ng build my-library --prod and then npm install that library into some other Angular app, the language server would see the metadata file in that installed npm package (in node_modules folder) and would not report "'xyz' is not a known element".

However, this is not working as expected and I can see the same error in a project that has npm installed my-library, even though there is a metadata json file present in my-library folder in node_modules.

Would this be the same bug as in this issue or a different bug?

Or is there some other (or additional) magical combination of keys to press or commands to give to the language server so it processes npm installed Angular libraries correctly?

@abdes
Copy link

abdes commented Jun 23, 2020

It appears that the new way Ivy is working is to rely on metadata from .d.ts files and no longer from metadat.json files. The only reason why a --prod build is working is because your tsconfig is setting enableIvy to false (as recommended by angular for npm published libraries). This is a language service issue and not an angular cli issue, as the build will work just fine with or without Ivy for an application using the published library.

The issue is two-fold:

  1. Ivy removes the metadata.json files, required by ALS and other tools as well
  2. ALS is not currently smart enough to get the info from Ivy metadata instead of .metadata.json

Why is this a very annoying issue?

  • Ivy is the way to go, and library developers will make it the way to go as well,
  • when creating a library in your Ivy-based application project, you still want to use Ivy end-to-end in your app while still being a good citizen and publishing your reusable library to npm for others to use it.
  • most developers use npm link or point the tsconfig to the library dist directory for imports during the app development, that's the obvious way anyway,
  • it's annoying as hell to have vscode flagging things in your library as unknown,

abdes added a commit to abdes/happy-coding that referenced this issue Jun 23, 2020
In order to avoid the complexity related to yarn/npm link and unlink
of publishable libs built as npm package, we add path mappings to
the tsconfig to pull the imports out of the repo source files.
Publishable libraries used as peer dependencies in other libraries will
still need to be installed from the npm repo as normal dependencies
in package.json. Independently of that, imports in the workspace will
still be taken from the source modules and will be built as part of the
apps without any restriction on the use of Ivy or not.

angular/vscode-ng-language-service#665
angular/vscode-ng-language-service#645
angular/vscode-ng-language-service#827
@abdes
Copy link

abdes commented Jun 23, 2020

Here is what I ended up doing to work around this issue, which may be acceptable to some people under the same circumstances. It won't help people who want to use their publishable libraries under the same conditions as a user of such libraries (i.e. from the published npm package):

Assuming you are using a monorepo or similar structure where the source code of the publishable library is accessible in a consistent manner to the application using it.

Let's assume the package is called 'happy-library'...

  1. Build (with --prod) and publish the library package to npm as usual. You must use --prod and have Ivy disabled in the build configuration,
  2. Update your tsconfig.json in the workspace root (or vscode will not figure it out...) to add a path mapping to that package, pointing to the source directory of the package.
  3. Import the package in the application code as if it were from node_modules, i.e. import {whatever} from 'happy-library';
    "paths": {
      "happy-library": ["libs/happy-library/src/index.ts"]
    }

It's not perfect, but at least I can use my own library in an end-to-end Ivy application, also made by me, without the errors in vscode, while still sharing the love and publishing it to NPM for other users, and I don't have to constantly yarn/npm link and debug why ALS is not working.

Interested in feedback if I may have missed something...

PS: fully working repo with this method at https://github.com/abdes/happy-coding

@Dzivo
Copy link

Dzivo commented Sep 13, 2020

Has any progress been made on this.

@jonyadamit
Copy link

Seems this will be available for beta-testing on Angular 11 scheduled for November.

See #335 (comment)

@schankam
Copy link

schankam commented Dec 15, 2020

I'm running on Angular 11 in my project (library built as well with Angular 11, with the --prod flag), and I have the issue decribed by @nprasovict . I published my library on Gitlab packages, and when I install it in our project with npm install, the Angular Language Service does not recognize my exported components coming from my library. Looks like it's been an issue for a very long time now, when can we expect it to be solved ?

I think I'll just end up removing the VSCode extension for now, but I'll be loosing a powerful development just because of this...

@JonWallsten
Copy link

JonWallsten commented Dec 15, 2020

@schankam: #457 (comment)

@schankam
Copy link

@JonWallsten Thanks, so it will be released soon if I understand well

@kyliau
Copy link
Contributor

kyliau commented Jan 21, 2021

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

@kyliau kyliau closed this as completed Jan 21, 2021
@JonWallsten
Copy link

Awesome work, @kyliau!
I see lot's of new errors in the template when it comes to strict null check and such that we've missed, really nice!

@rodro75
Copy link

rodro75 commented Feb 2, 2021

@kyliau Hmmmm... that's weird. I was having the very same problem with a directive declared in a library and I solved it by following the suggestion of building the library with the --prod switch. The thing is that I am already on ALS 11.1.1, so theoretically this would not have to be an issue anymore, right?
The project is a regular CLI multi-project, with some libs and an app.
Not sure about npm linking... I didn't do anything special. The library's path is listed in the root tsconfig.json.

@Blackfaded
Copy link

I have the same issue. I build my lib with the --prod flag, so that ivy is disabled.
Linked the library dist folder, linked the package to my app and imported the libmodule. But still getting this error, that it is not a known angular element.
The component in the lib is in the declarations and in the exports array.

The component gets displayed, but still getting this error in vscode. tested versions:

11.1.3
11.2.1
0.1100.4

@vicatcu
Copy link

vicatcu commented Feb 9, 2021

I agree, this probably shouldn't be closed @kyliau... I have a minimal reproducible example that I made for another problem that might serve to demonstrate this one as well. Have a look at this: https://github.com/vicatcu/monorepo-example-error (originally posted in connecction with this SO post)

@vicatcu
Copy link

vicatcu commented Feb 9, 2021

I'll go a step further, if I add the "enableIvy": false option under the angularCompilerOptions in the tsconfig.lib.json apropos this comment, as I have done on this branch of my example repo, my errors vanish in vscode (granted my example project is still broken in some way I don't understand)

@kyliau
Copy link
Contributor

kyliau commented Feb 9, 2021

Just to clarify, being on v11.1.x is not enough, you have to enable Ivy mode by following the instructions here.
You should not have to change your tsconfig.*.json.
The fact that ... is not a known angular element showed up means you are not in Ivy mode.
To determine which mode you're on, go to the Output panel and look for Angular language service. It should mention Ivy. (see screenshot below).
Your project does not have to be using Ivy to use the Ivy language service, but you do have to be using Angular >= v9.

Screen Shot 2021-02-01 at 3 15 40 PM

If after verifying all of the above and the extension is still not working as expected, please open a new issue to help us triage and reduce noise. Thank you very much!

@vicatcu
Copy link

vicatcu commented Feb 9, 2021

@kyliau thanks I, for one, had certainly missed that.

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Mar 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug ivy Feature / enhancement / bug fix in Ivy
Projects
None yet
Development

No branches or pull requests