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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False Positive: 'QueryList' is imported from external module '@angular/core' but never used #710

Closed
karan-kang opened this issue Mar 22, 2018 · 30 comments

Comments

@karan-kang
Copy link

Type of Issue

[ X] Bug Report

Description

A warning is logged during build time if a component uses '@ContentChildren' or '@ViewChildren' annotation with QueryList type.

'QueryList' is imported from external module '@angular/core' but never used

How To Reproduce

Create a new component, which has this property:


@ContentChildren(MyOptionComponent)
options: QueryList<MyOptionComponent>;

Expected Behaviour

No Warning should be logged, since QueryList is being used for type safety here.

Version Information

$ node_modules/.bin/ng-packagr --version
ng-packagr:            2.2.0
@angular/compiler:     5.2.3
@angular/compiler-cli: 5.2.3
rollup:                0.55.5
tsickle:               0.26.0
typescript:            2.5.3
@rafaelblink
Copy link

Can you share your project files?

@karan-kang
Copy link
Author

Sorry, i cannot share ny project files.

This issue is easily reproducible, just use the @ContentChildren with QueryList type.

@deebloo
Copy link

deebloo commented Mar 24, 2018

This won't cause a problem. It is because it is only being used as a type.

@karan-kang
Copy link
Author

I know this won’t cause a problem, that’s why i said in the title it is a false positive 😁

@alan-agius4
Copy link
Member

This is an issue with Angular Compiler.

Have a look at this angular/angular#21280

@dherges
Copy link
Contributor

dherges commented Jun 20, 2018

Yes, but I don't see how the issue could be solved?!?

After TypeScript compilation, the import is still there and then rollup is going to (tree?-)shake it out.

I think a fix for that should be in tsc, because only tsc knows whether the symbol is being used as a compile-time type only or as a value at runtime.

@alan-agius4
Copy link
Member

alan-agius4 commented Jun 20, 2018

Atually with tsc compilation the import is dropped but with ngc it isn’t hence the Angular Compiler issue mentioned above.

@dherges
Copy link
Contributor

dherges commented Jun 20, 2018

Ok. thanks for clarification.

@FirstVertex
Copy link

FirstVertex commented Jan 3, 2019

I get similar problem like this when using ElementRef.

I tried using tslint:disable and that did not help.

This warning message logged 2x to console is 'ElementRef' is imported from external module '@angular/core' but never used. See full console output from build:

[0] File change detected. Starting incremental compilation...
[0] Building entry point '@dynatron/framework'
[0] Compiling TypeScript sources through ngc
[0] Bundling to FESM2015
[0] 'ElementRef' is imported from external module '@angular/core' but never used
[0] Bundling to FESM5
[0] 'ElementRef' is imported from external module '@angular/core' but never used
[0] Bundling to UMD
[0] Minifying UMD bundle
[0] Copying declaration files
[0] Writing package metadata
[0] Removing scripts section in package.json as it's considered a potential security vulnerability.
[0] Built @dynatron/framework
[0] Built Angular Package!
[0]  - from: d:\Dynatron\code\framework\framework
[0]  - to:   d:\Dynatron\code\framework\dist\framework
[0]
[0] Compilation complete. Watching for file changes...

Here is my component that makes compile warning.

/// <reference types="@types/googlemaps" />

import { Component, OnInit, Inject, ViewChild } from '@angular/core';
// tslint:disable-next-line:no-unused-variable
import { ElementRef } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'dyna-location-finder',
  templateUrl: './location-finder.component.html',
  styleUrls: ['./location-finder.component.scss']
})
export class LocationFinderComponent implements OnInit {
  private window: Window;
  // tslint:disable-next-line:no-unused-variable
  @ViewChild('gmap') gmapElement: ElementRef;

  constructor(@Inject('Window') _window: any) {
    // https://github.com/angular/angular/issues/20351#issuecomment-446025223
    this.window = _window;
  }

  ngOnInit(): void {
    this.window.navigator.geolocation.getCurrentPosition((location: Position) => 
        this.updateMap(location.coords));
  }

  private updateMap(coords: Coordinates) {
    if (coords) {
      const position = new google.maps.LatLng(coords.latitude, coords.longitude);
      const mapProp = {
        center: position,
        zoom: 16,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        fullscreenControl: false
      };
      const map = new google.maps.Map(this.gmapElement.nativeElement, mapProp);
      new google.maps.Marker({
        position: position,
        map: map,
        title: "You are here",
        label: "You are here",
      });
    }
  }
}

The gmapElement: ElementRef is just a reference to a div in the html markup who looks like this <div class="map" #gmap></div>

Clearly ElementRef is used, it is the type of a class member. And the class member is used in the line const map = new google.maps.Map(this.gmapElement.nativeElement, mapProp); so there is no reason compiler should warn about this. Even more baffling the tslint flag is ignored.

@andresbm05
Copy link

Also happens with TemplateRef, I'm using it as a type:
@ViewChild('my-template') myTemplate: TemplateRef<any>

And when compiling it says:
'TemplateRef' is imported from external module '@angular/core' but never used

@skykick-cm
Copy link

I also am using a @Input() foo: TemplateRef<any>, which is being accessed in my HTML template, yet I still get the Warning: 'TemplateRef' is imported from external module '@angular/core' but never used during a build on the latest CLI 8.1.1.

@AliKalkandelen
Copy link

AliKalkandelen commented Jul 25, 2019

Also happens with TemplateRef, I'm using it as a type:
@ViewChild('my-template') myTemplate: TemplateRef<any>

And when compiling it says:
'TemplateRef' is imported from external module '@angular/core' but never used

Same thing happens to me. I am using TemplateRef to reference to a modal

  // reference to the text area modal
  @ViewChild('textAreaDialog') textAreaDialog: TemplateRef<any>;

@kKen94
Copy link

kKen94 commented Aug 8, 2019

Same

@werts
Copy link

werts commented Oct 8, 2019

any progress here?

@imike57
Copy link

imike57 commented Nov 13, 2019

Also looking for a solution... Any news ?

@dusekp
Copy link

dusekp commented Dec 9, 2019

Same problem with FormGroup imported from @angular/forms.

Solved by workaround - creating instance of FormGroup in constructor:

export class ProblematicClass {
    private pom: FormGroup;
    constructor(){
            this.pom = new FormGroup({});
    }
}

The compiler no longer thinks FormGroup is not used.

@mvmjacobs
Copy link

Same problem here with:

import { MatInput } from '@angular/material/input';
@ViewChild('searchInput', { static: false }) searchInput: MatInput;

@joshuwhi
Copy link

To all those commenting specific cases:

This will happen with any Class you import then use only as a type definition.

As already linked above this is a duplicate of: angular/angular#21280

@Semigradsky
Copy link

Semigradsky commented Jun 29, 2020

Hi! This issue will gone if you will use import type from Typescript 3.8

For example:

import { ChangeDetectionStrategy, Component, Input, ViewChild } from '@angular/core'
...

import type { ElementRef, NgZone, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'
...

It works nice for ng-packagr@10.0.0

@johncrim
Copy link

This warning went away when I switched to Ivy builds and disabled emitDecoratorMetadata for libraries:

tsconfig.js:

  "compilerOptions": {
---    "emitDecoratorMetadata": true,
  },
  "angularCompilerOptions": {
+++    "enableIvy": true
  },

Admittedly this isn't (yet) a viable workaround if you're publishing libraries that need to be used by non-Ivy projects.

@PowerKiKi
Copy link

Incidentally, warnings disappeared when I upgraded to Angular 10 (along with all other JS deps).

I was going to implement @Semigradsky solution when I noticed that Angular 10 was just released. So I started by upgrading everything. And without any change in my own code, warnings disappeared. I did not investigate further to find out exactly which package upgrade solved this, but if you are in a position to upgrade Angular, you might want to try that first.

@blockerdude
Copy link

blockerdude commented Jul 13, 2020

Building off of what @PowerKiKi said. I got these issues when I added
"enableIvy": false,
to the angular compile options. However I did just upgrade to angular 10, and on review I had missed upgrading ng-packagr (both the angular devkit and the normal ng-packagr versions). Upon upgrading them to version 10, my warnings went away.

@rajibhasan11
Copy link

Just ignore this warning, that is the best solution :)

@rojasjandro89
Copy link

this ticket is more than 3 years old and it's still happening ... I guess no one cares about a clean ci output anymore 🤷‍♂️

@PowerKiKi
Copy link

PowerKiKi commented May 7, 2021

On the contrary, this issue should be closed as solved, because it is no longer reproducible with latest version.

@karan-kang, @alxhub, could you please close this issue as solved ?

Creating a new lib from scratch with:

ng new my-workspace --create-application=false --strict
cd my-workspace/
ng generate library my-lib

Replace the content of projects/my-lib/src/lib/my-lib.component.ts with the following that contains both QueryList and ElementRef:

import {Component, ContentChildren, ElementRef, Inject, QueryList, ViewChild} from '@angular/core';

@Component({
  selector: 'lib-my-lib',
  template: `
    <p>
      my-lib works!
    </p>
  `,
  styles: [],
})
export class MyLibComponent {
  private window: Window;

  @ContentChildren(MyLibComponent)
  options: QueryList<MyLibComponent> | null = null;

  @ViewChild('gmap') gmapElement: ElementRef | null = null;

  constructor(@Inject('Window') myWindow: any) {
    this.window = myWindow;
  }
}

And this will build correctly with zero warnings:

$ ng build my-lib --prod
Building Angular Package

------------------------------------------------------------------------------
Building entry point 'my-lib'
------------------------------------------------------------------------------
✔ Compiling TypeScript sources through NGC
✔ Bundling to FESM2015
✔ Bundling to UMD
✔ Minifying UMD bundle
✔ Writing package metadata
ℹ Built my-lib

------------------------------------------------------------------------------
Built Angular Package
 - from: /tmp/q/my-workspace/projects/my-lib
 - to:   /tmp/q/my-workspace/dist/my-lib
------------------------------------------------------------------------------
$ ng --version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 11.2.12
Node: 14.16.1
OS: linux x64

Angular: 11.2.13
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1102.12
@angular-devkit/build-angular   0.1102.12
@angular-devkit/core            11.2.12
@angular-devkit/schematics      11.2.12
@angular/cli                    11.2.12
@schematics/angular             11.2.12
@schematics/update              0.1102.12
ng-packagr                      11.2.4
rxjs                            6.6.7
typescript                      4.1.5

@karan-kang
Copy link
Author

@PowerKiKi You are correct, I was not able to reproduce this with latest Angular either. Closing this issue, thanks!

@rojasjandro89
Copy link

rojasjandro89 commented May 11, 2021

@PowerKiKi I (respectfully) disagree. Please see the attachment, I have the same versions you posted. I'm not authorized to show you the code but I can ensure you QueryList is only used as a type for ContentChildren.

This issue is not resolved. There might be other variables involved, but it's not resolved.

Screen Shot 2021-05-11 at 5 26 11 PM

@JoostK
Copy link
Member

JoostK commented May 11, 2021

@rojasjandro89 if you are able to share a minimum reproduction I can look into it. Before doing that though, is this also an issue when building the library using Ivy enabled? We're on the brink of supporting Ivy-compiled libraries using partial compilation (shipping in v12, planned for this week) so I'd be interesting to know if Ivy has the same issue.

@rojasjandro89
Copy link

@JoostK thanks for the quick reply. I enabled Ivy and the warning disappeared. As for the minimum reproduction I'll try to create a stackblitz and I'll post it here but yeah... Ivy (once again) to the rescue 😅

SuperITMan added a commit to SuperITMan/stark that referenced this issue May 25, 2021
Use `type` imports introduced in TypeScript 3.8, fix warnings for imports `OnInit`,
`AfterViewInit`, `OnDestroy`, `ModuleWithProviders`...

More details available on
[False Positive: 'QueryList' is imported from external module '@angular/core'
but never used #710](ng-packagr/ng-packagr#710 (comment))
@github-actions
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.

This action has been performed automatically by a bot.

@github-actions github-actions bot locked and limited conversation to collaborators Jun 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests