What is proper way to run multiple angular2 applications using boot-server and boot client style?
I managed to get it half-working by duplicating existing app configuraration like this:
ClientApp/
admin/
admin.module.ts
app/
app.module.ts
dist/
vendor-manifest.json
vendor-admin-manifest.json
vendor.js
vendoradmin.js
boot-client.ts
boot-server.ts
boot-admin-client.ts
boot-admin-server.ts
After that I added Admin controller and Admin view with something like:
@{
ViewData["Title"] = "Home Page";
}
<app asp-prerender-module="ClientApp/dist/main-admin-server">Loading...</app>
<script src="~/dist/vendoadmin.js" asp-append-version="true"></script>
@section scripts {
<script src="~/dist/main-admin-client.js" asp-append-version="true"></script>
}
But then HMR worked only when I started first app, after going to second app /admin HMR went wild and started searching for non existing hot module update file, after returning to first app (/) I would get:
Prerendering failed because of error: Error: Zone already loaded.
Am I going in the right direction with this? I don't have much experience with webpack and prerendering, any tips or examples are welcome.
If you want to have two independent HMR processes going, then you'll need to have two separate Webpack configs, each pointing to different entry modules. Then you can call UseWebpackDevMiddleware twice in your Startup.cs, and with the two calls, set the ConfigFile property on the WebpackDevMiddlewareOptions options object to reference the two different config files.
To have two separate prerendering processes, you would need to find out what Angular and Zone.js are doing that gets unhappy if you load Zone.js twice, and find some way to make it load Zone.js only once. This is an Angular question so I'm not the best person to help find out how to do that. You could ask the folks in the Angular Universal project, since exactly the same issue would come up if you tried to prerender two different Angular apps within one Node process.
Hope that helps!
@tmedanovic Have you found a solution for this? Have the same issue here.
@deliberaligiacomo It was too much hassle, I've already lost alot of time on this and since it is a hobby application I decided on temporary solution, main purpose for running 2 apps for me was to separate "master" pages for public and admin part so I did this:
export const PUBLIC_ROUTES: Routes = [
{ path: '', redirectTo: 'blog', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'login', component: LoginComponent },
{ path: 'blog', component: BlogComponent },
{ path: 'post/create', component: BlogPostEditComponent, },
{ path: 'post/:id/:permalink', component: BlogPostDetailComponent, },
];
export const SECURE_ROUTES: Routes = [
{ path: '', redirectTo: 'admin', pathMatch: 'full' },
{ path: 'admin', component: AdminHomeComponent },
];
const APP_ROUTES: Routes = [
{ path: '', redirectTo: '/blog', pathMatch: 'full', },
{ path: '', component: AppLayoutComponent, data: { title: 'App Views' }, children: PUBLIC_ROUTES },
{ path: '', component: AdminLayoutComponent, data: { title: 'Admin Views' }, children: SECURE_ROUTES }
];
I still haven't get to playing around with bundling different resources for different views.
The approach I'm using that seems to work is to simply define multiple entry points in webpack config.
const clientBundleConfig = {
entry: {
'front': './client/front/main.ts',
'admin': './client/admin/main.ts',
},
output: {
path: './www/dist',
filename: '[name].bundle.js'
}
...
}
Now the relevant angular app front or admin will update from a single HMR process. I couldn't get it to work with separate webpack config and HMR processes using the same dotnet server process, I found only the first app would update.
Update
I needed to perform a separate build for apps due to restrictions I ran into. I now follow SteveSandersonMS suggestion of calling UseWebpackDevMiddleware for each app, the only step missing from his suggestion is the need to specify a unique endpoint for each app:
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true,
ConfigFile = "webpack.front.js",
HotModuleReplacementEndpoint = "/__webpack_hmr_front"
});
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true,
ConfigFile = "webpack.admin.js",
HotModuleReplacementEndpoint = "/__webpack_hmr_admin"
});
Most helpful comment
If you want to have two independent HMR processes going, then you'll need to have two separate Webpack configs, each pointing to different
entrymodules. Then you can callUseWebpackDevMiddlewaretwice in yourStartup.cs, and with the two calls, set theConfigFileproperty on theWebpackDevMiddlewareOptionsoptions object to reference the two different config files.To have two separate prerendering processes, you would need to find out what Angular and Zone.js are doing that gets unhappy if you load Zone.js twice, and find some way to make it load Zone.js only once. This is an Angular question so I'm not the best person to help find out how to do that. You could ask the folks in the Angular Universal project, since exactly the same issue would come up if you tried to prerender two different Angular apps within one Node process.
Hope that helps!