Skip to content

Could/would/will code using COMPILER_PROVIDERS be supported by AOT? #11780

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

Closed
Radim-Kohler opened this issue Sep 21, 2016 · 35 comments
Closed

Could/would/will code using COMPILER_PROVIDERS be supported by AOT? #11780

Radim-Kohler opened this issue Sep 21, 2016 · 35 comments
Labels
area: compiler Issues related to `ngc`, Angular's template compiler freq1: low type: use-case
Milestone

Comments

@Radim-Kohler
Copy link

When I run a command

>"node_modules/.bin/ngc" -p ./

I get the error:

Error: Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function (position 65:17 in the original .ts file), resolving symbol COMPILER_PROVIDERS in .../node_modules/@angular/compiler/src/compiler.d.ts,

That all is related to this piece of code

@NgModule({
    ...
    providers: [
        COMPILER_PROVIDERS
    ],  
})
export class AppModule {}

Once COMPILER_PROVIDERS are not declared

    providers: [
        // COMPILER_PROVIDERS

then AOT works as expected... just ... as also expected, the app is not working (simply, COMPILER_PROVIDERS are needed for it)

I did see this "encouraging disclaimer"

/**
 * @module
 * @description
 * Entry point for all APIs of the compiler package.
 *
 * <div class="callout is-critical">
 *   <header>Unstable APIs</header>
 *   <p>
 *     All compiler apis are currently considered experimental and private!
 *   </p>
 *   <p>
 *     We expect the APIs in this package to keep on changing. Do not rely on them.
 *   </p>
 * </div>

So - it is experimental, private, "I cannot rely on it" ... but I need it.

Please, am I doing something wrong? or is intended ... COMPILER_PROVIDERS will never be supported by AOT?

@ceolter
Copy link

ceolter commented Sep 22, 2016

+1

@vicb
Copy link
Contributor

vicb commented Sep 22, 2016

In AOT there is no need for compiler (as templates have already been compiler) which explains why you can not include it.

@seanlandsman
Copy link

Unless you're developing a library which creates components dynamically - as we are.

Our users want to be able to use AoT compiling on their projects, but we're unable to compile ours first (and generate the necessary metadata files) due to the above issue

@Radim-Kohler
Copy link
Author

Well, the application could be pretty large, robust at the end....and there could be up to 99% of components static ready for AOT. And only few could use RuntimeCompiler and/or ComponentFactoryResolver.

So, @vicb are you saying that we cannot pre-compile that application at all? Just because of these few components, which really will be re/compiled at runtime.

If the answer is all or nothing... I doubt I'd think it is a design decision I would support, vote for

Is there some workaround at least? I tried to move these providers among modules.. but if they are loaded to AppModule ... no success. Maybe lazy load?

@chuckjaz chuckjaz added the area: core Issues related to the framework runtime label Oct 4, 2016
@georgeedwards
Copy link

I get this issue on node 6.7.0 but not on 4.7.0

@zoechi
Copy link
Contributor

zoechi commented Oct 10, 2016

See also the first paragraph after the modules list in https://github.com/angular/angular/blob/f5b0e22d352fd00cee1dc9016e85bdef94256e62/docs/PUBLIC_API.md

@h2qutc
Copy link

h2qutc commented Oct 10, 2016

Hello,
I have updated an application using Ionic2 RC. In my application, I attempt to load/create a component dynamically. It worked fine when debugging, but when I tried to build android, I had the same error. The problem is that I declared COMPILER_PROVIDERS in the "providers" of app.module like that:
providers: [ COMPILER_PROVIDERS, ...APP_SERVICES ]

Is there any workaround ou a another method to use COMPILER_PROVIDERS with AOT?

@hadrien-toma
Copy link
Contributor

hadrien-toma commented Oct 27, 2016

For me, when importing COMPILER_PROVIDERS I have the error described in this issue.

Besides, without this import, using only Compiler from @angular/core also leads to success when debugging but fails when building.

The error I have :

0     791231   error    EXCEPTION: Runtime compiler is not loaded
1     791233   error    ORIGINAL STACKTRACE:
2     791234   error    Error: Runtime compiler is not loaded
    at q (http://192.168.1.17:8100/build/main.js:1:7415)                                                                             
    at t.compileModuleAndAllComponentsAsync (http://192.168.1.17:8100/build/main.js:6:2149)                                          
    at t.ngOnChanges (http://192.168.1.17:8100/build/main.js:23:18773)                                                               
    at e.detectChangesInternal (http://192.168.1.17:8100/build/main.js:31:28384)                                                     
    at e.t.detectChanges (http://192.168.1.17:8100/build/main.js:8:11183)                                                            
    at e.t.detectViewChildrenChanges (http://192.168.1.17:8100/build/main.js:8:11731)                                                
    at e.detectChangesInternal (http://192.168.1.17:8100/build/main.js:31:21943)                                                     
    at e.t.detectChanges (http://192.168.1.17:8100/build/main.js:8:11183)                                                            
    at t.detectChanges (http://192.168.1.17:8100/build/main.js:7:23007)                                                              
    at e._viewInsert (http://192.168.1.17:8100/build/main.js:15:4217)                                                                
3     791287   error    EXCEPTION: Runtime compiler is not loaded
4     791291   error    ORIGINAL STACKTRACE:
5     791298   error    Error: Runtime compiler is not loaded
    at q (http://192.168.1.17:8100/build/main.js:1:7415)                                                                             
    at t.compileModuleAndAllComponentsAsync (http://192.168.1.17:8100/build/main.js:6:2149)                                          
    at t.ngOnChanges (http://192.168.1.17:8100/build/main.js:23:18773)                                                               
    at e.detectChangesInternal (http://192.168.1.17:8100/build/main.js:31:28384)                                                     
    at e.t.detectChanges (http://192.168.1.17:8100/build/main.js:8:11183)                                                            
    at e.t.detectViewChildrenChanges (http://192.168.1.17:8100/build/main.js:8:11731)                                                
    at e.detectChangesInternal (http://192.168.1.17:8100/build/main.js:31:21943)                                                     
    at e.t.detectChanges (http://192.168.1.17:8100/build/main.js:8:11183)                                                            
    at t.detectChanges (http://192.168.1.17:8100/build/main.js:7:23007)                                                              
    at e._viewInsert (http://192.168.1.17:8100/build/main.js:15:4217)                                                                
6     791309   error    [object Object]
7     791455   log      DEVICE READY FIRED AFTER, 465, ms

Ionic version : 2.0.0-rc1

Any idea of what to do?

@DzmitryShylovich
Copy link
Contributor

Don't use runtime compiler and aot.

@hadrien-toma
Copy link
Contributor

@DzmitryShylovich do you have an idea of how to answer the need in an other way? The need being : to be able to dynamically create a component based on runtime configuration?

@DzmitryShylovich
Copy link
Contributor

then the only answer is jit

@hadrien-toma
Copy link
Contributor

Okay, so if I want to build a component just on time, what I have to do? I am not really experienced about that...

@DzmitryShylovich
Copy link
Contributor

You should use ComponentFactoryResolver http://plnkr.co/edit/kkM1aR4yPcIqeBhamoDW?p=preview

@hadrien-toma
Copy link
Contributor

Okay, it is interesting, thank you for sharing. After looking at API reference, I am now wondering how I could give arguments for configuring the component like template. Maybe you know what I have to do and/or where I have to go to deal with it in depth?

@hadrien-toma
Copy link
Contributor

hadrien-toma commented Oct 27, 2016

I found this article of @laco0416 that seems to answer the need.

@hadrien-toma
Copy link
Contributor

Finally, I am hardly following @Radim-Kohler and hope that we will be able to use COMPILER_PROVIDERS with AoT (maybe with some additionnable configuration, being aware of the drawbacks).

@arwindgao
Copy link

+1

@korywkoch
Copy link

+1

@teropa
Copy link
Contributor

teropa commented Jan 20, 2017

@hadrien-toma See here for a solution that bypasses the use of COMPILER_PROVIDERS and creates a JitCompilerFactory manually. With that you can dynamically create components.

@avbentem
Copy link

avbentem commented Jan 25, 2017

Just in case it helps anyone, the following still works for me in an Angular 2.4.4 project using Angular CLI 1.0.0-beta.26 and https://github.com/laco0416/angular2-component-outlet 3.0.1 (I know, we should migrate to ng-dynamic).

In main.ts:

import {COMPILER_PROVIDERS} from '@angular/compiler';
...
// Using "ng serve --aot" or "ng build --aot" will automatically replace this for AOT:
platformBrowserDynamic([...COMPILER_PROVIDERS]).bootstrapModule(AppModule);

In AppModule:

import {Compiler} from '@angular/core';
import {JitCompiler} from '@angular/compiler';

@NgModule({
    ...
    providers: [
        {
            provide: Compiler,
            useExisting: JitCompiler
        },
        provideComponentOutletModule({
            imports: [CommonModule]
        }),

I'll admit I'm not 100% sure what I'm doing here. But this works just fine for ng build --prod --aot, ng serve and ng serve --aot. And I love the speed that AOT gives me, while still allowing for dynamic templates where we need them.

Without the above, ng build --aot and ng serve --aot run fine, but the application rightfully throws Error: Runtime compiler is not loaded ... at ComponentOutlet.ngOnChanges.

@arjenbrandenburgh
Copy link

@avbentem does solve the issue, however, it adds 1.21MB to the vendor bundle. One of the reasons of course to use AoT is to having to avoid to include a compiler.

Is there any way to at least only include the compiler on a module level, so the added size is in a chunk instead of the vendor?

@SebastianFree
Copy link

Especially with Angular CLI being all AOT please seriously reconsider adding a feature that allows creating truly dynamic components at runtime!
By 'truly dynamic' I mean those components that have HTML templates that can not be put into predefined components and that cannot be enumerated up front (and then altered with a 'switch component' as proposed in other articles). There has to be a possibility to generate those components with AOT, just like Radim-Kohler says: 99.9% of an app will be AOT, but then there is that small part that is really dynamic.
For now I can use the JitCompiler with Angular CLI using JitCompilerFactory, but this only works in dev mode. In production mode everyone with this issue is screwed atm.

@SebastianFree
Copy link

@DzmitryShylovich Thanks, but I knew this article before. I was also able to use the JitCompiler before.
The question is - how to create that dynamic component? The JitCompiler needs to compile a full NgModule, not just a component. This Module has to be created at runtime just like the component since its 'declarations' (the dynamic component) can't be known at AOT compile time.
Please have a look at angular/angular-cli#5275 to see some code. The 'type' parameter to 'createComponentFactory' there is a fresh component, created just before with a very custom HTML template, created in code.
In the linked StackOverflow question someone answered that using a currying form of the decorators would do the trick but that just creates a different problem (custom module not found, while built-in modules do work).
It seems so well possible to use AOT and dynamic components at the same time, at least it feels very close to a solution. I would appreciate it a lot if you could help. Thanks!

@patrikx3
Copy link

Same error here, I cannot use dynamic compiler.
I need both AOT and the compiler. Why cannot I add it in?

@DzmitryShylovich
Copy link
Contributor

@patrikx3 see #11780 (comment)

@richardsengers
Copy link

@DzmitryShylovich thanks for all the effort, but all your references are pointing to examples where the component and the template html are statically available.
What people want is a dynamic component template, where @Component({template: templateString}) is possible

Correct me if I'm worng but I haven't found any solution to this problem concerning AOT

@patrikx3
Copy link

a tried jit, but aot is broken together. looks like aot and jit together not working,
though if you want jit and aot together , i think it is nonsense. bigger package, max same speed, more complex
if you use jit, easier leave it out.

@teropa
Copy link
Contributor

teropa commented Apr 12, 2017

if you use jit, easier leave it out.

I think there would be value in mixing JIT and AoT - if it was possible. We have an application similar to some of the commenters above, where 90% is statically known and could be compiled ahead of time to gain the start-up time benefits. But then there are individual sections that are dynamically compiled. We can't mix the two right now.

@patrikx3
Copy link

I get this error:
#15510

Have to wait for it.

@maxbellec
Copy link

I haven't tested it, but there is a proposed solution here that seems to have worked for at least two people

#15510 (comment)

@akvaliya
Copy link

Is there any plan to support this? I am also facing same issue in Angular 8. I have only one page which needs dynamic component. I can't use aot because of this error.

@osmanmeer
Copy link

osmanmeer commented Nov 1, 2019

Is there any plan to support this? I am also facing same issue in Angular 8. I have only one page which needs dynamic component. I can't use aot because of this error.

I'm trying to do the same thing, except I'm on Angular 7 still. Looks like there is an option of using "import()" if you upgrade to Angular 8. Have you tried this? https://blog.angularindepth.com/automatically-upgrade-lazy-loaded-angular-modules-for-ivy-e760872e6084

@pkozlowski-opensource pkozlowski-opensource added area: compiler Issues related to `ngc`, Angular's template compiler and removed area: core Issues related to the framework runtime labels Feb 21, 2020
@ngbot ngbot bot modified the milestones: Backlog, needsTriage May 28, 2020
@alxhub
Copy link
Member

alxhub commented May 28, 2020

I'm going to close this as a duplicate of #15510, which has a lot of other discussion on the topic.

The tl;dr is that this wasn't ever a design goal of Angular View Engine, but it was in Angular Ivy, and so in Ivy you can happily write an AOT app that loads the JIT compiler (even lazy-loads it!) to compile and render a few dynamic components.

@alxhub alxhub closed this as completed May 28, 2020
@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 Jun 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: compiler Issues related to `ngc`, Angular's template compiler freq1: low type: use-case
Projects
None yet
Development

No branches or pull requests