How to run Nuxt from a ASP.NET Core Web Application

How to run Nuxt from a ASP.Net Core Web Application

npx create-nuxt-app client-app ORyarn create nuxt-app client-app
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
<IsPackable>false</IsPackable>
<SpaRoot>client-app\</SpaRoot>
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
</PropertyGroup>


<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.0.0-preview6.19307.2" />
</ItemGroup>

<ItemGroup>
<!-- Don't publish the SPA source files, but do show them in the project files list -->
<Content Remove="$(SpaRoot)**" />
<None Remove="$(SpaRoot)**" />
<None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules\**" />
</ItemGroup>

<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
<!-- Ensure Node.js is installed -->
<Exec Command="node --version" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
</Exec>
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
</Target>

<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run generate" />

<!-- Include the newly-built files in the publish output -->
<ItemGroup>
<DistFiles Include="$(SpaRoot)dist\**" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
</Project>
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.SpaServices;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace NuxtIntegration.Helpers
{
public static class NuxtHelper
{
// default port number of 'npm run dev'
private static int Port { get; } = 3000;
private static Uri DevelopmentServerEndpoint { get; } = new Uri($"http://localhost:{Port}");
private static TimeSpan Timeout { get; } = TimeSpan.FromSeconds(30);
// done message of 'npm run dev' command.
private static string DoneMessage { get; } = "DONE Compiled successfully in";

public static void UseNuxtDevelopmentServer(this ISpaBuilder spa)
{
spa.UseProxyToSpaDevelopmentServer(async () =>
{
var loggerFactory = spa.ApplicationBuilder.ApplicationServices.GetService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Nuxt");
// if 'npm dev' command was executed yourself, then just return the endpoint.
if (IsRunning())
{
return DevelopmentServerEndpoint;
}

// launch Nuxt development server
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
var processInfo = new ProcessStartInfo
{
FileName = isWindows ? "cmd" : "npm",
Arguments = $"{(isWindows ? "/c npm " : "")}run dev",
WorkingDirectory = "client-app",
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
};
var process = Process.Start(processInfo);
var tcs = new TaskCompletionSource<int>();
_ = Task.Run(() =>
{
try
{
string line;
while ((line = process.StandardOutput.ReadLine()) != null)
{
logger.LogInformation(line);
if (!tcs.Task.IsCompleted && line.Contains(DoneMessage))
{
tcs.SetResult(1);
}
}
}
catch (EndOfStreamException ex)
{
logger.LogError(ex.ToString());
tcs.SetException(new InvalidOperationException("'npm run dev' failed.", ex));
}
});
_ = Task.Run(() =>
{
try
{
string line;
while ((line = process.StandardError.ReadLine()) != null)
{
logger.LogError(line);
}
}
catch (EndOfStreamException ex)
{
logger.LogError(ex.ToString());
tcs.SetException(new InvalidOperationException("'npm run dev' failed.", ex));
}
});

var timeout = Task.Delay(Timeout);
if (await Task.WhenAny(timeout, tcs.Task) == timeout)
{
throw new TimeoutException();
}

return DevelopmentServerEndpoint;
});

}

private static bool IsRunning() => IPGlobalProperties.GetIPGlobalProperties()
.GetActiveTcpListeners()
.Select(x => x.Port)
.Contains(Port);
}
}
services.AddSpaStaticFiles(options => options.RootPath = "client-app/dist");
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "client-app";
if (env.IsDevelopment())
{
// Launch development server for Nuxt
spa.UseNuxtDevelopmentServer();
}
});

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store