valor-software / ngx-bootstrap

Fast and reliable Bootstrap widgets in Angular (supports Ivy engine)
https://valor-software.com/ngx-bootstrap
MIT License
5.53k stars 1.69k forks source link

Angular v10 & ngx-bootstrap v6.0.0 in libraries build issue [some workaround here] #5858

Closed roopeshchinnakampalli closed 4 years ago

roopeshchinnakampalli commented 4 years ago

Bug description:

When I upgrade to v6.0.0 version with Angular v10 Library project, I've been thrown with the below error -

Error during template compile of 'CoreModule' Function calls are not supported in decorators but 'PopoverModule' was called. Error during template compile of 'CoreModule' Function calls are not supported in decorators but 'TabsModule' was called. Error during template compile of 'CoreModule' Function calls are not supported in decorators but 'TooltipModule' was called. Error during template compile of 'CoreModule' Function calls are not supported in decorators but 'ModalModule' was called. Error during template compile of 'CoreModule' Function calls are not supported in decorators but 'BsDropdownModule' was called.

In the above, I've added the bootstrap, in CoreModule, like below -

import { PopoverModule } from 'ngx-bootstrap/popover'; import { TabsModule } from 'ngx-bootstrap/tabs'; import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { ModalModule } from 'ngx-bootstrap/modal';

P Versions of ngx-bootstrap, Angular, and Bootstrap:

ngx-bootstrap: v6.0.0

Angular: v10

Bootstrap: 4.0

Build system: Angular CLI, System.js, webpack, starter seed: Angular CLI

Expected behavior

Build should happen. It was working fine with Angular v9.x & v5.3.2.

roopeshchinnakampalli commented 4 years ago

I've tried adding "NO_ERRORS_SCHEMA" and now it started throwing this error -

There is no directive with "exportAs" set to "bs-popover" ("-popover" placement="bottom" [adaptivePosition]="false" container="body" [outsideClick]="true" [ERROR ->]#pop3="bs-popover" (onShown)="popUser=true; popSettings=false" (onHidden)="popUser=false"> <div ")

I',m using the popover like this -

<a href="javascript:;" [popover]="userProfilePop" [ngClass]="{'active': popUser}" placement="bottom" [adaptivePosition]="false" container="body" [outsideClick]="true"

pop3="bs-popover" (onShown)="popUser=true; popSettings=false" (onHidden)="popUser=false">

<ng-template #userProfilePop>

daniloff200 commented 4 years ago

@roopeshreddy that's strange, and looks like ng-packagr or Angular issue, like https://github.com/angular/angular/issues/23609

Can you share some repo, when I can check that and try to play with that

I wasn't able to reproduct that with 10.0.2 versions of Angular-related dependencies in the local demo app, so, wanna see your app

roopeshchinnakampalli commented 4 years ago

@daniloff200 On Interesting note, this is not throwing error in a application project. It's throwing only in the Library Project.

We've an internal library and ngx-bootstrap is used as a dependency!

daniloff200 commented 4 years ago

Well, okay, let's do it another way

Can you show me the CoreModule, the component, when you saw this issue, and, I think, angular-cli.json / tsconfig.json?

roopeshchinnakampalli commented 4 years ago

Sure, here you go -

tsconfig.lib.json

{ "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "../../out-tsc/lib", "target": "es2015", "declaration": true, "inlineSources": true, "downlevelIteration": true, "experimentalDecorators": true, "removeComments": true, "importHelpers": true, "sourceMap": true, "lib": ["dom", "es2018"], "moduleResolution": "node", "module": "es2020", "typeRoots": ["node_modules/@types"]

}, "angularCompilerOptions": { "skipTemplateCodegen": true, "strictMetadataEmit": true, "fullTemplateTypeCheck": true, "strictInjectionParameters": true, "enableResourceInlining": true }, "exclude": ["src/test.ts", "*/.spec.ts"] }

CoreModule.ts

import { PopoverModule } from 'ngx-bootstrap/popover'; import { AccordionModule } from 'ngx-bootstrap/accordion'; import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { CollapseModule } from 'ngx-bootstrap/collapse';

imports: [ RouterModule, CommonModule, CommonutilModule, DragulaModule.forRoot(), DynamicModule, FormsModule, PopoverModule.forRoot(), AccordionModule.forRoot(), BsDropdownModule.forRoot(), CollapseModule.forRoot(), PlatformModule ],

In Component HTML, I'm using like this -

<a href="javascript:;" [popover]="userProfilePop" [ngClass]="{'active': popUser}" placement="bottom" [adaptivePosition]="false" container="body" [outsideClick]="true"

pop3="bs-popover" (onShown)="popUser=true; popSettings=false" (onHidden)="popUser=false">

<ng-template #userProfilePop>

roopeshchinnakampalli commented 4 years ago

@daniloff200 Here you go with the repo - https://github.com/roopeshreddy/ngx-bootstrap-issue

If we build with --prod, then it's failing, ng build my-lib --prod

My observation is, It's failing if we disable the "Ivy" flag in tsconfig.

roopeshchinnakampalli commented 4 years ago

I see that, enableIvy flag is set to true for your library, which shouldn't be case as per Angular team! https://github.com/valor-software/ngx-bootstrap/blob/development/src/tsconfig-ivy.spec.json

Hence it's forcing all to compile with Ivy mode only!

daniloff200 commented 4 years ago

@roopeshreddy you can try to make a fork of repo, change it there, attach it to your library, and check, will it work, or not If everything will be good, feel free to submit a PR, and we will make a new version with a fix later on

roopeshchinnakampalli commented 4 years ago

@daniloff200 Looks like you're not using that tsconfig while building. May be some other issue!

daniloff200 commented 4 years ago

Yeah, that was strange for me, because, all ivy-related stuff was removed, during the migration to 9 Angular (except this config, maybe, which also not needed here)

roopeshchinnakampalli commented 4 years ago

Yeah! Irony is it's failing if you set to the Ivy to false 😀

Since We're using internal library, which may be fine for now, but what if any library consumer switch to 'ViewEngine' mode.

We may have to wait till this gets resolved!

roopeshchinnakampalli commented 4 years ago

Can we ask @valorkin to take a look once? May be he can sense something on this?

valorkin commented 4 years ago

I honestly tried, but can't reproduce. Can you give me some small repo with reproduction?

fscali commented 4 years ago

Hi, I am experiencing the same problem that @roopeshreddy pointed out: with Angular 10, when I build a library that imports a module fron ngx-bootstrap@6 I have the error. The same error doesn't occur if I build an application that uses the same ngx-bootstrap module

Here is my sample repo: https://github.com/fscali/ngx-bootstrap-angular10

By running: ng build --prod --project=my-lib

I get this error:

ERROR: Error during template compile of 'MyLibModule' Function calls are not supported in decorators but 'ModalModule' was called.

An unhandled exception occurred: Error during template compile of 'MyLibModule' Function calls are not supported in decorators but 'ModalModule' was called.

Thanks!

roopeshchinnakampalli commented 4 years ago

I honestly tried, but can't reproduce. Can you give me some small repo with reproduction?

@valorkin Thanks for your effort. Here's the repo - https://github.com/roopeshreddy/ngx-bootstrap-issue

hieutranagi47 commented 4 years ago

I faced the same problem, but when I enabled ivy in tsconfig.app.json file, the problem solved:

{
  ...
  "angularCompilerOptions": {
    "enableIvy": true
  },
  ...
}
roopeshchinnakampalli commented 4 years ago

I faced the same problem, but when I enabled ivy in tsconfig.app.json file, the problem solved:

{
  ...
  "angularCompilerOptions": {
    "enableIvy": true
  },
  ...
}

Yes, you're right. Issue will be resolved if you enable Ivy. But libraries shouldn't enable Ivy!

daniloff200 commented 4 years ago

hey, @fscali I've found a solution, that, you can use (I think)

So, generally, the issue , that we discussed here related to forRoot() / forChild() methods. If you try to import just a ModalModule, the issue will be fixed (but, modals will be broken)

import { ModuleWithProviders, NgModule } from '@angular/core';
import { MyLibComponent } from './my-lib.component';
import { ModalModule } from 'ngx-bootstrap/modal';

export const modalModuleForRoot: ModuleWithProviders<ModalModule> = ModalModule.forRoot()

@NgModule({
  declarations: [MyLibComponent],
  imports: [
    modalModuleForRoot
  ],
  exports: [MyLibComponent]
})
export class MyLibModule { }

Can you try this solution, and share results with me?

@roopeshreddy I've tried to use the same for popover, but, no luck, continue to investigate

UPDATE -> solution added in https://github.com/fscali/ngx-bootstrap-angular10/pull/2

daniloff200 commented 4 years ago

@roopeshreddy I've tried the same approach, as above, and get a

  Function calls are not supported in decorators but 'PopoverModule' was called.
Unexpected value 'undefined' imported by the module 'MyLibModule in /home/dmitry/ngx-bootstrap-issue/projects/my-lib/src/lib/my-lib.module.ts'

An unhandled exception occurred: Error during template compile of 'storeModuleForRoot'
  Function calls are not supported in decorators but 'PopoverModule' was called.
Unexpected value 'undefined' imported by the module 'MyLibModule in /home/dmitry/ngx-bootstrap-issue/projects/my-lib/src/lib/my-lib.module.ts'

I have thoughts, that, it can be related to some tsconfig / cli settings. Could you, please, compare all that stuff to @fscali example repo? Because, for him it helped (I HOPE), so, maybe some other stuff, that has to be changed.

UPDATED:

I've even tried to copypaste your html, related to popover, to the component in this repo, and added the same fix for module, and it worked! So, maybe, some other things should be checked. But, looks like, for this repo it works

Check this, please https://github.com/fscali/ngx-bootstrap-angular10/pull/2

roopeshchinnakampalli commented 4 years ago

Thanks @daniloff200 I will check it out and get back to you ASAP.

fscali commented 4 years ago

Hi @daniloff200 I can confirm that the solution you provided actually works in my sample repository and it's important the "export" statement..otherwise it wouldn't work. So starting from Angular 10 we will have to use this pattern in Angular Libraries? Anyway on Monday I will test this solution on a much more complex project (which is the real scenario where I first experienced the issue) and let you know the results.

Thanks!

daniloff200 commented 4 years ago

@fscali well, it's hard to give a 100% correct answer about that. I don't think it's because of Angular 10, it's, maybe, because of Ivy. However, issues with the same error were described even in 2018 https://stackoverflow.com/questions/51475871/angular-6-prod-function-calls-are-not-supported-in-decorators-but-module-was/52016077 https://github.com/dschnelldavis/angular2-json-schema-form/issues/273

and with 8 version of Angular, long time ago https://github.com/angular/angular/issues/30988 https://github.com/angular/angular/issues/32694

The main point, that I found, is, that you can't use any other code in forRoot/forChild , before return statement. But, in ngx-bootstrap we don't have any code in forRoot.

static forRoot(): ModuleWithProviders<ModalModule> { return { ngModule: ModalModule, providers: [BsModalService, ComponentLoaderFactory, PositioningService] }; }

In conclusion, a lot of different ways to fix that described in https://github.com/angular/angular/issues/23609 , also, with a response about that from Angular team devs

Also, very useful link -> https://medium.com/angular-in-depth/solving-aot-error-in-ngrx-function-calls-are-not-supported-in-decorators-5c337381457a , I've found an inspiration for solution, I've used, here

UPD: the same way to fix that was found here -> https://github.com/angular/angular/issues/23609#issuecomment-407191955

fscali commented 4 years ago

Hi I just tested the proposed solution in another repository, used in my company, and unfortunately the same approach doesn't work... I think this issue deserves a more deep investigation :(

daniloff200 commented 4 years ago

@fscali sad news. You can try to go through ideas from issue, mentioned above, maybe, you found something useful

roopeshchinnakampalli commented 4 years ago

Hey All, Somehow it's not working for me :(

ERROR: Error during template compile of 'modalModuleForRoot' Function calls are not supported in decorators but 'PopoverModule' was called. Unexpected value 'undefined' imported by the module 'MyLibModule in C:/Users/wb527065/source/demo/ng-dynamic-comp/projects/my-lib/src/lib/my-lib.module.ts' Can't bind to 'popover' since it isn't a known property of 'a'. (" href="javascript:;" class="btn btn-default btn-secondary" [ERROR ->][popover]="test" popoverTitle="Popover on top" placement="top" ")

May be I need to play with tsconfig? I've copied my existing project tsconfig which was working fine with Angular v9.x an ngx-bootstrap v5.3.x

daniloff200 commented 4 years ago

@roopeshreddy yeah, maybe. My initial thoughts was, that your and fscali's project have some differences in tsconfigs

l-robinson commented 4 years ago

I've just spent the afternoon trying to get this working and after copying fscali/ngx-bootstrap-angular10 over the top of my existing project, I finally got it to build. It looks like older projects will have the following config in tsconfig.base.json:

    "angularCompilerOptions": {
        "fullTemplateTypeCheck": true,
        "strictInjectionParameters": true
    }

When creating a new project with Angular 10, this is not there. Once I removed those options from my existing project, the build was successful. It seems this might have been an oversight and something that should happen in the ng update migration.

fscali commented 4 years ago

I can confirm that finally I had my project compiling correctly. In order for it to work I had to produce two changes:

Thank you!

daniloff200 commented 4 years ago

Great news, @fscali !!! Thanks for your info!

roopeshchinnakampalli commented 4 years ago

Sorry for the delayed response! Thanks @daniloff200 for all the help!

I've tried the @l-robinson suggestion and it's working fine. I'm surprised, when we're building the library why it's taking the base - tsconfig.base.json file angularCompilerOptions instead of the library - tsconfig.lib.json

Anyway for now, I'm closing this issue since this is solved with these configurations.

daniloff200 commented 4 years ago

Yay! What a great news ^_^ !

Thanks @l-robinson for help too!!!

jziggas commented 4 years ago

I think there is still something going on here because I can set those angularCompilerOptions to false in my tsconfig.spec.json and my unit tests still fail

hakimio commented 4 years ago

@roopeshreddy even there is a workaround, the issue is not fixed. This bug report should stay open until it's actually fixed in ngx-bootstrap.

EDIT: also, changes in the config are not the only thing that's needed to work-around the issue. Also, forRoot() changes (as mentioned by @daniloff200 ) are required as well.

Gillardo commented 4 years ago

I am still getting this error and the above does not fix my project.

Why is this project still using forRoot instead of using the following for any services?

@Injectable({
    providedIn: 'root'
})
valorkin commented 4 years ago

backward compatibility, there are several PRs for ngx-bs v7, to replace forRoot with provideIn

FabianaFaria-awin commented 4 years ago

The fix described here works for the build but when running the extracting tool xi18n I still get the error: Function calls are not supported in decorators but 'AccordionModule' was called

hieutranagi47 commented 4 years ago

The fix described here works for the build but when running the extracting tool xi18n I still get the error: Function calls are not supported in decorators but 'AccordionModule' was called

You created your project by Angular CLI 10.x or you upgraded your project from Angular old version? If you upgraded your project, what is the first version of Angular when you initialized your project?

FabianaFaria-awin commented 4 years ago

@hieutranagi47 the project was upgraded from ng9.x to ng10.x `Angular CLI: 10.0.5 Node: 12.16.1 OS: darwin x64

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

Package Version

@angular-devkit/architect 0.1000.5 @angular-devkit/build-angular 0.1000.5 @angular-devkit/build-optimizer 0.1000.5 @angular-devkit/build-webpack 0.1000.5 @angular-devkit/core 10.0.5 @angular-devkit/schematics 10.0.5 @angular/cdk 10.1.2 @angular/cli 10.0.5 @angular/material 10.1.2 @ngtools/webpack 10.0.5 @schematics/angular 10.0.5 @schematics/update 0.1000.5 rxjs 6.5.5 typescript 3.9.7 webpack 4.43.0`

I was first initialised with ng9x

hieutranagi47 commented 4 years ago

@FabianaFaria-awin I faced the same problem with you, I solved it by enabling Ivy in tsconfig.app.json, and make sure that you are using ngx-bootstrap version 6.x. However, Ivy is used by default in Angular 10, so we can remove "angularCompilerOptions": { "enableIvy": true },

FabianaFaria-awin commented 4 years ago

@haridevelops yes it is enabled by default, I don't have any angularCompilerOptions in my tsconfig and I am using ngx-bootstrap version 6.x So you're saying you are able to run ng xi18n ? and you're using AccordionModule?

Gillardo commented 4 years ago

I still get this error, but setting enableIvy=true seems to fix it, although i am not sure if we are supposed to be using Ivy.

hieutranagi47 commented 4 years ago

@haridevelops yes it is enabled by default, I don't have any angularCompilerOptions in my tsconfig and I am using ngx-bootstrap version 6.x So you're saying you are able to run ng xi18n ? and you're using AccordionModule?

I get the problem like you when I run ng xi18n, but I can run the project in dev mode and build production. :(

hieutranagi47 commented 4 years ago

@haridevelops yes it is enabled by default, I don't have any angularCompilerOptions in my tsconfig and I am using ngx-bootstrap version 6.x So you're saying you are able to run ng xi18n ? and you're using AccordionModule?

The ngx-bootstrap verion 6.1.0 can work well with ng xi18n. try: yarn upgrade ngx-bootstrap
If you're still facing the issue, have a look at this

alanj853 commented 3 years ago

hey, @fscali I've found a solution, that, you can use (I think)

So, generally, the issue , that we discussed here related to forRoot() / forChild() methods. If you try to import just a ModalModule, the issue will be fixed (but, modals will be broken)

import { ModuleWithProviders, NgModule } from '@angular/core';
import { MyLibComponent } from './my-lib.component';
import { ModalModule } from 'ngx-bootstrap/modal';

export const modalModuleForRoot: ModuleWithProviders<ModalModule> = ModalModule.forRoot()

@NgModule({
  declarations: [MyLibComponent],
  imports: [
    modalModuleForRoot
  ],
  exports: [MyLibComponent]
})
export class MyLibModule { }

Can you try this solution, and share results with me?

@roopeshreddy I've tried to use the same for popover, but, no luck, continue to investigate

UPDATE -> solution added in fscali/ngx-bootstrap-angular10#2

@daniloff200 , this solution worked for me. I had almost the exact same problem as @roopeshreddy .