-
Notifications
You must be signed in to change notification settings - Fork 12k
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
Provide options to enable/disable the removal of decorators and replacement of resources in a prod build with AOT #9306
Comments
For the sake of completeness, I reference some of the issues I found that are related to this feature request (either because the decorators are removed or because developers have issues with AOT and JIT): angular/angular#15510 |
Yeah, I think we need both options, because we use pure webpack and don't use |
@hansl would you accept a pull request for that? If so, in what form: config parameter, cli parameter, something else? |
Thanks a lot, @ocombe , for providing help for this issue! |
Yes, it flag very need |
I see that some people did nasty hack to remove all decorators that come from angular-cli/packages/@ngtools/webpack/src/transformers/remove_decorators.ts Lines 33 to 37 in a47f024
There should be a better way to decide which decorators should be preserved than preserving all of them. For example, I only need decorated modules from a specific directory. I did some research and it turns out that if you reexport // ngmodule.decorator
import { NgModule } from '@angular/core';
export { NgModule }; import { NgModule } from './ngmodule.decorator'; |
@pawelkondraciuk where do you put this? import { NgModule } from '@angular/core';
export { NgModule };
import { NgModule } from './ngmodule.decorator'; Error
|
Put |
Same error. :( I even added like this: ngmodule.decorator.tsimport { NgModule, ModuleWithProviders } from '@angular/core';
export { NgModule, ModuleWithProviders }; module.tsimport {
NgModule,
ModuleWithProviders
} from './ngmodule.decorator';
@NgModule({
imports: [
etc,
],
// export
declarations: [
etc,
],
providers: [
etc,
forwardRef(() => Boot),
],
exports: [
etc,
],
entryComponents: [],
})
export class CorifeusModule {
constructor(private boot: Boot) {
this.boot.boot();
}
public static forRoot(): ModuleWithProviders {
return {
ngModule: CorifeusModule,
// providers: providers,
};
}
} test module.tsimport { NgModule } from '../../../src/ngmodule.decorator';
@NgModule({
imports: [
HttpClientModule,
BrowserModule,
CorifeusModule,
RouterModule.forRoot(routes),
],
declarations: [
Application,
Http,
Layout,
Color,
AuthHome,
AuthLogin,
],
providers: [
SettingsService
],
bootstrap: [ Application ]
})
export class Module {
constructor(
private settings: SettingsService,
) {
const json = require('../json/settings.core.json');
settings.extend('core', json);
}
}; Same error
It just removes some other decorators, but which??? It's cool for you it works :/ |
|
I looked at it on the latest @ngtools/webpack, but no change on the remove decorators function in 4 months. |
@Paladinium I think you help me a lot before with AOT and JIT at once, so here is a help for you: |
@Paladinium besides, the aot on my pages.corifeus.com is double speed instead of jit so it works! 🔢 |
i just upgraded everything, just removed the decorators and that's it, it works, like magic. |
Thanks, @p3x-robot . It's funny, we do the same workaround as you but with Gradle (which is our main build invoking the CLI - not going into details why) just after npm install. It is renaming removeDecorators by replaceResources in angular_compiler_plugin.js. One could also think of applying such a hack as part of the postinstall hook in packages.json if not using gradle. However, this is very unstable meaning that it can break anytime the CLI changes. This is why I hope that @ocombe , besides being busy with many other tasks, can eventually help to solve this issue. In my view, he understands the pain and the use-cases described in this feature request. @p3x-robot : with our help, others should now be able to figure out what to do. I highly appreciate that you shared it here! If you ask me, we should let the Angular guys do their job and avoid adding further comments. |
Could the commit of marcelamsler be merged on angular-cli? I need also to skip removal of decorators in aot mode :( |
In my view, the commit is only 50% correct. For JIT to work, the resources must also be replaced which is the IF condition just above where @marcelamsler made his change where function 'replaceResources' is called. Therefore, instead of having a narrow argument like 'skipRemoveDecorators', maybe a more general like 'enableJitInAot' might provide a higher level of abstraction. |
Yep I also noticed the build-optimizer option of angular-cli AOT compilation (default: true since Angular 5), is stripping the decorators as well :( so workaround for me, is to apply the hack above, and also to set build-optimizer to false. Definitively too much..... |
but they are not allowing this merge... |
... just to notice ... using JitCompiler together with AOT mode is available right now -> and it means using any HTML code in run-time in fact. The only problem is CLI and its decorators removal when an app is built. If any other way of compiling and building is used (Rollup, SystemJS, CC, ...) then it works just fine because decorators are contained in compiled code via ngc by default and it is necessary to remove them (regexp is the simplest way how to do it) if the minimum bundle sizing is required. |
Is there any update of this feature request? |
i can only this: https://gist.github.com/p3x-robot/e12ed76acb7033638b4179149546bb73 plus i depreciated jit, i only use aot. |
for the size i use gzip... wicked quick pure aot... |
I found a viable solution to this problem. can create an angular element Then insert the script main.js and inline.js at run time and go! you can create and compile components that can be loaded at run time, this technique does not need the application to know the components at compile time and get the benefits of the compiler |
No there is no update...
just set buildOptimizer to "false" and reexport the core decorators if you
need them at runtime. Your own decorator should not be removed by normal
build because it is not a core decorator...
As far as I understand the build optimizer, it does not affect size or
performance in a way that would it make really necessary for a normal sized
app.
…On Mon, 9 Jul 2018, 10:51 psamusev, ***@***.***> wrote:
guys, any updates on it? I faced with this problem during usage of custom
decorator. WIth buildOptimizer: true I'm getting all my classes without
decorators
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#9306 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AD5v9DVCAFtHYWHzmNBWeB-j9uCrAP48ks5uExmCgaJpZM4Rl3tJ>
.
|
@marcelamsler From your example above, do I need to know about the @app/aot.decorators? At the moment during my runtime I'm getting a StaticInjectError: Could this be my DI for the Compiler from @angular/core? |
No, I also use the compiler from core directly. Make sure that all Modules for all components, pipes are passed in in "modules"-input. Also make sure, that your custom components you want to use (and their dependencies are using the re-exported decorators. Here is my current code with some minor improvements (supports replacing/changing template) reexports
Here the dynamic component:
|
@robwormald As others have expressed, there are companies (like mine) that want to use Angular but have use cases which would be very well served by being able to dynamically compile an html template into a component at runtime, knowing the risks and performance implications. You may want to reconsider this as a valid use case. |
@marcelamsler I'm able to make this work without re-exporting the decorators. I only have to set build-optimizer=false. Of course this increases my output main.js file size by 40%. |
@lefoulkrod why not use angular element? |
Can I dynamically compile an html template into a component at runtime without build-optimizer=false ? Any update of this issue? |
this is not something they want to care about ... |
where is my angular 1.x ... |
Is there an update or work around for this issue yet? |
Here are some of my observations relative to this problem (all 3 ways implies aot compilation enabled and combination of lib with custom decorators and project importing it)
The problem is raised only when these factors meet together: optimization enabled (by default), es2015 target (by default) and library with it's own decorators is external to the project (comes from node_modules) Still very waiting this flag (preserving custom annotations from external node_modules lib)! Probably it may be done by providing some ability to export custom decorators with lib module same way as it is done for pipes and services? Angular team, please pay attention to this, your users are unhappy without it! It's actually a kind of trap: you writing custom decorators and all works well until you develop all the stuff. Next you go live of your project and everything wraps into a singularity because angular decides you don't need them as well as they don't and "optimizing" it without any care or choose. Just take a look at this instruction how to achive this functionality here: https://blog.angularindepth.com/converting-typescript-decorators-into-static-code-using-tsquery-tstemplate-and-transforms-8c65d606a517 It's a kind of Fifty Shades of Grey. Do you think it's normal to rewrite AST tree in 2019 to bring this to project? |
I have similar use-case: I need an Angular module which is compiled and stored on a remote server, and loaded into the main app in the runtime. Having in-browser compiler in the AOT build of the main app would solve the issue. But since there is no solution for this yet (at least none of the solutions described above helped me, I was still getting other errors), I ended up with a different approach: compiling my remote module as an AOT bundle, using a custom builder script for that. And that is where this great article came handy: https://blog.angularindepth.com/building-extensible-dynamic-pluggable-enterprise-application-with-angular-aed8979faba5 |
This came up in a CLI meeting recently. @robwormald's previous comment is still a pretty accurate description of our feelings on the matter. Using JIT in a prod application causes a lot of performance and security issues. JIT is intended for development use only, and we don't expect that to change anytime soon. |
Here's a link to a relevant discussion, if anybody still needs AOT-compilation of a separate module which is then included to the main application in the runtime via HTTP request: angular/angular#20875 (comment) |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
This is a feature request referring to the prod build with AOT using the CLI. A more general title would be "Provide options to make the applied transformations configurable". For my use case, it is sufficient to just consider the two specific options described below - but other developers might have other use-cases.
Requirements
It would be very helpful to me and many other developers if the compiler options would provide means to control the removal of decorators in a prod build with AOT. There are two ways that could make it happen. Either in tsconfig.json as a parameter to angularCompilerOptions, e.g.:
Or as a switch to the ng-command, e.g.
ng build --prod --aotRemoveDecorators=false
The wording of such an option is yet to be discussed. I personally would favor to distinguish options that are only valid for either AOT or JIT by having a prefix/suffix in the option's name as indicated.
Additional Requirement
For the use-case described below, it is also important to replace style and template URLs by their content. This is what is done in JIT mode just a few lines above the referenced code (see link below). Now either the proposed option implies this behavior (which I don't like since it is not obvious) or another option gives the developer control for that behavior, too, e.g.
ng build --prod --aotRemoveDecorators=false --aotReplaceResources=true
Use-Case
There are Angular apps that use standard Angular means. To make those applications run fast, it makes sense to use AOT. However, many of those applications also have a need to build Angular components dynamically and invoke the JIT compiler. I am aware that it seems unusual to use JIT and AOT in one app, but it is also a reality that many applications have this need (just do a search for AOT and JIT in the angular github issues). It has also been shown that it is indeed possible to make AOT and JIT work together (e.g. see angular/angular#15510). However, since the CLI removes the decorators in a prod build, the JIT compiler cannot compile the components and is emitting errors like "Please add a @NgModule annotation".
To make it work nowadays, it requires to hand-craft the build yourself using webpack or another bundler, but it is much more complex. Instead, it would be much more convenient to rely on the Angular CLI and use the powerful ecosystem that the CLI provides. The cost of adding such an option seems to me negligible compared to the pain many developers have. And I would highly appreciate if the CLI team would consider it.
The code responsible for the removal
The code responsible for the removal is located here:
angular-cli/packages/@ngtools/webpack/src/angular_compiler_plugin.ts
Line 682 in 5f73a75
Workarounds
I don't know any workaround and I would be very happy to hear some. For example, I was wondering if it is possible to override the function "removeDecorators" to just do nothing? Any other ideas?
The text was updated successfully, but these errors were encountered: