-
Notifications
You must be signed in to change notification settings - Fork 12k
AOT with multiple root module #4624
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
Comments
@hikalkan I think best practice in this case would be to manage this with routes and router guards. You can also lazy load those modules from the router so only the code needed to run would be downloaded. |
I will try the lazy load first to see if it's possible. Thank you @deebloo |
I suppose there is no way of doing that. |
need to be able to select module. Error is thrown with aot on |
@hikalkan did you get things working with the router? |
No. What I did is to create a new RootModule which lazy loads other modules via router. |
@hikalkan ok. that does sound closer to best practice for angular though. |
Hey I have followed this documentation : https://www.aspnetzero.com/Documents/Getting-Started-Angular |
I suppose here is not the best place to ask this question :) Can you write to the aspnetzero forum. |
How long it will take to get a response on forum against this topic? http://forum.aspnetboilerplate.com/viewtopic.php?f=5&t=5201 |
@hansl can you have a look? |
Can anyone from the Angular team confirm the principle behind AoT not supporting multiple entry points? Is it a basic principle of Angular 2+ that there must only ever be one root module and everything has to be part of one monolithic SPA application with centralized routing? This feels like a distinct lack of flexibility that real world applications often require. In my mind AoT needs to just work, regardless of whether or not I have a single monolithic application, multiple sub application or I just want to drop in some components on a static marketing page that is optimized for SEO. |
I've patched the AngularCompilerPlugin to allow for multiple entry points. Are you interested in a PR? |
Anyway, if somebody needs this feature can see the patch here miiihi@fb75650 |
@filipesilva @hansl What would be your recommendation regarding a workaround for multiple entry point apps at this moment? Starting from Angular 5, if we want to use AOT compilation for development builds as well, we cannot do it with Even if we continue using For a description of our particular use case, see my comment here: #7954 (comment) Alternatively, maybe you could suggest how the project should be structured instead of having multiple entry points, so that it would work with |
Having multiple app modules is necessary for us too. We have a very small AppIncognitoModule that checks if localstorage is available since safari incognito (and possibly other small browsers) have this limitation. If localstorage is disabled then we make an API call to retrieve it. This allows us to readily have the data available once the regular AppModule bootstraps since we have them promise chained together. Any suggestions on how else to do this would be welcome. |
I am also interested in something like this. We have several apps (different web landing pages, mobile, desktop, embed, etc.). I don't think it makes much sense to view these as different "routes", we'd really like to have a single build for all the apps (in part so we can avoid compiling shared code multiple times). |
Recently I've just landed on the matter of this subject. In my case I do have to manage having Angular working within a JSF project. The project is an old fashioned one and cannot use pretty much the angular goodies like SPA, or having the whole app holding form one angular root node. In order to use components in such monolithic way I've structured modules per container components. This offers the possibility of locating them where they are needed on the page without relying on a root node. Of course, for this purpose it would be interesting a react or polymer solution but as per client's requirement is not possible. The shared state can be achieved through a factory provider which uses some global window object. This factory checks if the object property is present in the global scope and return it, in case not just create the new object. The same provider will be set on the modules used in the same page. The object can be any RxJS Subject object or a Mobx instance or whatever you like. Also can be used redux but I think is an overwhelming approach. To make these modules works on the same page, I've just bootstrap them to the platform.bootstrapModule(AModule);
platform.bootstrapModule(BModule); But the main problem resides when deploying within a JSF page. It just don't work. So knowing about two compilations modes, I've tried out the AOT way. Apart from some peculiarities of AOT strictness everything looked fine until the project testing. The modules were not being mounted. The message error pointed out the first module being mounted was a null instance. After some hours figuring out why this was happening, I removed one of the bootstrap calls. It worked! I still could not discover how is happening but why. Anyway, this is another subject. Because the only way to work with AOT was having only one module bundler I had to figure it out how to solve this issue. Well, the solution came reading a post from Maximus Koretskyi about manually bootstrap different components. This approach allows to place the components wherever we like, not depending on a root node. The only requirement is defining in the markup a The key points are to achieve this manual approach are specified below:
@NgModule({
imports: [ BrowserModule ],
declarations: [ AComponent, BComponent ],
entryComponents: [ AComponent, BComponent ]
})
const components = [AComponent, BComponent];
@NgModule({
imports: [ BrowserModule ],
declarations: [ AComponent, BComponent ],
entryComponents: [ AComponent, BComponent ]
})
export class AppModule {
ngDoBootstrap (app) {
components
.forEach(component => this.bootstrapComponent(app, component));
}
bootstrapComponent (app, component) {
const mountName = component.mountName;
const mountPoint = document.querySelector(`#${mountName}`);
if (isNil(mountPoint)) {
console.error(`${mountPoint} id is not present in DOM`);
return;
}
// Create the mounting point and append into DOM
const componentElement = document.createElement(mountName);
mountPoint.appendChild(componentElement);
// Bootstrap the new component
app.bootstrap(component);
}
} I've added in the component a static property called And that's pretty much it. Well, of course, don't forget bootstrap the new module. This way allows having several components (think of them as apps) placed wherever you like in the page using an AOT approach. Please refer to this post for much on this topic. Also check this app demo to see it working. I hope this approach can help until AOT supports having multiple root modules. Best Regards. |
While this get fixed, I published a npm package with some modifications to handle multiple entry modules: |
Heya, is this still a problem? Can someone provide a repro using the current version of Angular CLI please? |
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. |
OS?
Windows 10
Versions.
Node v6.9.1
Npm v3.10.8.
ng-cli beta.30
Repro steps.
In brief, I want to bootstap one of my root modules based on an async call to the server. So, my code is like that:
Given workaround works fine when AOT is disabled. But, when AOT is enabled, it only compiles AppModule and the logic above can not work.
I know AOT statically analysis main.ts and bundles all module files starting from the root module. But I also believe my case is not so unique. I simple want to bootstrap a different module if user has not logged in.
So, isn't that possible or is there a way of doing it? If not, how do you recommend as a best practice? Should I merge 2 modules and implement the logic with routes and route guards?
Thanks.
The text was updated successfully, but these errors were encountered: