Skip to content
This repository was archived by the owner on Nov 6, 2023. It is now read-only.

Commit 1b67ff0

Browse files
committed
Add experimental EndpointRouting
1 parent 537568d commit 1b67ff0

File tree

3 files changed

+168
-43
lines changed

3 files changed

+168
-43
lines changed

README.md

Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,36 @@
22

33
[![](https://img.shields.io/nuget/v/VueCliMiddleware.svg)](https://www.nuget.org/packages/VueCliMiddleware/)
44

5-
This is a stand-alone module to add VueCli support to AspNet Core 2.2.0.
5+
This is a stand-alone module to add Vue Cli and Quasar Cli support to AspNet Core.
66

7-
## Usage Example
7+
8+
## ASP.NET 3.0 Preview Endpoint Routing (experimental)
9+
First, be sure to switch Vue Cli or Quasar Cli to output distribution files to wwwroot directly (not dist).
10+
11+
* Quasar CLI: regex: "Compiled successfully"
12+
* Vue CLI: regex: default or "running at"
13+
14+
See [Migrating Asp.Net 2.2 to 3.0 Endpoint Routing](https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-2.2&tabs=visual-studio#update-routing-startup-code)
15+
```csharp
16+
// To use with EndpointRouting
17+
18+
app.UseEndpoints(endpoints =>
19+
{
20+
endpoints.MapControllers();
21+
22+
// initialize vue cli middleware
23+
#if DEBUG
24+
if (System.Diagnostics.Debugger.IsAttached)
25+
endpoints.MapToVueCliProxy("{*path}", new SpaOptions { SourcePath = "ClientApp" }, "dev", regex: "Compiled successfully");
26+
else
27+
#endif
28+
// note: output of vue cli or quasar cli should be wwwroot
29+
endpoints.MapFallbackToFile("index.html");
30+
});
31+
```
32+
33+
34+
## ASP.NET 2.2 Usage Example
835
```csharp
936
using VueCliMiddleware;
1037

@@ -57,46 +84,46 @@ This is a stand-alone module to add VueCli support to AspNet Core 2.2.0.
5784
You may also need to add the following tasks to your csproj file. This are similar to what are found in the default ASPNETSPA templates.
5885

5986
```project.csproj
60-
<PropertyGroup>
61-
<!-- Typescript/Javascript Client Configuration -->
62-
<SpaRoot>ClientApp\</SpaRoot>
63-
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
87+
<PropertyGroup>
88+
<!-- Typescript/Javascript Client Configuration -->
89+
<SpaRoot>ClientApp\</SpaRoot>
90+
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
6491
</PropertyGroup>
65-
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build">
66-
<!-- Build Target: Ensure Node.js is installed -->
67-
<Exec Command="node --version" ContinueOnError="true">
68-
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
69-
</Exec>
70-
<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." />
71-
</Target>
72-
73-
<Target Name="DebugEnsureNpm" AfterTargets="DebugEnsureNodeEnv">
74-
<!-- Build Target: Ensure Node.js is installed -->
75-
<Exec Command="npm --version" ContinueOnError="true">
76-
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
77-
</Exec>
78-
</Target>
79-
80-
<Target Name="EnsureNodeModulesInstalled" BeforeTargets="Build" Inputs="package.json" Outputs="packages-lock.json">
81-
<!-- Build Target: Restore NPM packages using npm -->
82-
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
83-
84-
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
85-
</Target>
86-
87-
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
88-
<!-- Build Target: Run webpack dist build -->
89-
<Message Importance="high" Text="Running npm build..." />
90-
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />
91-
92-
<!-- Include the newly-built files in the publish output -->
93-
<ItemGroup>
94-
<DistFiles Include="$(SpaRoot)dist\**" />
95-
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
96-
<RelativePath>%(DistFiles.Identity)</RelativePath>
97-
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
98-
</ResolvedFileToPublish>
99-
</ItemGroup>
92+
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build">
93+
<!-- Build Target: Ensure Node.js is installed -->
94+
<Exec Command="node --version" ContinueOnError="true">
95+
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
96+
</Exec>
97+
<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." />
98+
</Target>
99+
100+
<Target Name="DebugEnsureNpm" AfterTargets="DebugEnsureNodeEnv">
101+
<!-- Build Target: Ensure Node.js is installed -->
102+
<Exec Command="npm --version" ContinueOnError="true">
103+
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
104+
</Exec>
105+
</Target>
106+
107+
<Target Name="EnsureNodeModulesInstalled" BeforeTargets="Build" Inputs="package.json" Outputs="packages-lock.json">
108+
<!-- Build Target: Restore NPM packages using npm -->
109+
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
110+
111+
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
112+
</Target>
113+
114+
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
115+
<!-- Build Target: Run webpack dist build -->
116+
<Message Importance="high" Text="Running npm build..." />
117+
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />
118+
119+
<!-- Include the newly-built files in the publish output -->
120+
<ItemGroup>
121+
<DistFiles Include="$(SpaRoot)dist\**" />
122+
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
123+
<RelativePath>%(DistFiles.Identity)</RelativePath>
124+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
125+
</ResolvedFileToPublish>
126+
</ItemGroup>
100127
</Target>
101128

102129
```

src/VueCliMiddleware/VueCliMiddleware.csproj

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,23 @@
66

77
<Title>VueCliMiddleware</Title>
88
<VersionPrefix>3.0.0</VersionPrefix>
9-
<VersionSuffix>preview7</VersionSuffix>
9+
<VersionSuffix>preview7-1</VersionSuffix>
1010
<LangVersion>Latest</LangVersion>
1111
<Authors>EEParker</Authors>
12+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
1213
<RepositoryUrl>https://github.com/EEParker/aspnetcore-vueclimiddleware.git</RepositoryUrl>
1314
<PackageProjectUrl>https://github.com/EEParker/aspnetcore-vueclimiddleware.git</PackageProjectUrl>
14-
<PackageLicenseUrl>https://github.com/EEParker/aspnetcore-vueclimiddleware/blob/master/LICENSE.txt</PackageLicenseUrl>
15+
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
1516
</PropertyGroup>
1617

18+
<ItemGroup>
19+
<None Include="..\..\LICENSE.txt" Pack="true" PackagePath=""/>
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" PrivateAssets="All" />
24+
</ItemGroup>
25+
1726
<ItemGroup>
1827
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.0.0-preview7.19365.7" />
1928
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0-preview7.19362.4" />

src/VueCliMiddleware/VueDevelopmentServerMiddlewareExtensions.cs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using Microsoft.AspNetCore.Builder;
2+
using Microsoft.AspNetCore.Http;
3+
using Microsoft.AspNetCore.Routing;
24
using Microsoft.AspNetCore.SpaServices;
35
using System;
46

@@ -43,5 +45,92 @@ public static void UseVueCli(
4345

4446
VueCliMiddleware.Attach(spaBuilder, npmScript, port, runner: runner, regex: regex);
4547
}
48+
49+
public static IEndpointConventionBuilder MapToVueCliProxy(
50+
this IEndpointRouteBuilder endpoints,
51+
string pattern,
52+
SpaOptions options,
53+
string npmScript,
54+
int port = 8080,
55+
ScriptRunnerType runner = ScriptRunnerType.Npm,
56+
string regex = VueCliMiddleware.DefaultRegex)
57+
{
58+
if (pattern == null) { throw new ArgumentNullException(nameof(pattern)); }
59+
return endpoints.MapFallback(pattern, CreateProxyRequestDelegate(endpoints, options, npmScript, port, runner, regex));
60+
}
61+
62+
public static IEndpointConventionBuilder MapToVueCliProxy(
63+
this IEndpointRouteBuilder endpoints,
64+
string pattern,
65+
string sourcePath,
66+
string npmScript,
67+
int port = 8080,
68+
ScriptRunnerType runner = ScriptRunnerType.Npm,
69+
string regex = VueCliMiddleware.DefaultRegex)
70+
{
71+
if (pattern == null) { throw new ArgumentNullException(nameof(pattern)); }
72+
if (sourcePath == null) { throw new ArgumentNullException(nameof(sourcePath)); }
73+
return endpoints.MapFallback(pattern, CreateProxyRequestDelegate(endpoints, new SpaOptions { SourcePath = sourcePath }, npmScript, port, runner, regex));
74+
}
75+
76+
public static IEndpointConventionBuilder MapToVueCliProxy(
77+
this IEndpointRouteBuilder endpoints,
78+
SpaOptions options,
79+
string npmScript,
80+
int port = 8080,
81+
ScriptRunnerType runner = ScriptRunnerType.Npm,
82+
string regex = VueCliMiddleware.DefaultRegex)
83+
{
84+
return endpoints.MapFallback("{*path}", CreateProxyRequestDelegate(endpoints, options, npmScript, port, runner, regex));
85+
}
86+
87+
public static IEndpointConventionBuilder MapToVueCliProxy(
88+
this IEndpointRouteBuilder endpoints,
89+
string sourcePath,
90+
string npmScript,
91+
int port = 8080,
92+
ScriptRunnerType runner = ScriptRunnerType.Npm,
93+
string regex = VueCliMiddleware.DefaultRegex)
94+
{
95+
if (sourcePath == null) { throw new ArgumentNullException(nameof(sourcePath)); }
96+
return endpoints.MapFallback("{*path}", CreateProxyRequestDelegate(endpoints, new SpaOptions { SourcePath = sourcePath }, npmScript, port, runner, regex));
97+
}
98+
99+
100+
// based on CreateRequestDelegate() https://github.com/aspnet/AspNetCore/blob/master/src/Middleware/StaticFiles/src/StaticFilesEndpointRouteBuilderExtensions.cs#L194
101+
private static RequestDelegate CreateProxyRequestDelegate(
102+
IEndpointRouteBuilder endpoints,
103+
SpaOptions options,
104+
string npmScript,
105+
int port = 8080,
106+
ScriptRunnerType runner = ScriptRunnerType.Npm,
107+
string regex = VueCliMiddleware.DefaultRegex)
108+
{
109+
if (endpoints == null) { throw new ArgumentNullException(nameof(endpoints)); }
110+
if (options == null) { throw new ArgumentNullException(nameof(options)); }
111+
if (npmScript == null) { throw new ArgumentNullException(nameof(npmScript)); }
112+
113+
var app = endpoints.CreateApplicationBuilder();
114+
app.Use(next => context =>
115+
{
116+
// Set endpoint to null so the SPA middleware will handle the request.
117+
context.SetEndpoint(null);
118+
return next(context);
119+
});
120+
121+
app.UseSpa(opt =>
122+
{
123+
if (options != null)
124+
{
125+
opt.Options.DefaultPage = options.DefaultPage;
126+
opt.Options.DefaultPageStaticFileOptions = options.DefaultPageStaticFileOptions;
127+
opt.Options.SourcePath = options.SourcePath;
128+
opt.Options.StartupTimeout = options.StartupTimeout;
129+
}
130+
opt.UseVueCli(npmScript, port, runner, regex);
131+
});
132+
133+
return app.Build();
134+
}
46135
}
47136
}

0 commit comments

Comments
 (0)