Is it possible create a SPA module? if yes how startup class should look like?
I've created a test app with several modules. One of them contains react client application.
As a result I get an error Failed to start 'npm'. I suppose I have problems with routes in module and I don't know how to relosve it.

Startup class in SpaModule4 looks like this
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSpaStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.Map("/spamodule4", config =>
{
app.UseSpa(config =>
{
config.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
config.UseReactDevelopmentServer(npmScript: "start");
}
});
});
}
}
here's a sample angular one I got running the other day.
You're pretty close ;)
public class Startup : StartupBase
{
private readonly IHostEnvironment _env;
public Startup(IHostEnvironment environment)
{
_env = environment;
}
public override void ConfigureServices(IServiceCollection services)
{
services.AddSpaStaticFiles(spa => spa.RootPath = "../ThisNetWorks.OrchardCore.Spa/ClientApp");
}
public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
{
app.UseSpaStaticFiles();
app.Map("/app", spaApp =>
{
spaApp.UseSpa(spa =>
{
spa.Options.SourcePath = Path.Join(_env.ContentRootPath, "../ThisNetWorks.OrchardCore.Spa/ClientApp");
if (_env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start --base-href=/app/ --serve-path=/");
}
});
});
}
}
It works nice. Thank you!)
https://github.com/OrchardCMS/OrchardCore/tree/skrypt/webpack-hmr
I did that a while ago too.
What if I have several SPA modules? Will it work?
@abdurahmanus yes, should do. If they're mapped under different routing routes.
You're essentially getting into SpaServices there, so if you can do it with aspnetcore, then it should work under Orchard Core
It works fine for several SPA apps. I tested it for two React apps. You have to configure your startup classes as shown above and also change a spa app public path in webpack.config. It depends on your map route.
In my project it looks like:
const publicPath = isEnvProduction
? paths.servedPath
: isEnvDevelopment && '/learning/';
@eugene-latarevich how did you change public path in React app? Did you eject it?
If you create react app via npm it will create node_modules folder in your client app folder. In VS the folder is hidden. In that folder you should follow /react-scripts/config/webpack.config.js. There is the variable publicPath.