-
Notifications
You must be signed in to change notification settings - Fork 12k
Multiple entryModule support #12107
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
From @james-criscuolo on May 7, 2018 20:41 I am also running into this issue while upgrading. I used to be able to use the ngtools/webpack loader without the plugin, which allowed me to get around this issue. I would do this in development, then for production builds I would have the significantly longer build where I sent each entry point individually through webpack. Now I have no choice but to use the plugin in development, so my build process will suffer tremendously once I complete the upgrade. |
From @artonge on May 9, 2018 9:3 Could this feature be backported to version 1.10.2 ? Any ETA ? When trying to install |
From @filipesilva on May 24, 2018 17:33 This is something we are interested it, but not for 6.x. We will re-evaluate when the Angular Ivy compiler is available as that changes how this feature would work. |
From @sherlock1982 on May 24, 2018 17:54 Could you please provide a kind of a workaround for this? Because I don't quite understand how can I code-split two endpoints in one app. Or for example how a custom element and an app can code-split angular. |
From @artonge on May 25, 2018 9:32 Thanks for the answer @filipesilva ! As @sherlock1982 asked, could you provide some workaround ? Or tell us if my solution in #875 is safe to use ? |
I would love to find a solution as well. |
is it still relevant? |
This is a fairly significant blocker. Our application can't be an SPA due to varying concerns/implementations. We really want to use Angular w/AOT and have implemented a significant amount of our frontend code using Angular 7. Not being able to bootstrap multiple root modules is a huge blocker for us since we don't need a complete page takeover, but multiple modules to only takeover certain parts of the UI since the majority of the UI is generated on the backend. Having multiple root modules work via JIT, but not AOT, doesn't make a lot of sense and gives a false impression during development that it would work in production w/AOT. I didn't even realize this was a limitation since I didn't see anything about it in the documentation. It took me troubleshooting and looking on stackoverflow/googling for 3 days to find this out. The documentation does give an example of having multiple roots, which is kinda confusing. Creating multiple projects doesn't seem like a reasonable option, either. As it would lead to having to create an individual project for each part of the UI that needs to be taken over.
Could we get some feedback on whether there is an approach to workaround this issue, other than sticking with JIT? There were other comments asking for clarity on it that never received a response.
If there were a way to have a root module that could then conditionally bootstrap other modules, that would at least provide a work-around. I attempted this workaround while attempting to utilize lazy-loading. But it doesn't work since the root module doesn't actually attach to the DOM and I was simply attempting to bootstrap the other modules. No matter my attempt, I consistently received the "Uncaught Error: No NgModule metadata found" exception in the browser for AOT. During the build process, no errors were being generated. |
@trickeyone For AOT you may want to try my fork of And use it like so: const AotPlugin = require('@rush/webpack').AngularCompilerPlugin;
const aotPlugins = USE_AOT ? [
new AotPlugin({
tsConfigPath: IS_PRODUCTION ? 'tsconfig.prod.json' : 'tsconfig.dev.json',
entryModules: [
path.join(__dirname, 'src/js/app/app.module#AppModule'),
path.join(__dirname, 'src/js/app/landing.module#LandingModule'),
],
skipCodeGeneration: !IS_PRODUCTION,
})
] : [];
Kind of :-) // unfortunately for AOT compiler to work, these components need to be defined twice
// (AOT will throw)
const declarations = [
LandingComponent,
GetNotifiedComponent,
TypedComponent,
StickyBarComponent,
ImageGalleryComponent,
RequestDemoFormComponent,
PricingPlansComponent,
SalesRequestFormComponent,
DetailedPricingPlansComponent,
];
const landingComponents = {
'landing-root': LandingComponent,
'get-notified': GetNotifiedComponent,
'typed-component': TypedComponent,
'sticky-bar': StickyBarComponent,
'image-gallery': ImageGalleryComponent,
'request-demo-form': RequestDemoFormComponent,
'pricing-plans': PricingPlansComponent,
'detailed-pricing-plans': DetailedPricingPlansComponent,
'standalone-help-manual': StandaloneHelpManualComponent,
};
function hasKey<O>(obj: O, key: string | number | symbol): key is (keyof O) {
return key in obj;
}
// tslint:disable-next-line:max-classes-per-file
@NgModule({
declarations,
entryComponents: [...declarations, StandaloneHelpManualComponent],
imports: [
BrowserModule,
CommonModule,
ClarityModule,
LightboxModule,
HttpClientModule,
FormsModule,
BrowserAnimationsModule,
HelpModule,
],
providers: [
WaitlistedService,
PricingService,
],
})
export class LandingModule {
ngDoBootstrap(applicationRef: ApplicationRef) {
for (const tagName in landingComponents) {
if (hasKey(landingComponents, tagName)) {
const component = landingComponents[tagName];
if (document.getElementsByTagName(tagName).length) {
applicationRef.bootstrap(component as any);
}
}
}
}
} As you can see I am using both methods. I have one app which is a plain old regular Angular app and a |
After doing some research into I do really like the @angular/elements setup, but I would suggest possibly allowing for components to be included as custom elements without having to do the i.e. @Component({
selector: 'my-component',
templateUrl: '...'
})
class MyComponent {
}
@NgModule({
...
customElements: [MyElementComponent]
})
class AppModule {} This seems like it would a much easier implementation. If |
if you need an option for multiple paths instead of multiple entry modules, I've forked @Rush (based from @artonge) and added this feature npm install import { AngularCompilerPlugin } from "@jetlogs/webpack";
new AngularCompilerPlugin({
tsConfigPath: "tsconfig.json",
paths: [
"/path/to/entry1.ts",
"/path/to/entry2.ts"
]
})
|
Any news on this feature? Do you have an ETA for the multi entryModule support? It's a blocker for us. Is it possible to add this commit to webpack repository? |
I'm glad to see some activity on this issue! For what it's worth, I have my own branches in which I've rebased the work by @Rush and @artonge onto the v9.1.7 release of angular-cli: https://github.com/francisli/angular-cli/tree/v9.1.7-multiple-entry-modules And I've built the package for direct reference in package.json files here (instead of publishing yet another variation of the package to npm): https://github.com/francisli/ngtools-webpack-builds/tree/9.1.x-multiple-entry-modules Hope this helps anyone else landing here, looking for this support with the latest release of Angular and TypeScript... |
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. |
From @artonge on May 7, 2018 14:51
Bug Report or Feature Request (mark with an
x
)Area
Versions
node version: v9.4.0
npm version: 5.6.0
Linux (Ubuntu 17.10)
Repro steps
Clone this example: https://github.com/artonge/multiple-entrymodules
The log given by the failure
At execution in the browser I have:
Uncaught Error: No NgModule metadata found for 'AppModule'.
This error only appears for the module that wasn't specified has the entryModule in the webpack config.
Desired functionality
At my company our webpack config has two entry points for two different apps, and generate two bundles for the two apps. The problem is that when using AOT, we can only specify one entryModule, but the two apps have different entryModule. It would be nice to specify two entryModules so the metadata are generated for both of them.
Copied from original issue: angular/devkit#861
The text was updated successfully, but these errors were encountered: