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

Commit 5839ba6

Browse files
authored
Merge pull request #60 from T0shik/master
WSL Support
2 parents 0cb1498 + ac1a464 commit 5839ba6

File tree

5 files changed

+72
-27
lines changed

5 files changed

+72
-27
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
#Ignore thumbnails created by Windows
33
Thumbs.db
4+
#Ignore .idea
5+
*.idea
46
#Ignore files built by Visual Studio
57
*.obj
68
*.exe

src/VueCliMiddleware/Util/Internals.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ private async Task Run()
166166
// get all the newlines
167167
while ((lineBreakPos = Array.IndexOf(buf, '\n', startPos, chunkLength - startPos)) >= 0 && startPos < chunkLength)
168168
{
169-
var length = (lineBreakPos + 1) - startPos;
169+
var length = lineBreakPos - startPos;
170170
_linesBuffer.Append(buf, startPos, length);
171171
OnCompleteLine(_linesBuffer.ToString());
172172
_linesBuffer.Clear();

src/VueCliMiddleware/Util/ScriptRunner.cs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ internal class ScriptRunner
2424

2525
public ScriptRunnerType Runner { get; }
2626

27-
private string GetExeName()
27+
private string GetExeName()
2828
{
2929
switch (Runner)
3030
{
@@ -64,7 +64,7 @@ public void Kill()
6464
try { RunnerProcess?.WaitForExit(); } catch { }
6565
}
6666

67-
public ScriptRunner(string workingDirectory, string scriptName, string arguments, IDictionary<string, string> envVars, ScriptRunnerType runner)
67+
public ScriptRunner(string workingDirectory, string scriptName, string arguments, IDictionary<string, string> envVars, ScriptRunnerType runner, bool wsl)
6868
{
6969
if (string.IsNullOrEmpty(workingDirectory))
7070
{
@@ -83,11 +83,19 @@ public ScriptRunner(string workingDirectory, string scriptName, string arguments
8383

8484
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
8585
{
86-
// On Windows, the NPM executable is a .cmd file, so it can't be executed
87-
// directly (except with UseShellExecute=true, but that's no good, because
88-
// it prevents capturing stdio). So we need to invoke it via "cmd /c".
89-
completeArguments = $"/c {exeName} {completeArguments}";
90-
exeName = "cmd";
86+
if (wsl)
87+
{
88+
completeArguments = $"{exeName} {completeArguments}";
89+
exeName = "wsl";
90+
}
91+
else
92+
{
93+
// On Windows, the NPM executable is a .cmd file, so it can't be executed
94+
// directly (except with UseShellExecute=true, but that's no good, because
95+
// it prevents capturing stdio). So we need to invoke it via "cmd /c".
96+
completeArguments = $"/c {exeName} {completeArguments}";
97+
exeName = "cmd";
98+
}
9199
}
92100

93101
var processStartInfo = new ProcessStartInfo(exeName)
@@ -124,8 +132,15 @@ public void AttachToLogger(ILogger logger)
124132
// NPM tasks commonly emit ANSI colors, but it wouldn't make sense to forward
125133
// those to loggers (because a logger isn't necessarily any kind of terminal)
126134
//logger.LogInformation(StripAnsiColors(line).TrimEnd('\n'));
127-
// making this console for debug purpose
128-
Console.Write(line);
135+
// making this console for debug purpose
136+
if (line.StartsWith("<s>"))
137+
{
138+
Console.Error.WriteLine(line.Substring(3));
139+
}
140+
else
141+
{
142+
Console.Error.WriteLine(line);
143+
}
129144
}
130145
};
131146

@@ -135,7 +150,14 @@ public void AttachToLogger(ILogger logger)
135150
{
136151
//logger.LogError(StripAnsiColors(line).TrimEnd('\n'));
137152
// making this console for debug purpose
138-
Console.Error.Write(line);
153+
if (line.StartsWith("<s>"))
154+
{
155+
Console.Error.WriteLine(line.Substring(3));
156+
}
157+
else
158+
{
159+
Console.Error.WriteLine(line);
160+
}
139161
}
140162
};
141163

src/VueCliMiddleware/VueDevelopmentServerMiddleware.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ internal static class VueCliMiddleware
1818

1919
public static void Attach(
2020
ISpaBuilder spaBuilder,
21-
string scriptName, int port = 8080, bool https = false, ScriptRunnerType runner = ScriptRunnerType.Npm, string regex = DefaultRegex, bool forceKill = false)
21+
string scriptName,
22+
int port = 8080,
23+
bool https = false,
24+
ScriptRunnerType runner = ScriptRunnerType.Npm,
25+
string regex = DefaultRegex,
26+
bool forceKill = false,
27+
bool wsl = false)
2228
{
2329
var sourcePath = spaBuilder.Options.SourcePath;
2430
if (string.IsNullOrEmpty(sourcePath))
@@ -34,7 +40,7 @@ public static void Attach(
3440
// Start vue-cli and attach to middleware pipeline
3541
var appBuilder = spaBuilder.ApplicationBuilder;
3642
var logger = LoggerFinder.GetOrCreateLogger(appBuilder, LogCategoryName);
37-
var portTask = StartVueCliServerAsync(sourcePath, scriptName, logger, port, runner, regex, forceKill);
43+
var portTask = StartVueCliServerAsync(sourcePath, scriptName, logger, port, runner, regex, forceKill, wsl);
3844

3945
// Everything we proxy is hardcoded to target localhost because:
4046
// - the requests are always from the local machine (we're not accepting remote
@@ -55,7 +61,14 @@ public static void Attach(
5561
}
5662

5763
private static async Task<int> StartVueCliServerAsync(
58-
string sourcePath, string npmScriptName, ILogger logger, int portNumber, ScriptRunnerType runner, string regex, bool forceKill = false)
64+
string sourcePath,
65+
string npmScriptName,
66+
ILogger logger,
67+
int portNumber,
68+
ScriptRunnerType runner,
69+
string regex,
70+
bool forceKill = false,
71+
bool wsl = false)
5972
{
6073
if (portNumber < 80)
6174
{
@@ -76,7 +89,7 @@ private static async Task<int> StartVueCliServerAsync(
7689
{ "BROWSER", "none" }, // We don't want vue-cli to open its own extra browser window pointing to the internal dev server port
7790
};
7891

79-
var npmScriptRunner = new ScriptRunner(sourcePath, npmScriptName, $"--port {portNumber:0}", envVars, runner: runner);
92+
var npmScriptRunner = new ScriptRunner(sourcePath, npmScriptName, $"--port {portNumber:0}", envVars, runner: runner, wsl: wsl);
8093
AppDomain.CurrentDomain.DomainUnload += (s, e) => npmScriptRunner?.Kill();
8194
AppDomain.CurrentDomain.ProcessExit += (s, e) => npmScriptRunner?.Kill();
8295
AppDomain.CurrentDomain.UnhandledException += (s, e) => npmScriptRunner?.Kill();

src/VueCliMiddleware/VueDevelopmentServerMiddlewareExtensions.cs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,17 @@ public static class VueCliMiddlewareExtensions
2525
/// <param name="https">Specify vue cli server schema </param>
2626
/// <param name="runner">Specify the runner, Npm and Yarn are valid options. Yarn support is HIGHLY experimental.</param>
2727
/// <param name="regex">Specify a custom regex string to search for in the log indicating proxied server is running. VueCli: "running at", QuasarCli: "Compiled successfully"</param>
28+
/// <param name="forceKill"></param>
29+
/// <param name="wsl"></param>
2830
public static void UseVueCli(
2931
this ISpaBuilder spaBuilder,
3032
string npmScript = "serve",
3133
int port = 8080,
3234
bool https = false,
3335
ScriptRunnerType runner = ScriptRunnerType.Npm,
3436
string regex = VueCliMiddleware.DefaultRegex,
35-
bool forceKill = false)
37+
bool forceKill = false,
38+
bool wsl = false)
3639
{
3740
if (spaBuilder == null)
3841
{
@@ -46,7 +49,7 @@ public static void UseVueCli(
4649
throw new InvalidOperationException($"To use {nameof(UseVueCli)}, you must supply a non-empty value for the {nameof(SpaOptions.SourcePath)} property of {nameof(SpaOptions)} when calling {nameof(SpaApplicationBuilderExtensions.UseSpa)}.");
4750
}
4851

49-
VueCliMiddleware.Attach(spaBuilder, npmScript, port, https: https, runner: runner, regex: regex, forceKill: forceKill);
52+
VueCliMiddleware.Attach(spaBuilder, npmScript, port, https: https, runner: runner, regex: regex, forceKill: forceKill, wsl: wsl);
5053
}
5154

5255

@@ -59,10 +62,11 @@ public static IEndpointConventionBuilder MapToVueCliProxy(
5962
bool https = false,
6063
ScriptRunnerType runner = ScriptRunnerType.Npm,
6164
string regex = VueCliMiddleware.DefaultRegex,
62-
bool forceKill = false)
65+
bool forceKill = false,
66+
bool wsl = false)
6367
{
6468
if (pattern == null) { throw new ArgumentNullException(nameof(pattern)); }
65-
return endpoints.MapFallback(pattern, CreateProxyRequestDelegate(endpoints, options, npmScript, port, https, runner, regex, forceKill));
69+
return endpoints.MapFallback(pattern, CreateProxyRequestDelegate(endpoints, options, npmScript, port, https, runner, regex, forceKill, wsl));
6670
}
6771

6872
public static IEndpointConventionBuilder MapToVueCliProxy(
@@ -74,11 +78,12 @@ public static IEndpointConventionBuilder MapToVueCliProxy(
7478
bool https = false,
7579
ScriptRunnerType runner = ScriptRunnerType.Npm,
7680
string regex = VueCliMiddleware.DefaultRegex,
77-
bool forceKill = false)
81+
bool forceKill = false,
82+
bool wsl = false)
7883
{
7984
if (pattern == null) { throw new ArgumentNullException(nameof(pattern)); }
8085
if (sourcePath == null) { throw new ArgumentNullException(nameof(sourcePath)); }
81-
return endpoints.MapFallback(pattern, CreateProxyRequestDelegate(endpoints, new SpaOptions { SourcePath = sourcePath }, npmScript, port, https, runner, regex, forceKill));
86+
return endpoints.MapFallback(pattern, CreateProxyRequestDelegate(endpoints, new SpaOptions { SourcePath = sourcePath }, npmScript, port, https, runner, regex, forceKill, wsl));
8287
}
8388

8489
public static IEndpointConventionBuilder MapToVueCliProxy(
@@ -89,9 +94,10 @@ public static IEndpointConventionBuilder MapToVueCliProxy(
8994
bool https = false,
9095
ScriptRunnerType runner = ScriptRunnerType.Npm,
9196
string regex = VueCliMiddleware.DefaultRegex,
92-
bool forceKill = false)
97+
bool forceKill = false,
98+
bool wsl = false)
9399
{
94-
return endpoints.MapFallback("{*path}", CreateProxyRequestDelegate(endpoints, options, npmScript, port, https, runner, regex, forceKill));
100+
return endpoints.MapFallback("{*path}", CreateProxyRequestDelegate(endpoints, options, npmScript, port, https, runner, regex, forceKill, wsl));
95101
}
96102

97103
public static IEndpointConventionBuilder MapToVueCliProxy(
@@ -102,10 +108,11 @@ public static IEndpointConventionBuilder MapToVueCliProxy(
102108
bool https = false,
103109
ScriptRunnerType runner = ScriptRunnerType.Npm,
104110
string regex = VueCliMiddleware.DefaultRegex,
105-
bool forceKill = false)
111+
bool forceKill = false,
112+
bool wsl = false)
106113
{
107114
if (sourcePath == null) { throw new ArgumentNullException(nameof(sourcePath)); }
108-
return endpoints.MapFallback("{*path}", CreateProxyRequestDelegate(endpoints, new SpaOptions { SourcePath = sourcePath }, npmScript, port, https, runner, regex, forceKill));
115+
return endpoints.MapFallback("{*path}", CreateProxyRequestDelegate(endpoints, new SpaOptions { SourcePath = sourcePath }, npmScript, port, https, runner, regex, forceKill, wsl));
109116
}
110117

111118

@@ -118,7 +125,8 @@ private static RequestDelegate CreateProxyRequestDelegate(
118125
bool https = false,
119126
ScriptRunnerType runner = ScriptRunnerType.Npm,
120127
string regex = VueCliMiddleware.DefaultRegex,
121-
bool forceKill = false)
128+
bool forceKill = false,
129+
bool wsl = false)
122130
{
123131
// based on CreateRequestDelegate() https://github.com/aspnet/AspNetCore/blob/master/src/Middleware/StaticFiles/src/StaticFilesEndpointRouteBuilderExtensions.cs#L194
124132

@@ -146,7 +154,7 @@ private static RequestDelegate CreateProxyRequestDelegate(
146154

147155
if (!string.IsNullOrWhiteSpace(npmScript))
148156
{
149-
opt.UseVueCli(npmScript, port, https, runner, regex, forceKill);
157+
opt.UseVueCli(npmScript, port, https, runner, regex, forceKill, wsl);
150158
}
151159
});
152160

0 commit comments

Comments
 (0)