mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-23 10:08:57 +00:00
Compare commits
44 Commits
angular4-p
...
rel/2.0.0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e19873874 | ||
|
|
c128fa6e06 | ||
|
|
3ef23ece23 | ||
|
|
68e84bac3f | ||
|
|
a38d3bdc4b | ||
|
|
8e5f255346 | ||
|
|
a3bcc0d863 | ||
|
|
5e7bb0f5c5 | ||
|
|
8396be24c8 | ||
|
|
728b18431d | ||
|
|
9a59bccad9 | ||
|
|
bf6d2227db | ||
|
|
bcaa3af92e | ||
|
|
f3b7103c83 | ||
|
|
0dd24068ca | ||
|
|
0526852e05 | ||
|
|
60c8a3471d | ||
|
|
c7b7f40d2c | ||
|
|
5127a74d3f | ||
|
|
e38399fbf4 | ||
|
|
045c05fc88 | ||
|
|
b444831c8d | ||
|
|
2aaceaa9f8 | ||
|
|
1c5bd98d8a | ||
|
|
dbdc81a06a | ||
|
|
8a1d64cc73 | ||
|
|
087183ea18 | ||
|
|
9b131ea7d3 | ||
|
|
75fd215b1a | ||
|
|
38997c3f3f | ||
|
|
bee4c6ff11 | ||
|
|
cc859306a3 | ||
|
|
44512226c6 | ||
|
|
a2bde750be | ||
|
|
c592282646 | ||
|
|
b86e9f9254 | ||
|
|
970dc6c457 | ||
|
|
6baa2faf09 | ||
|
|
918e7edbff | ||
|
|
e1c90b3601 | ||
|
|
b9e62cd4c9 | ||
|
|
ad9cfbb176 | ||
|
|
941ae9a34d | ||
|
|
3645ae6cf2 |
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json" />
|
<clear />
|
||||||
<add key="AspNetCoreTools" value="https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json" />
|
<add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-master/api/v3/index.json" />
|
||||||
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
|
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -33,7 +33,7 @@ cd $PSScriptRoot
|
|||||||
$repoFolder = $PSScriptRoot
|
$repoFolder = $PSScriptRoot
|
||||||
$env:REPO_FOLDER = $repoFolder
|
$env:REPO_FOLDER = $repoFolder
|
||||||
|
|
||||||
$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip"
|
$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0-preview2.zip"
|
||||||
if ($env:KOREBUILD_ZIP)
|
if ($env:KOREBUILD_ZIP)
|
||||||
{
|
{
|
||||||
$koreBuildZip=$env:KOREBUILD_ZIP
|
$koreBuildZip=$env:KOREBUILD_ZIP
|
||||||
|
|||||||
2
build.sh
2
build.sh
@@ -2,7 +2,7 @@
|
|||||||
repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
cd $repoFolder
|
cd $repoFolder
|
||||||
|
|
||||||
koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip"
|
koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0-preview2.zip"
|
||||||
if [ ! -z $KOREBUILD_ZIP ]; then
|
if [ ! -z $KOREBUILD_ZIP ]; then
|
||||||
koreBuildZip=$KOREBUILD_ZIP
|
koreBuildZip=$KOREBUILD_ZIP
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
<PackageReference Include="Internal.AspNetCore.Sdk" Version="$(InternalAspNetCoreSdkVersion)" PrivateAssets="All" />
|
<PackageReference Include="Internal.AspNetCore.Sdk" Version="$(InternalAspNetCoreSdkVersion)" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFrameworkIdentifier)'=='.NETFramework' AND '$(OutputType)'=='library'">
|
<ItemGroup Condition="'$(TargetFrameworkIdentifier)'=='.NETFramework'">
|
||||||
<PackageReference Include="NETStandard.Library" Version="$(BundledNETStandardPackageVersion)" />
|
<PackageReference Include="NETStandard.Library" Version="$(BundledNETStandardPackageVersion)" />
|
||||||
|
<PackageReference Include="NETStandard.Library.NETFramework" Version="$(NETStandardLibraryNETFrameworkVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AspNetCoreVersion>2.0.0-*</AspNetCoreVersion>
|
<AspNetCoreVersion>2.0.0-preview2-*</AspNetCoreVersion>
|
||||||
<AutoMapperVersion>5.0.2</AutoMapperVersion>
|
<AutoMapperVersion>5.0.2</AutoMapperVersion>
|
||||||
<CoreFxVersion>4.3.0</CoreFxVersion>
|
|
||||||
<InternalAspNetCoreSdkVersion>2.1.0-*</InternalAspNetCoreSdkVersion>
|
<InternalAspNetCoreSdkVersion>2.1.0-*</InternalAspNetCoreSdkVersion>
|
||||||
<JsonNetVersion>10.0.1</JsonNetVersion>
|
<JsonNetVersion>10.0.1</JsonNetVersion>
|
||||||
<NETStandardImplicitPackageVersion>$(BundledNETStandardPackageVersion)</NETStandardImplicitPackageVersion>
|
<NETStandardImplicitPackageVersion>$(BundledNETStandardPackageVersion)</NETStandardImplicitPackageVersion>
|
||||||
|
<NETStandardLibraryNETFrameworkVersion>2.0.0-*</NETStandardLibraryNETFrameworkVersion>
|
||||||
|
<RuntimeFrameworkVersion Condition="'$(TargetFramework)'=='netcoreapp2.0'">2.0.0-*</RuntimeFrameworkVersion>
|
||||||
<ThreadingDataflowVersion>4.7.0</ThreadingDataflowVersion>
|
<ThreadingDataflowVersion>4.7.0</ThreadingDataflowVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
<Project>
|
|
||||||
<Target Name="NpmRestore" AfterTargets="Restore" Condition="'$(PreflightRestore)' != 'true'">
|
|
||||||
<ItemGroup>
|
|
||||||
<NpmModules Include="$(RepositoryRoot)**\package.json"
|
|
||||||
Exclude="$(RepositoryRoot)**\node_modules\**\*" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Message Text="Restoring NPM modules for: %0A - @(NpmModules -> '%(FullPath)','%0A - ')" Importance="high" />
|
|
||||||
|
|
||||||
<Exec Command="npm install" WorkingDirectory="%(NpmModules.RootDir)%(Directory)" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<Import Project="..\..\..\build\dependencies.props" />
|
<Import Project="..\..\..\build\common.props" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<OutputType>exe</OutputType>
|
<OutputType>exe</OutputType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<Import Project="..\..\..\build\dependencies.props" />
|
<Import Project="..\..\..\build\common.props" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ namespace Webpack.ActionResults
|
|||||||
{
|
{
|
||||||
var nodeServices = context.HttpContext.RequestServices.GetRequiredService<INodeServices>();
|
var nodeServices = context.HttpContext.RequestServices.GetRequiredService<INodeServices>();
|
||||||
var hostEnv = context.HttpContext.RequestServices.GetRequiredService<IHostingEnvironment>();
|
var hostEnv = context.HttpContext.RequestServices.GetRequiredService<IHostingEnvironment>();
|
||||||
|
var applicationLifetime = context.HttpContext.RequestServices.GetRequiredService<IApplicationLifetime>();
|
||||||
var applicationBasePath = hostEnv.ContentRootPath;
|
var applicationBasePath = hostEnv.ContentRootPath;
|
||||||
var request = context.HttpContext.Request;
|
var request = context.HttpContext.Request;
|
||||||
var response = context.HttpContext.Response;
|
var response = context.HttpContext.Response;
|
||||||
@@ -34,6 +35,7 @@ namespace Webpack.ActionResults
|
|||||||
var prerenderedHtml = await Prerenderer.RenderToString(
|
var prerenderedHtml = await Prerenderer.RenderToString(
|
||||||
applicationBasePath,
|
applicationBasePath,
|
||||||
nodeServices,
|
nodeServices,
|
||||||
|
applicationLifetime.ApplicationStopping,
|
||||||
_moduleExport,
|
_moduleExport,
|
||||||
request.GetEncodedUrl(),
|
request.GetEncodedUrl(),
|
||||||
request.Path + request.QueryString.Value,
|
request.Path + request.QueryString.Value,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<Import Project="..\..\..\build\dependencies.props" />
|
<Import Project="..\..\..\build\common.props" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>Socket-based RPC for Microsoft.AspNetCore.NodeServices.</Description>
|
<Description>Socket-based RPC for Microsoft.AspNetCore.NodeServices.</Description>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<PackageTags>aspnetcore;aspnetcoremvc;nodeservices</PackageTags>
|
<PackageTags>aspnetcore;aspnetcoremvc;nodeservices</PackageTags>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -15,14 +15,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Microsoft.AspNetCore.NodeServices\Microsoft.AspNetCore.NodeServices.csproj" />
|
<ProjectReference Include="..\Microsoft.AspNetCore.NodeServices\Microsoft.AspNetCore.NodeServices.csproj" />
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
|
|
||||||
<PackageReference Include="Microsoft.Tpl.Dataflow" Version="$(MicrosoftDataflowVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">
|
|
||||||
<PackageReference Include="System.IO.Pipes" Version="$(CoreFxVersion)" />
|
|
||||||
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="$(ThreadingDataflowVersion)" />
|
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="$(ThreadingDataflowVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -18,11 +18,7 @@ namespace Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections
|
|||||||
PipeDirection.InOut,
|
PipeDirection.InOut,
|
||||||
PipeOptions.Asynchronous);
|
PipeOptions.Asynchronous);
|
||||||
|
|
||||||
#if NET451
|
|
||||||
_namedPipeClientStream.Connect();
|
|
||||||
#else
|
|
||||||
await _namedPipeClientStream.ConnectAsync().ConfigureAwait(false);
|
await _namedPipeClientStream.ConnectAsync().ConfigureAwait(false);
|
||||||
#endif
|
|
||||||
|
|
||||||
return _namedPipeClientStream;
|
return _namedPipeClientStream;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ namespace Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections
|
|||||||
|
|
||||||
public static StreamConnection Create()
|
public static StreamConnection Create()
|
||||||
{
|
{
|
||||||
#if NET451
|
|
||||||
return new NamedPipeConnection();
|
|
||||||
#else
|
|
||||||
var useNamedPipes = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
|
var useNamedPipes = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
|
||||||
System.Runtime.InteropServices.OSPlatform.Windows);
|
System.Runtime.InteropServices.OSPlatform.Windows);
|
||||||
if (useNamedPipes)
|
if (useNamedPipes)
|
||||||
@@ -24,7 +21,6 @@ namespace Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections
|
|||||||
{
|
{
|
||||||
return new UnixDomainSocketConnection();
|
return new UnixDomainSocketConnection();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,16 +10,6 @@ namespace Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections
|
|||||||
private NetworkStream _networkStream;
|
private NetworkStream _networkStream;
|
||||||
private Socket _socket;
|
private Socket _socket;
|
||||||
|
|
||||||
#if NET451
|
|
||||||
public override Task<Stream> Open(string address)
|
|
||||||
{
|
|
||||||
// The 'null' assignments avoid the compiler warnings about unassigned fields.
|
|
||||||
// Note that this whole class isn't supported on .NET 4.5.1, since that's not cross-platform.
|
|
||||||
_networkStream = null;
|
|
||||||
_socket = null;
|
|
||||||
throw new System.PlatformNotSupportedException();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
public override async Task<Stream> Open(string address)
|
public override async Task<Stream> Open(string address)
|
||||||
{
|
{
|
||||||
var endPoint = new UnixDomainSocketEndPoint("/tmp/" + address);
|
var endPoint = new UnixDomainSocketEndPoint("/tmp/" + address);
|
||||||
@@ -28,7 +18,6 @@ namespace Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections
|
|||||||
_networkStream = new NetworkStream(_socket);
|
_networkStream = new NetworkStream(_socket);
|
||||||
return _networkStream;
|
return _networkStream;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -59,11 +59,7 @@ namespace Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if NET451
|
|
||||||
_encodedPath = new byte[0];
|
|
||||||
#else
|
|
||||||
_encodedPath = Array.Empty<byte>();
|
_encodedPath = Array.Empty<byte>();
|
||||||
#endif
|
|
||||||
_path = string.Empty;
|
_path = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ namespace Microsoft.AspNetCore.NodeServices.Sockets
|
|||||||
options.ProjectPath,
|
options.ProjectPath,
|
||||||
options.WatchFileExtensions,
|
options.WatchFileExtensions,
|
||||||
MakeNewCommandLineOptions(socketAddress),
|
MakeNewCommandLineOptions(socketAddress),
|
||||||
|
options.ApplicationStoppingToken,
|
||||||
options.NodeInstanceOutputLogger,
|
options.NodeInstanceOutputLogger,
|
||||||
options.EnvironmentVariables,
|
options.EnvironmentVariables,
|
||||||
options.InvocationTimeoutMilliseconds,
|
options.InvocationTimeoutMilliseconds,
|
||||||
|
|||||||
@@ -12,11 +12,7 @@ namespace Microsoft.AspNetCore.NodeServices.Sockets.VirtualConnections
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class VirtualConnection : Stream
|
internal class VirtualConnection : Stream
|
||||||
{
|
{
|
||||||
#if NET451
|
|
||||||
private readonly static Task CompletedTask = Task.FromResult((object)null);
|
|
||||||
#else
|
|
||||||
private readonly static Task CompletedTask = Task.CompletedTask;
|
private readonly static Task CompletedTask = Task.CompletedTask;
|
||||||
#endif
|
|
||||||
private VirtualConnectionClient _host;
|
private VirtualConnectionClient _host;
|
||||||
private readonly BufferBlock<byte[]> _receivedDataQueue = new BufferBlock<byte[]>();
|
private readonly BufferBlock<byte[]> _receivedDataQueue = new BufferBlock<byte[]>();
|
||||||
private ArraySegment<byte> _receivedDataNotYetUsed;
|
private ArraySegment<byte> _receivedDataNotYetUsed;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using Microsoft.AspNetCore.NodeServices.HostingModels;
|
using Microsoft.AspNetCore.NodeServices.HostingModels;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@@ -42,6 +43,12 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
EnvironmentVariables["NODE_ENV"] = hostEnv.IsDevelopment() ? "development" : "production"; // De-facto standard values for Node
|
EnvironmentVariables["NODE_ENV"] = hostEnv.IsDevelopment() ? "development" : "production"; // De-facto standard values for Node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var applicationLifetime = serviceProvider.GetService<IApplicationLifetime>();
|
||||||
|
if (applicationLifetime != null)
|
||||||
|
{
|
||||||
|
ApplicationStoppingToken = applicationLifetime.ApplicationStopping;
|
||||||
|
}
|
||||||
|
|
||||||
// If the DI system gives us a logger, use it. Otherwise, set up a default one.
|
// If the DI system gives us a logger, use it. Otherwise, set up a default one.
|
||||||
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
|
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
|
||||||
NodeInstanceOutputLogger = loggerFactory != null
|
NodeInstanceOutputLogger = loggerFactory != null
|
||||||
@@ -93,5 +100,10 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
/// Specifies the maximum duration, in milliseconds, that your .NET code should wait for Node.js RPC calls to return.
|
/// Specifies the maximum duration, in milliseconds, that your .NET code should wait for Node.js RPC calls to return.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int InvocationTimeoutMilliseconds { get; set; }
|
public int InvocationTimeoutMilliseconds { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A token that indicates when the host application is stopping.
|
||||||
|
/// </summary>
|
||||||
|
public CancellationToken ApplicationStoppingToken { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,6 +42,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
options.ProjectPath,
|
options.ProjectPath,
|
||||||
options.WatchFileExtensions,
|
options.WatchFileExtensions,
|
||||||
MakeCommandLineOptions(port),
|
MakeCommandLineOptions(port),
|
||||||
|
options.ApplicationStoppingToken,
|
||||||
options.NodeInstanceOutputLogger,
|
options.NodeInstanceOutputLogger,
|
||||||
options.EnvironmentVariables,
|
options.EnvironmentVariables,
|
||||||
options.InvocationTimeoutMilliseconds,
|
options.InvocationTimeoutMilliseconds,
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
/// <param name="projectPath">The root path of the current project. This is used when resolving Node.js module paths relative to the project root.</param>
|
/// <param name="projectPath">The root path of the current project. This is used when resolving Node.js module paths relative to the project root.</param>
|
||||||
/// <param name="watchFileExtensions">The filename extensions that should be watched within the project root. The Node instance will automatically shut itself down if any matching file changes.</param>
|
/// <param name="watchFileExtensions">The filename extensions that should be watched within the project root. The Node instance will automatically shut itself down if any matching file changes.</param>
|
||||||
/// <param name="commandLineArguments">Additional command-line arguments to be passed to the Node.js instance.</param>
|
/// <param name="commandLineArguments">Additional command-line arguments to be passed to the Node.js instance.</param>
|
||||||
|
/// <param name="applicationStoppingToken">A token that indicates when the host application is stopping.</param>
|
||||||
/// <param name="nodeOutputLogger">The <see cref="ILogger"/> to which the Node.js instance's stdout/stderr (and other log information) should be written.</param>
|
/// <param name="nodeOutputLogger">The <see cref="ILogger"/> to which the Node.js instance's stdout/stderr (and other log information) should be written.</param>
|
||||||
/// <param name="environmentVars">Environment variables to be set on the Node.js process.</param>
|
/// <param name="environmentVars">Environment variables to be set on the Node.js process.</param>
|
||||||
/// <param name="invocationTimeoutMilliseconds">The maximum duration, in milliseconds, to wait for RPC calls to complete.</param>
|
/// <param name="invocationTimeoutMilliseconds">The maximum duration, in milliseconds, to wait for RPC calls to complete.</param>
|
||||||
@@ -55,6 +56,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
string projectPath,
|
string projectPath,
|
||||||
string[] watchFileExtensions,
|
string[] watchFileExtensions,
|
||||||
string commandLineArguments,
|
string commandLineArguments,
|
||||||
|
CancellationToken applicationStoppingToken,
|
||||||
ILogger nodeOutputLogger,
|
ILogger nodeOutputLogger,
|
||||||
IDictionary<string, string> environmentVars,
|
IDictionary<string, string> environmentVars,
|
||||||
int invocationTimeoutMilliseconds,
|
int invocationTimeoutMilliseconds,
|
||||||
@@ -67,7 +69,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
OutputLogger = nodeOutputLogger;
|
OutputLogger = nodeOutputLogger;
|
||||||
_entryPointScript = new StringAsTempFile(entryPointScript);
|
_entryPointScript = new StringAsTempFile(entryPointScript, applicationStoppingToken);
|
||||||
_invocationTimeoutMilliseconds = invocationTimeoutMilliseconds;
|
_invocationTimeoutMilliseconds = invocationTimeoutMilliseconds;
|
||||||
_launchWithDebugging = launchWithDebugging;
|
_launchWithDebugging = launchWithDebugging;
|
||||||
|
|
||||||
@@ -315,11 +317,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
|
|
||||||
private static void SetEnvironmentVariable(ProcessStartInfo startInfo, string name, string value)
|
private static void SetEnvironmentVariable(ProcessStartInfo startInfo, string name, string value)
|
||||||
{
|
{
|
||||||
#if NET451
|
|
||||||
startInfo.EnvironmentVariables[name] = value;
|
|
||||||
#else
|
|
||||||
startInfo.Environment[name] = value;
|
startInfo.Environment[name] = value;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Process LaunchNodeProcess(ProcessStartInfo startInfo)
|
private static Process LaunchNodeProcess(ProcessStartInfo startInfo)
|
||||||
@@ -383,12 +381,6 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
{
|
{
|
||||||
OutputLogger.LogWarning(evt.Data);
|
OutputLogger.LogWarning(evt.Data);
|
||||||
}
|
}
|
||||||
else if (!initializationIsCompleted)
|
|
||||||
{
|
|
||||||
_connectionIsReadySource.SetException(
|
|
||||||
new InvalidOperationException("The Node.js process failed to initialize: " + evt.Data));
|
|
||||||
initializationIsCompleted = true;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OnErrorDataReceived(UnencodeNewlines(evt.Data));
|
OnErrorDataReceived(UnencodeNewlines(evt.Data));
|
||||||
@@ -402,9 +394,11 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
|
|
||||||
private static bool IsDebuggerMessage(string message)
|
private static bool IsDebuggerMessage(string message)
|
||||||
{
|
{
|
||||||
return message.StartsWith("Debugger attached", StringComparison.OrdinalIgnoreCase) ||
|
return message.StartsWith("Debugger attached", StringComparison.Ordinal) ||
|
||||||
message.StartsWith("Debugger listening ", StringComparison.OrdinalIgnoreCase) ||
|
message.StartsWith("Debugger listening ", StringComparison.Ordinal) ||
|
||||||
message.StartsWith("To start debugging", StringComparison.OrdinalIgnoreCase) ||
|
message.StartsWith("To start debugging", StringComparison.Ordinal) ||
|
||||||
|
message.Equals("Warning: This is an experimental feature and could change at any time.", StringComparison.Ordinal) ||
|
||||||
|
message.Equals("For help see https://nodejs.org/en/docs/inspector", StringComparison.Ordinal) ||
|
||||||
message.Contains("chrome-devtools:");
|
message.Contains("chrome-devtools:");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>Invoke Node.js modules at runtime in ASP.NET Core applications.</Description>
|
<Description>Invoke Node.js modules at runtime in ASP.NET Core applications.</Description>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<PackageTags>aspnetcore;aspnetcoremvc;nodeservices</PackageTags>
|
<PackageTags>aspnetcore;aspnetcoremvc;nodeservices</PackageTags>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -19,12 +20,6 @@
|
|||||||
<PackageReference Include="Newtonsoft.Json" Version="$(JsonNetVersion)" />
|
<PackageReference Include="Newtonsoft.Json" Version="$(JsonNetVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">
|
|
||||||
<PackageReference Include="System.Diagnostics.Process" Version="$(CoreFxVersion)" />
|
|
||||||
<PackageReference Include="System.IO.FileSystem.Watcher" Version="$(CoreFxVersion)" />
|
|
||||||
<PackageReference Include="System.Runtime.Loader" Version="$(CoreFxVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
|
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
|
||||||
<Exec Command="npm install" />
|
<Exec Command="npm install" />
|
||||||
<Exec Command="node node_modules/webpack/bin/webpack.js" />
|
<Exec Command="node node_modules/webpack/bin/webpack.js" />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices
|
namespace Microsoft.AspNetCore.NodeServices
|
||||||
{
|
{
|
||||||
@@ -11,27 +12,21 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
private bool _disposedValue;
|
private bool _disposedValue;
|
||||||
private bool _hasDeletedTempFile;
|
private bool _hasDeletedTempFile;
|
||||||
private object _fileDeletionLock = new object();
|
private object _fileDeletionLock = new object();
|
||||||
|
private IDisposable _applicationLifetimeRegistration;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new instance of <see cref="StringAsTempFile"/>.
|
/// Create a new instance of <see cref="StringAsTempFile"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="content">The contents of the temporary file to be created.</param>
|
/// <param name="content">The contents of the temporary file to be created.</param>
|
||||||
public StringAsTempFile(string content)
|
/// <param name="applicationStoppingToken">A token that indicates when the host application is stopping.</param>
|
||||||
|
public StringAsTempFile(string content, CancellationToken applicationStoppingToken)
|
||||||
{
|
{
|
||||||
FileName = Path.GetTempFileName();
|
FileName = Path.GetTempFileName();
|
||||||
File.WriteAllText(FileName, content);
|
File.WriteAllText(FileName, content);
|
||||||
|
|
||||||
// Because .NET finalizers don't reliably run when the process is terminating, also
|
// Because .NET finalizers don't reliably run when the process is terminating, also
|
||||||
// add event handlers for other shutdown scenarios.
|
// add event handlers for other shutdown scenarios.
|
||||||
#if NET451
|
_applicationLifetimeRegistration = applicationStoppingToken.Register(EnsureTempFileDeleted);
|
||||||
AppDomain.CurrentDomain.ProcessExit += HandleProcessExit;
|
|
||||||
AppDomain.CurrentDomain.DomainUnload += HandleProcessExit;
|
|
||||||
#else
|
|
||||||
// Note that this still doesn't capture SIGKILL (at least on macOS) - there doesn't
|
|
||||||
// appear to be a way of doing that. So in that case, the temporary file will be
|
|
||||||
// left behind.
|
|
||||||
System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += HandleAssemblyUnloading;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -55,12 +50,7 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
// Dispose managed state
|
// Dispose managed state
|
||||||
#if NET451
|
_applicationLifetimeRegistration.Dispose();
|
||||||
AppDomain.CurrentDomain.ProcessExit -= HandleProcessExit;
|
|
||||||
AppDomain.CurrentDomain.DomainUnload -= HandleProcessExit;
|
|
||||||
#else
|
|
||||||
System.Runtime.Loader.AssemblyLoadContext.Default.Unloading -= HandleAssemblyUnloading;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EnsureTempFileDeleted();
|
EnsureTempFileDeleted();
|
||||||
@@ -81,18 +71,6 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if NET451
|
|
||||||
private void HandleProcessExit(object sender, EventArgs args)
|
|
||||||
{
|
|
||||||
EnsureTempFileDeleted();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
private void HandleAssemblyUnloading(System.Runtime.Loader.AssemblyLoadContext context)
|
|
||||||
{
|
|
||||||
EnsureTempFileDeleted();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements the finalization part of the IDisposable pattern by calling Dispose(false).
|
/// Implements the finalization part of the IDisposable pattern by calling Dispose(false).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -4,15 +4,17 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>Helpers for building single-page applications on ASP.NET MVC Core.</Description>
|
<Description>Helpers for building single-page applications on ASP.NET MVC Core.</Description>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<PackageTags>aspnetcore;aspnetcoremvc;nodeservices</PackageTags>
|
<PackageTags>aspnetcore;aspnetcoremvc;nodeservices</PackageTags>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Content\**\*" />
|
<EmbeddedResource Include="Content\**\*" />
|
||||||
<ProjectReference Include="..\Microsoft.AspNetCore.NodeServices\Microsoft.AspNetCore.NodeServices.csproj" />
|
<ProjectReference Include="..\Microsoft.AspNetCore.NodeServices\Microsoft.AspNetCore.NodeServices.csproj" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(AspNetCoreVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.TagHelpers" Version="$(AspNetCoreVersion)" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="$(AspNetCoreVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
|
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
@@ -24,6 +25,7 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
|
|||||||
private static INodeServices _fallbackNodeServices; // Used only if no INodeServices was registered with DI
|
private static INodeServices _fallbackNodeServices; // Used only if no INodeServices was registered with DI
|
||||||
|
|
||||||
private readonly string _applicationBasePath;
|
private readonly string _applicationBasePath;
|
||||||
|
private readonly CancellationToken _applicationStoppingToken;
|
||||||
private readonly INodeServices _nodeServices;
|
private readonly INodeServices _nodeServices;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -35,6 +37,9 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
|
|||||||
var hostEnv = (IHostingEnvironment) serviceProvider.GetService(typeof(IHostingEnvironment));
|
var hostEnv = (IHostingEnvironment) serviceProvider.GetService(typeof(IHostingEnvironment));
|
||||||
_nodeServices = (INodeServices) serviceProvider.GetService(typeof(INodeServices)) ?? _fallbackNodeServices;
|
_nodeServices = (INodeServices) serviceProvider.GetService(typeof(INodeServices)) ?? _fallbackNodeServices;
|
||||||
_applicationBasePath = hostEnv.ContentRootPath;
|
_applicationBasePath = hostEnv.ContentRootPath;
|
||||||
|
|
||||||
|
var applicationLifetime = (IApplicationLifetime) serviceProvider.GetService(typeof(IApplicationLifetime));
|
||||||
|
_applicationStoppingToken = applicationLifetime.ApplicationStopping;
|
||||||
|
|
||||||
// Consider removing the following. Having it means you can get away with not putting app.AddNodeServices()
|
// Consider removing the following. Having it means you can get away with not putting app.AddNodeServices()
|
||||||
// in your startup file, but then again it might be confusing that you don't need to.
|
// in your startup file, but then again it might be confusing that you don't need to.
|
||||||
@@ -101,6 +106,7 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
|
|||||||
var result = await Prerenderer.RenderToString(
|
var result = await Prerenderer.RenderToString(
|
||||||
_applicationBasePath,
|
_applicationBasePath,
|
||||||
_nodeServices,
|
_nodeServices,
|
||||||
|
_applicationStoppingToken,
|
||||||
new JavaScriptModuleExport(ModuleName)
|
new JavaScriptModuleExport(ModuleName)
|
||||||
{
|
{
|
||||||
ExportName = ExportName
|
ExportName = ExportName
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.NodeServices;
|
using Microsoft.AspNetCore.NodeServices;
|
||||||
|
|
||||||
@@ -9,22 +10,16 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Prerenderer
|
public static class Prerenderer
|
||||||
{
|
{
|
||||||
private static readonly Lazy<StringAsTempFile> NodeScript;
|
private static readonly object CreateNodeScriptLock = new object();
|
||||||
|
|
||||||
static Prerenderer()
|
private static StringAsTempFile NodeScript;
|
||||||
{
|
|
||||||
NodeScript = new Lazy<StringAsTempFile>(() =>
|
|
||||||
{
|
|
||||||
var script = EmbeddedResourceReader.Read(typeof(Prerenderer), "/Content/Node/prerenderer.js");
|
|
||||||
return new StringAsTempFile(script); // Will be cleaned up on process exit
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs server-side prerendering by invoking code in Node.js.
|
/// Performs server-side prerendering by invoking code in Node.js.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="applicationBasePath">The root path to your application. This is used when resolving project-relative paths.</param>
|
/// <param name="applicationBasePath">The root path to your application. This is used when resolving project-relative paths.</param>
|
||||||
/// <param name="nodeServices">The instance of <see cref="INodeServices"/> that will be used to invoke JavaScript code.</param>
|
/// <param name="nodeServices">The instance of <see cref="INodeServices"/> that will be used to invoke JavaScript code.</param>
|
||||||
|
/// <param name="applicationStoppingToken">A token that indicates when the host application is stopping.</param>
|
||||||
/// <param name="bootModule">The path to the JavaScript file containing the prerendering logic.</param>
|
/// <param name="bootModule">The path to the JavaScript file containing the prerendering logic.</param>
|
||||||
/// <param name="requestAbsoluteUrl">The URL of the currently-executing HTTP request. This is supplied to the prerendering code.</param>
|
/// <param name="requestAbsoluteUrl">The URL of the currently-executing HTTP request. This is supplied to the prerendering code.</param>
|
||||||
/// <param name="requestPathAndQuery">The path and query part of the URL of the currently-executing HTTP request. This is supplied to the prerendering code.</param>
|
/// <param name="requestPathAndQuery">The path and query part of the URL of the currently-executing HTTP request. This is supplied to the prerendering code.</param>
|
||||||
@@ -35,6 +30,7 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
|
|||||||
public static Task<RenderToStringResult> RenderToString(
|
public static Task<RenderToStringResult> RenderToString(
|
||||||
string applicationBasePath,
|
string applicationBasePath,
|
||||||
INodeServices nodeServices,
|
INodeServices nodeServices,
|
||||||
|
CancellationToken applicationStoppingToken,
|
||||||
JavaScriptModuleExport bootModule,
|
JavaScriptModuleExport bootModule,
|
||||||
string requestAbsoluteUrl,
|
string requestAbsoluteUrl,
|
||||||
string requestPathAndQuery,
|
string requestPathAndQuery,
|
||||||
@@ -43,7 +39,7 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
|
|||||||
string requestPathBase)
|
string requestPathBase)
|
||||||
{
|
{
|
||||||
return nodeServices.InvokeExportAsync<RenderToStringResult>(
|
return nodeServices.InvokeExportAsync<RenderToStringResult>(
|
||||||
NodeScript.Value.FileName,
|
GetNodeScriptFilename(applicationStoppingToken),
|
||||||
"renderToString",
|
"renderToString",
|
||||||
applicationBasePath,
|
applicationBasePath,
|
||||||
bootModule,
|
bootModule,
|
||||||
@@ -53,5 +49,19 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
|
|||||||
timeoutMilliseconds,
|
timeoutMilliseconds,
|
||||||
requestPathBase);
|
requestPathBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetNodeScriptFilename(CancellationToken applicationStoppingToken)
|
||||||
|
{
|
||||||
|
lock(CreateNodeScriptLock)
|
||||||
|
{
|
||||||
|
if (NodeScript == null)
|
||||||
|
{
|
||||||
|
var script = EmbeddedResourceReader.Read(typeof(Prerenderer), "/Content/Node/prerenderer.js");
|
||||||
|
NodeScript = new StringAsTempFile(script, applicationStoppingToken); // Will be cleaned up on process exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NodeScript.FileName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,15 @@ namespace Microsoft.AspNetCore.SpaServices.Webpack
|
|||||||
|
|
||||||
using (var responseStream = await responseMessage.Content.ReadAsStreamAsync())
|
using (var responseStream = await responseMessage.Content.ReadAsStreamAsync())
|
||||||
{
|
{
|
||||||
await responseStream.CopyToAsync(context.Response.Body, DefaultHttpBufferSize, context.RequestAborted);
|
try
|
||||||
|
{
|
||||||
|
await responseStream.CopyToAsync(context.Response.Body, DefaultHttpBufferSize, context.RequestAborted);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// The CopyToAsync task will be canceled if the client disconnects (e.g., user
|
||||||
|
// closes or refreshes the browser tab). Don't treat this as an error.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.NodeServices;
|
using Microsoft.AspNetCore.NodeServices;
|
||||||
using Microsoft.AspNetCore.SpaServices.Webpack;
|
using Microsoft.AspNetCore.SpaServices.Webpack;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Builder
|
namespace Microsoft.AspNetCore.Builder
|
||||||
{
|
{
|
||||||
@@ -54,7 +49,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||||||
// middleware). And since this is a dev-time-only feature, it doesn't matter if the default transport isn't
|
// middleware). And since this is a dev-time-only feature, it doesn't matter if the default transport isn't
|
||||||
// as fast as some theoretical future alternative.
|
// as fast as some theoretical future alternative.
|
||||||
var nodeServicesOptions = new NodeServicesOptions(appBuilder.ApplicationServices);
|
var nodeServicesOptions = new NodeServicesOptions(appBuilder.ApplicationServices);
|
||||||
nodeServicesOptions.WatchFileExtensions = new string[] {}; // Don't watch anything
|
nodeServicesOptions.WatchFileExtensions = new string[] { }; // Don't watch anything
|
||||||
if (!string.IsNullOrEmpty(options.ProjectPath))
|
if (!string.IsNullOrEmpty(options.ProjectPath))
|
||||||
{
|
{
|
||||||
nodeServicesOptions.ProjectPath = options.ProjectPath;
|
nodeServicesOptions.ProjectPath = options.ProjectPath;
|
||||||
@@ -73,7 +68,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||||||
// Get a filename matching the middleware Node script
|
// Get a filename matching the middleware Node script
|
||||||
var script = EmbeddedResourceReader.Read(typeof(WebpackDevMiddleware),
|
var script = EmbeddedResourceReader.Read(typeof(WebpackDevMiddleware),
|
||||||
"/Content/Node/webpack-dev-middleware.js");
|
"/Content/Node/webpack-dev-middleware.js");
|
||||||
var nodeScript = new StringAsTempFile(script); // Will be cleaned up on process exit
|
var nodeScript = new StringAsTempFile(script, nodeServicesOptions.ApplicationStoppingToken); // Will be cleaned up on process exit
|
||||||
|
|
||||||
// Ideally, this would be relative to the application's PathBase (so it could work in virtual directories)
|
// Ideally, this would be relative to the application's PathBase (so it could work in virtual directories)
|
||||||
// but it's not clear that such information exists during application startup, as opposed to within the context
|
// but it's not clear that such information exists during application startup, as opposed to within the context
|
||||||
|
|||||||
@@ -1,19 +1,27 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' == ''">netcoreapp2.0</TargetFramework>
|
||||||
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' != ''">TargetFrameworkOverride</TargetFramework>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
|
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-*" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-preview2-final" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-*" />
|
</ItemGroup>
|
||||||
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
|
<PackageReference Include="NETStandard.Library.NETFramework" Version="2.0.0-preview2-25405-01" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-preview2-final" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-*" />
|
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-preview2-final" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -21,7 +29,23 @@
|
|||||||
<Content Remove="ClientApp\**" />
|
<Content Remove="ClientApp\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="RunWebpack" AfterTargets="ComputeFilesToPublish">
|
<!--/-:cnd:noEmit -->
|
||||||
|
<Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('wwwroot\dist') ">
|
||||||
|
<!-- 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." />
|
||||||
|
|
||||||
|
<!-- In development, the dist files won't exist on the first run or when cloning to
|
||||||
|
a different machine, so rebuild them if not already present. -->
|
||||||
|
<Message Importance="high" Text="Performing first-run Webpack build..." />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js" />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js" />
|
||||||
|
</Target>
|
||||||
|
<!--/+:cnd:noEmit -->
|
||||||
|
|
||||||
|
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
|
||||||
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
||||||
<Exec Command="npm install" />
|
<Exec Command="npm install" />
|
||||||
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
||||||
|
|||||||
17
templates/AngularSpa/ClientApp/app/app.module.browser.ts
Normal file
17
templates/AngularSpa/ClientApp/app/app.module.browser.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { AppModuleShared } from './app.module.shared';
|
||||||
|
import { AppComponent } from './components/app/app.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
bootstrap: [ AppComponent ],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
AppModuleShared
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: 'ORIGIN_URL', useValue: location.origin }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class AppModule {
|
||||||
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
import { HttpModule } from '@angular/http';
|
|
||||||
import { sharedConfig } from './app.module.shared';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
bootstrap: sharedConfig.bootstrap,
|
|
||||||
declarations: sharedConfig.declarations,
|
|
||||||
imports: [
|
|
||||||
BrowserModule,
|
|
||||||
FormsModule,
|
|
||||||
HttpModule,
|
|
||||||
...sharedConfig.imports
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
{ provide: 'ORIGIN_URL', useValue: location.origin }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class AppModule {
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { ServerModule } from '@angular/platform-server';
|
import { ServerModule } from '@angular/platform-server';
|
||||||
import { sharedConfig } from './app.module.shared';
|
import { AppModuleShared } from './app.module.shared';
|
||||||
|
import { AppComponent } from './components/app/app.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
bootstrap: sharedConfig.bootstrap,
|
bootstrap: [ AppComponent ],
|
||||||
declarations: sharedConfig.declarations,
|
|
||||||
imports: [
|
imports: [
|
||||||
ServerModule,
|
ServerModule,
|
||||||
...sharedConfig.imports
|
AppModuleShared
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { HttpModule } from '@angular/http';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
import { AppComponent } from './components/app/app.component'
|
import { AppComponent } from './components/app/app.component';
|
||||||
import { NavMenuComponent } from './components/navmenu/navmenu.component';
|
import { NavMenuComponent } from './components/navmenu/navmenu.component';
|
||||||
import { HomeComponent } from './components/home/home.component';
|
import { HomeComponent } from './components/home/home.component';
|
||||||
import { FetchDataComponent } from './components/fetchdata/fetchdata.component';
|
import { FetchDataComponent } from './components/fetchdata/fetchdata.component';
|
||||||
import { CounterComponent } from './components/counter/counter.component';
|
import { CounterComponent } from './components/counter/counter.component';
|
||||||
|
|
||||||
export const sharedConfig: NgModule = {
|
@NgModule({
|
||||||
bootstrap: [ AppComponent ],
|
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
NavMenuComponent,
|
NavMenuComponent,
|
||||||
@@ -17,6 +19,9 @@ export const sharedConfig: NgModule = {
|
|||||||
HomeComponent
|
HomeComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
HttpModule,
|
||||||
|
FormsModule,
|
||||||
RouterModule.forRoot([
|
RouterModule.forRoot([
|
||||||
{ path: '', redirectTo: 'home', pathMatch: 'full' },
|
{ path: '', redirectTo: 'home', pathMatch: 'full' },
|
||||||
{ path: 'home', component: HomeComponent },
|
{ path: 'home', component: HomeComponent },
|
||||||
@@ -25,4 +30,6 @@ export const sharedConfig: NgModule = {
|
|||||||
{ path: '**', redirectTo: 'home' }
|
{ path: '**', redirectTo: 'home' }
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
};
|
})
|
||||||
|
export class AppModuleShared {
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import 'reflect-metadata';
|
import 'reflect-metadata';
|
||||||
import 'zone.js';
|
import 'zone.js';
|
||||||
|
import 'bootstrap';
|
||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode } from '@angular/core';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
import { AppModule } from './app/app.module.client';
|
import { AppModule } from './app/app.module.browser';
|
||||||
|
|
||||||
if (module['hot']) {
|
if (module['hot']) {
|
||||||
module['hot'].accept();
|
module['hot'].accept();
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"sdk": { "version": "sdkVersionInjectedHere" }
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,46 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' == ''">netcoreapp2.0</TargetFramework>
|
||||||
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' != ''">TargetFrameworkOverride</TargetFramework>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
|
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-*" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-preview2-final" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-*" />
|
</ItemGroup>
|
||||||
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
|
<PackageReference Include="NETStandard.Library.NETFramework" Version="2.0.0-preview2-25405-01" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-preview2-final" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-*" />
|
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="RunWebpack" AfterTargets="ComputeFilesToPublish">
|
<!--/-:cnd:noEmit -->
|
||||||
|
<Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('wwwroot\dist') ">
|
||||||
|
<!-- 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." />
|
||||||
|
|
||||||
|
<!-- In development, the dist files won't exist on the first run or when cloning to
|
||||||
|
a different machine, so rebuild them if not already present. -->
|
||||||
|
<Message Importance="high" Text="Performing first-run Webpack build..." />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js" />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js" />
|
||||||
|
</Target>
|
||||||
|
<!--/+:cnd:noEmit -->
|
||||||
|
|
||||||
|
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
|
||||||
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
||||||
<Exec Command="npm install" />
|
<Exec Command="npm install" />
|
||||||
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"sdk": { "version": "sdkVersionInjectedHere" }
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,46 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' == ''">netcoreapp2.0</TargetFramework>
|
||||||
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' != ''">TargetFrameworkOverride</TargetFramework>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
|
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-*" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-preview2-final" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-*" />
|
</ItemGroup>
|
||||||
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
|
<PackageReference Include="NETStandard.Library.NETFramework" Version="2.0.0-preview2-25405-01" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-preview2-final" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-*" />
|
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="RunWebpack" AfterTargets="ComputeFilesToPublish">
|
<!--/-:cnd:noEmit -->
|
||||||
|
<Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('wwwroot\dist') ">
|
||||||
|
<!-- 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." />
|
||||||
|
|
||||||
|
<!-- In development, the dist files won't exist on the first run or when cloning to
|
||||||
|
a different machine, so rebuild them if not already present. -->
|
||||||
|
<Message Importance="high" Text="Performing first-run Webpack build..." />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js" />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js" />
|
||||||
|
</Target>
|
||||||
|
<!--/+:cnd:noEmit -->
|
||||||
|
|
||||||
|
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
|
||||||
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
||||||
<Exec Command="npm install" />
|
<Exec Command="npm install" />
|
||||||
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"sdk": { "version": "sdkVersionInjectedHere" }
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,23 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' == ''">netcoreapp2.0</TargetFramework>
|
||||||
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' != ''">TargetFrameworkOverride</TargetFramework>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
|
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-*" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-preview2-final" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-*" />
|
</ItemGroup>
|
||||||
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
|
<PackageReference Include="NETStandard.Library.NETFramework" Version="2.0.0-preview2-25405-01" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-preview2-final" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -21,7 +29,23 @@
|
|||||||
<Content Remove="ClientApp\**" />
|
<Content Remove="ClientApp\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="RunWebpack" AfterTargets="ComputeFilesToPublish">
|
<!--/-:cnd:noEmit -->
|
||||||
|
<Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('wwwroot\dist') ">
|
||||||
|
<!-- 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." />
|
||||||
|
|
||||||
|
<!-- In development, the dist files won't exist on the first run or when cloning to
|
||||||
|
a different machine, so rebuild them if not already present. -->
|
||||||
|
<Message Importance="high" Text="Performing first-run Webpack build..." />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js" />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js" />
|
||||||
|
</Target>
|
||||||
|
<!--/+:cnd:noEmit -->
|
||||||
|
|
||||||
|
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
|
||||||
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
||||||
<Exec Command="npm install" />
|
<Exec Command="npm install" />
|
||||||
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"sdk": { "version": "sdkVersionInjectedHere" }
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,46 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' == ''">netcoreapp2.0</TargetFramework>
|
||||||
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' != ''">TargetFrameworkOverride</TargetFramework>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
|
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-*" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-preview2-final" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-*" />
|
</ItemGroup>
|
||||||
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
|
<PackageReference Include="NETStandard.Library.NETFramework" Version="2.0.0-preview2-25405-01" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-preview2-final" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-*" />
|
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="RunWebpack" AfterTargets="ComputeFilesToPublish">
|
<!--/-:cnd:noEmit -->
|
||||||
|
<Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('wwwroot\dist') ">
|
||||||
|
<!-- 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." />
|
||||||
|
|
||||||
|
<!-- In development, the dist files won't exist on the first run or when cloning to
|
||||||
|
a different machine, so rebuild them if not already present. -->
|
||||||
|
<Message Importance="high" Text="Performing first-run Webpack build..." />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js" />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js" />
|
||||||
|
</Target>
|
||||||
|
<!--/+:cnd:noEmit -->
|
||||||
|
|
||||||
|
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
|
||||||
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
||||||
<Exec Command="npm install" />
|
<Exec Command="npm install" />
|
||||||
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"sdk": { "version": "sdkVersionInjectedHere" }
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,46 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' == ''">netcoreapp2.0</TargetFramework>
|
||||||
|
<TargetFramework Condition="'$(TargetFrameworkOverride)' != ''">TargetFrameworkOverride</TargetFramework>
|
||||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||||
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
|
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-*" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-preview2-final" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-*" />
|
</ItemGroup>
|
||||||
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
|
<PackageReference Include="NETStandard.Library.NETFramework" Version="2.0.0-preview2-25405-01" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-preview2-final" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-preview2-final" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-*" />
|
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="RunWebpack" AfterTargets="ComputeFilesToPublish">
|
<!--/-:cnd:noEmit -->
|
||||||
|
<Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('wwwroot\dist') ">
|
||||||
|
<!-- 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." />
|
||||||
|
|
||||||
|
<!-- In development, the dist files won't exist on the first run or when cloning to
|
||||||
|
a different machine, so rebuild them if not already present. -->
|
||||||
|
<Message Importance="high" Text="Performing first-run Webpack build..." />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js" />
|
||||||
|
<Exec Command="node node_modules/webpack/bin/webpack.js" />
|
||||||
|
</Target>
|
||||||
|
<!--/+:cnd:noEmit -->
|
||||||
|
|
||||||
|
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
|
||||||
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
||||||
<Exec Command="npm install" />
|
<Exec Command="npm install" />
|
||||||
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"sdk": { "version": "sdkVersionInjectedHere" }
|
|
||||||
}
|
|
||||||
@@ -11,26 +11,29 @@ import * as targz from 'tar.gz';
|
|||||||
const isWindows = /^win/.test(process.platform);
|
const isWindows = /^win/.test(process.platform);
|
||||||
const textFileExtensions = ['.gitignore', 'template_gitignore', '.config', '.cs', '.cshtml', '.csproj', '.html', '.js', '.json', '.jsx', '.md', '.nuspec', '.ts', '.tsx'];
|
const textFileExtensions = ['.gitignore', 'template_gitignore', '.config', '.cs', '.cshtml', '.csproj', '.html', '.js', '.json', '.jsx', '.md', '.nuspec', '.ts', '.tsx'];
|
||||||
const yeomanGeneratorSource = './src/yeoman';
|
const yeomanGeneratorSource = './src/yeoman';
|
||||||
|
const webToolsVSPackageGuid = '{0CD94836-1526-4E85-87D3-FB5274C5AFC9}';
|
||||||
|
|
||||||
// To support the "dotnet new" templates, we want to bundle prebuilt dist dev-mode files, because "dotnet new" can't auto-run
|
const dotNetPackages = {
|
||||||
// webpack on project creation. Note that these script entries are *not* the same as the project's usual prepublish
|
builtIn: 'Microsoft.DotNet.Web.Spa.ProjectTemplates',
|
||||||
// scripts, because here we want dev-mode builds (e.g., to support HMR), not prod-mode builds.
|
extra: 'Microsoft.AspNetCore.SpaTemplates'
|
||||||
const commonTemplatePrepublishSteps = [
|
|
||||||
'npm install',
|
|
||||||
'node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js',
|
|
||||||
'node node_modules/webpack/bin/webpack.js'
|
|
||||||
];
|
|
||||||
const commonForceInclusionRegex = /^(wwwroot|ClientApp)\/dist\//; // Files to be included in template, even though gitignored
|
|
||||||
|
|
||||||
const templates: { [key: string]: { dir: string, dotNetNewId: string, displayName: string, prepublish?: string[], forceInclusion?: RegExp } } = {
|
|
||||||
'angular': { dir: '../../templates/AngularSpa/', dotNetNewId: 'Angular', displayName: 'Angular' },
|
|
||||||
'aurelia': { dir: '../../templates/AureliaSpa/', dotNetNewId: 'Aurelia', displayName: 'Aurelia' },
|
|
||||||
'knockout': { dir: '../../templates/KnockoutSpa/', dotNetNewId: 'Knockout', displayName: 'Knockout.js' },
|
|
||||||
'react-redux': { dir: '../../templates/ReactReduxSpa/', dotNetNewId: 'ReactRedux', displayName: 'React.js and Redux' },
|
|
||||||
'react': { dir: '../../templates/ReactSpa/', dotNetNewId: 'React', displayName: 'React.js' },
|
|
||||||
'vue': { dir: '../../templates/VueSpa/', dotNetNewId: 'Vue', displayName: 'Vue.js' }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface TemplateConfig {
|
||||||
|
dir: string;
|
||||||
|
dotNetNewId: string;
|
||||||
|
dotNetPackageId: string;
|
||||||
|
displayName: string;
|
||||||
|
localizationIdStart: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const templates: { [key: string]: TemplateConfig } = {
|
||||||
|
'angular': { dotNetPackageId: dotNetPackages.builtIn, dir: '../../templates/AngularSpa/', dotNetNewId: 'Angular', displayName: 'Angular', localizationIdStart: 1100 },
|
||||||
|
'aurelia': { dotNetPackageId: dotNetPackages.extra, dir: '../../templates/AureliaSpa/', dotNetNewId: 'Aurelia', displayName: 'Aurelia', localizationIdStart: 1200 },
|
||||||
|
'knockout': { dotNetPackageId: dotNetPackages.extra, dir: '../../templates/KnockoutSpa/', dotNetNewId: 'Knockout', displayName: 'Knockout.js', localizationIdStart: 1300 },
|
||||||
|
'react-redux': { dotNetPackageId: dotNetPackages.builtIn, dir: '../../templates/ReactReduxSpa/', dotNetNewId: 'ReactRedux', displayName: 'React.js and Redux', localizationIdStart: 1400 },
|
||||||
|
'react': { dotNetPackageId: dotNetPackages.builtIn, dir: '../../templates/ReactSpa/', dotNetNewId: 'React', displayName: 'React.js', localizationIdStart: 1500 },
|
||||||
|
'vue': { dotNetPackageId: dotNetPackages.extra, dir: '../../templates/VueSpa/', dotNetNewId: 'Vue', displayName: 'Vue.js', localizationIdStart: 1600 }
|
||||||
|
};
|
||||||
|
|
||||||
function isTextFile(filename: string): boolean {
|
function isTextFile(filename: string): boolean {
|
||||||
return textFileExtensions.indexOf(path.extname(filename).toLowerCase()) >= 0
|
return textFileExtensions.indexOf(path.extname(filename).toLowerCase()) >= 0
|
||||||
@@ -43,7 +46,7 @@ function writeFileEnsuringDirExists(root: string, filename: string, contents: st
|
|||||||
fs.writeFileSync(fullPath, contents);
|
fs.writeFileSync(fullPath, contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
function listFilesExcludingGitignored(root: string, forceInclusion: RegExp): string[] {
|
function listFilesExcludingGitignored(root: string): string[] {
|
||||||
// Note that the gitignore files, prior to be written by the generator, are called 'template_gitignore'
|
// Note that the gitignore files, prior to be written by the generator, are called 'template_gitignore'
|
||||||
// instead of '.gitignore'. This is a workaround for Yeoman doing strange stuff with .gitignore files
|
// instead of '.gitignore'. This is a workaround for Yeoman doing strange stuff with .gitignore files
|
||||||
// (it renames them to .npmignore, which is not helpful).
|
// (it renames them to .npmignore, which is not helpful).
|
||||||
@@ -52,21 +55,23 @@ function listFilesExcludingGitignored(root: string, forceInclusion: RegExp): str
|
|||||||
? gitignore.compile(fs.readFileSync(gitIgnorePath, 'utf8'))
|
? gitignore.compile(fs.readFileSync(gitIgnorePath, 'utf8'))
|
||||||
: { accepts: () => true };
|
: { accepts: () => true };
|
||||||
return glob.sync('**/*', { cwd: root, dot: true, nodir: true })
|
return glob.sync('**/*', { cwd: root, dot: true, nodir: true })
|
||||||
.filter(fn => gitignoreEvaluator.accepts(fn) || (forceInclusion && forceInclusion.test(fn)));
|
.filter(fn => gitignoreEvaluator.accepts(fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeTemplate(sourceRoot: string, destRoot: string, contentReplacements: { from: RegExp, to: string }[], filenameReplacements: { from: RegExp, to: string }[], forceInclusion: RegExp) {
|
function applyContentReplacements(sourceContent: Buffer, contentReplacements: { from: RegExp, to: string }[]) {
|
||||||
listFilesExcludingGitignored(sourceRoot, forceInclusion).forEach(fn => {
|
let sourceText = sourceContent.toString('utf8');
|
||||||
|
contentReplacements.forEach(replacement => {
|
||||||
|
sourceText = sourceText.replace(replacement.from, replacement.to);
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Buffer(sourceText, 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeTemplate(sourceRoot: string, destRoot: string, contentReplacements: { from: RegExp, to: string }[], filenameReplacements: { from: RegExp, to: string }[]) {
|
||||||
|
listFilesExcludingGitignored(sourceRoot).forEach(fn => {
|
||||||
let sourceContent = fs.readFileSync(path.join(sourceRoot, fn));
|
let sourceContent = fs.readFileSync(path.join(sourceRoot, fn));
|
||||||
|
|
||||||
// For text files, replace hardcoded values with template tags
|
|
||||||
if (isTextFile(fn)) {
|
if (isTextFile(fn)) {
|
||||||
let sourceText = sourceContent.toString('utf8');
|
sourceContent = applyContentReplacements(sourceContent, contentReplacements);
|
||||||
contentReplacements.forEach(replacement => {
|
|
||||||
sourceText = sourceText.replace(replacement.from, replacement.to);
|
|
||||||
});
|
|
||||||
|
|
||||||
sourceContent = new Buffer(sourceText, 'utf8');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also apply replacements in filenames
|
// Also apply replacements in filenames
|
||||||
@@ -86,6 +91,22 @@ function copyRecursive(sourceRoot: string, destRoot: string, matchGlob: string)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function leftPad(str: string, minLength: number, padChar: string) {
|
||||||
|
while (str.length < minLength) {
|
||||||
|
str = padChar + str;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBuildNumber(): string {
|
||||||
|
if (process.env.APPVEYOR_BUILD_NUMBER) {
|
||||||
|
return leftPad(process.env.APPVEYOR_BUILD_NUMBER, 6, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
// For local builds, use timestamp
|
||||||
|
return 't-' + Math.floor((new Date().valueOf() - new Date(2017, 0, 1).valueOf()) / (60*1000));
|
||||||
|
}
|
||||||
|
|
||||||
function buildYeomanNpmPackage(outputRoot: string) {
|
function buildYeomanNpmPackage(outputRoot: string) {
|
||||||
const outputTemplatesRoot = path.join(outputRoot, 'app/templates');
|
const outputTemplatesRoot = path.join(outputRoot, 'app/templates');
|
||||||
rimraf.sync(outputTemplatesRoot);
|
rimraf.sync(outputTemplatesRoot);
|
||||||
@@ -95,12 +116,11 @@ function buildYeomanNpmPackage(outputRoot: string) {
|
|||||||
{ from: /.*\.csproj$/, to: 'tokenreplace-namePascalCase.csproj' }
|
{ from: /.*\.csproj$/, to: 'tokenreplace-namePascalCase.csproj' }
|
||||||
];
|
];
|
||||||
const contentReplacements = [
|
const contentReplacements = [
|
||||||
// global.json items
|
// Currently, there are none
|
||||||
{ from: /sdkVersionInjectedHere/, to: '<%= sdkVersion %>' }
|
|
||||||
];
|
];
|
||||||
_.forEach(templates, (templateConfig, templateName) => {
|
_.forEach(templates, (templateConfig, templateName) => {
|
||||||
const outputDir = path.join(outputTemplatesRoot, templateName);
|
const outputDir = path.join(outputTemplatesRoot, templateName);
|
||||||
writeTemplate(templateConfig.dir, outputDir, contentReplacements, filenameReplacements, commonForceInclusionRegex);
|
writeTemplate(templateConfig.dir, outputDir, contentReplacements, filenameReplacements);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Also copy the generator files (that's the compiled .js files, plus all other non-.ts files)
|
// Also copy the generator files (that's the compiled .js files, plus all other non-.ts files)
|
||||||
@@ -112,7 +132,17 @@ function buildYeomanNpmPackage(outputRoot: string) {
|
|||||||
rimraf.sync(tempRoot);
|
rimraf.sync(tempRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildDotNetNewNuGetPackage() {
|
function buildDotNetNewNuGetPackages(outputDir: string) {
|
||||||
|
const dotNetPackageIds = _.values(dotNetPackages);
|
||||||
|
dotNetPackageIds.forEach(packageId => {
|
||||||
|
const dotNetNewNupkgPath = buildDotNetNewNuGetPackage(packageId);
|
||||||
|
|
||||||
|
// Move the .nupkg file to the output dir
|
||||||
|
fs.renameSync(dotNetNewNupkgPath, path.join(outputDir, path.basename(dotNetNewNupkgPath)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildDotNetNewNuGetPackage(packageId: string) {
|
||||||
const outputRoot = './dist/dotnetnew';
|
const outputRoot = './dist/dotnetnew';
|
||||||
rimraf.sync(outputRoot);
|
rimraf.sync(outputRoot);
|
||||||
|
|
||||||
@@ -125,8 +155,13 @@ function buildDotNetNewNuGetPackage() {
|
|||||||
];
|
];
|
||||||
const contentReplacements = [];
|
const contentReplacements = [];
|
||||||
_.forEach(templates, (templateConfig, templateName) => {
|
_.forEach(templates, (templateConfig, templateName) => {
|
||||||
|
// Only include templates matching the output package ID
|
||||||
|
if (templateConfig.dotNetPackageId !== packageId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const templateOutputDir = path.join(outputRoot, 'Content', templateName);
|
const templateOutputDir = path.join(outputRoot, 'Content', templateName);
|
||||||
writeTemplate(templateConfig.dir, templateOutputDir, contentReplacements, filenameReplacements, commonForceInclusionRegex);
|
writeTemplate(templateConfig.dir, templateOutputDir, contentReplacements, filenameReplacements);
|
||||||
|
|
||||||
// Add the .template.config dir and its contents
|
// Add the .template.config dir and its contents
|
||||||
const templateConfigDir = path.join(templateOutputDir, '.template.config');
|
const templateConfigDir = path.join(templateOutputDir, '.template.config');
|
||||||
@@ -134,10 +169,10 @@ function buildDotNetNewNuGetPackage() {
|
|||||||
|
|
||||||
fs.writeFileSync(path.join(templateConfigDir, 'template.json'), JSON.stringify({
|
fs.writeFileSync(path.join(templateConfigDir, 'template.json'), JSON.stringify({
|
||||||
author: 'Microsoft',
|
author: 'Microsoft',
|
||||||
classifications: ["Web", "MVC", "SPA"],
|
classifications: ['Web', 'MVC', 'SPA'],
|
||||||
groupIdentity: `Microsoft.AspNetCore.SpaTemplates.${templateConfig.dotNetNewId}`,
|
groupIdentity: `${packageId}.${templateConfig.dotNetNewId}`,
|
||||||
identity: `Microsoft.AspNetCore.SpaTemplates.${templateConfig.dotNetNewId}.CSharp`,
|
identity: `${packageId}.${templateConfig.dotNetNewId}.CSharp`,
|
||||||
name: `MVC ASP.NET Core with ${templateConfig.displayName}`,
|
name: `ASP.NET Core with ${templateConfig.displayName}`,
|
||||||
preferNameDirectory: true,
|
preferNameDirectory: true,
|
||||||
primaryOutputs: [{ path: `${sourceProjectName}.csproj` }],
|
primaryOutputs: [{ path: `${sourceProjectName}.csproj` }],
|
||||||
shortName: `${templateConfig.dotNetNewId.toLowerCase()}`,
|
shortName: `${templateConfig.dotNetNewId.toLowerCase()}`,
|
||||||
@@ -148,46 +183,116 @@ function buildDotNetNewNuGetPackage() {
|
|||||||
exclude: ['.template.config/**']
|
exclude: ['.template.config/**']
|
||||||
}],
|
}],
|
||||||
symbols: {
|
symbols: {
|
||||||
sdkVersion: {
|
TargetFrameworkOverride: {
|
||||||
type: 'bind',
|
type: 'parameter',
|
||||||
binding: 'dotnet-cli-version',
|
description: 'Overrides the target framework',
|
||||||
replaces: 'sdkVersionInjectedHere'
|
replaces: 'TargetFrameworkOverride',
|
||||||
|
datatype: 'string',
|
||||||
|
defaultValue: ''
|
||||||
},
|
},
|
||||||
Framework: {
|
Framework: {
|
||||||
type: "parameter",
|
type: 'parameter',
|
||||||
description: "The target framework for the project.",
|
description: 'The target framework for the project.',
|
||||||
datatype: "choice",
|
datatype: 'choice',
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
choice: "netcoreapp1.1",
|
choice: 'netcoreapp2.0',
|
||||||
description: "Target netcoreapp1.1"
|
description: 'Target netcoreapp2.0'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
defaultValue: "netcoreapp1.1"
|
replaces: 'netcoreapp2.0',
|
||||||
|
defaultValue: 'netcoreapp2.0'
|
||||||
|
},
|
||||||
|
HostIdentifier: {
|
||||||
|
type: 'bind',
|
||||||
|
binding: 'HostIdentifier'
|
||||||
|
},
|
||||||
|
skipRestore: {
|
||||||
|
type: 'parameter',
|
||||||
|
datatype: 'bool',
|
||||||
|
description: 'If specified, skips the automatic restore of packages on project creation.',
|
||||||
|
defaultValue: 'false'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tags: { language: 'C#', type: 'project' },
|
tags: { language: 'C#', type: 'project' },
|
||||||
|
postActions: [
|
||||||
|
{
|
||||||
|
condition: '(!skipRestore)',
|
||||||
|
description: 'Restores NuGet packages required by this project.',
|
||||||
|
manualInstructions: [{ text: 'Run \'dotnet restore\'' }],
|
||||||
|
actionId: '210D431B-A78B-4D2F-B762-4ED3E3EA9025',
|
||||||
|
continueOnError: true
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
// Currently it doesn't appear to be possible to run `npm install` from a
|
||||||
|
// postAction, due to https://github.com/dotnet/templating/issues/849
|
||||||
|
// We will re-enable this when that bug is fixed.
|
||||||
|
{
|
||||||
|
condition: '(!skipRestore)',
|
||||||
|
description: 'Restores NPM packages required by this project.',
|
||||||
|
manualInstructions: [{ text: 'Run \'npm install\'' }],
|
||||||
|
actionId: '3A7C4B45-1F5D-4A30-959A-51B88E82B5D2',
|
||||||
|
args: { executable: 'npm', args: 'install' },
|
||||||
|
continueOnError: false
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
// For the preview2 release, just display manual instructions instead.
|
||||||
|
// This is only applicable on the command line, because VS will restore
|
||||||
|
// NPM packages automatically by default.
|
||||||
|
condition: '(HostIdentifier == "dotnetcli" || HostIdentifier == "dotnetcli-preview")',
|
||||||
|
actionId: 'AC1156F7-BB77-4DB8-B28F-24EEBCCA1E5C',
|
||||||
|
description: '\n\n-------------------------------------------------------------------\nIMPORTANT: Before running this project on the command line,\n you must restore NPM packages by running "npm install"\n-------------------------------------------------------------------\n',
|
||||||
|
manualInstructions: [{ text: 'Run "npm install"' }]
|
||||||
|
}
|
||||||
|
],
|
||||||
}, null, 2));
|
}, null, 2));
|
||||||
|
|
||||||
fs.writeFileSync(path.join(templateConfigDir, 'dotnetcli.host.json'), JSON.stringify({
|
fs.writeFileSync(path.join(templateConfigDir, 'dotnetcli.host.json'), JSON.stringify({
|
||||||
symbolInfo: {}
|
$schema: 'http://json.schemastore.org/dotnetcli.host',
|
||||||
|
symbolInfo: {
|
||||||
|
TargetFrameworkOverride: {
|
||||||
|
isHidden: 'true',
|
||||||
|
longName: 'target-framework-override',
|
||||||
|
shortName: ''
|
||||||
|
},
|
||||||
|
Framework: {
|
||||||
|
longName: 'framework'
|
||||||
|
},
|
||||||
|
skipRestore: {
|
||||||
|
longName: 'no-restore',
|
||||||
|
shortName: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
}, null, 2));
|
}, null, 2));
|
||||||
|
|
||||||
|
const localisedNameId = templateConfig.localizationIdStart + 0;
|
||||||
|
const localisedDescId = templateConfig.localizationIdStart + 1;
|
||||||
|
|
||||||
fs.writeFileSync(path.join(templateConfigDir, 'vs-2017.3.host.json'), JSON.stringify({
|
fs.writeFileSync(path.join(templateConfigDir, 'vs-2017.3.host.json'), JSON.stringify({
|
||||||
name: { text: templateConfig.displayName },
|
$schema: 'http://json.schemastore.org/vs-2017.3.host',
|
||||||
description: { text: `Web application built with MVC ASP.NET Core and ${templateConfig.displayName}` },
|
name: { text: templateConfig.displayName, package: webToolsVSPackageGuid, id: localisedNameId.toString() },
|
||||||
order: 2000,
|
description: { text: `A project template for creating an ASP.NET Core application with ${templateConfig.displayName}`, package: webToolsVSPackageGuid, id: localisedDescId.toString() },
|
||||||
|
order: 301,
|
||||||
icon: 'icon.png',
|
icon: 'icon.png',
|
||||||
learnMoreLink: 'https://github.com/aspnet/JavaScriptServices',
|
learnMoreLink: 'https://github.com/aspnet/JavaScriptServices',
|
||||||
uiFilters: [ 'oneaspnet' ]
|
uiFilters: [ 'oneaspnet' ],
|
||||||
|
minFullFrameworkVersion: '4.6.1'
|
||||||
}, null, 2));
|
}, null, 2));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Invoke NuGet to create the final package
|
// Create the .nuspec file
|
||||||
const yeomanPackageVersion = JSON.parse(fs.readFileSync(path.join(yeomanGeneratorSource, 'package.json'), 'utf8')).version;
|
const yeomanPackageVersion = JSON.parse(fs.readFileSync(path.join(yeomanGeneratorSource, 'package.json'), 'utf8')).version;
|
||||||
writeTemplate('./src/dotnetnew', outputRoot, [
|
const nuspecContentTemplate = fs.readFileSync(`./src/dotnetnew/${ packageId }.nuspec`);
|
||||||
{ from: /\{version\}/g, to: yeomanPackageVersion },
|
writeFileEnsuringDirExists(outputRoot,
|
||||||
], [], null);
|
`${ packageId }.nuspec`,
|
||||||
|
applyContentReplacements(nuspecContentTemplate, [
|
||||||
|
{ from: /\{yeomanversion\}/g, to: yeomanPackageVersion },
|
||||||
|
{ from: /\{buildnumber\}/g, to: getBuildNumber() },
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
// Invoke NuGet to create the final package
|
||||||
const nugetExe = path.join(process.cwd(), './bin/NuGet.exe');
|
const nugetExe = path.join(process.cwd(), './bin/NuGet.exe');
|
||||||
const nugetStartInfo = { cwd: outputRoot, stdio: 'inherit' };
|
const nugetStartInfo = { cwd: outputRoot, stdio: 'inherit' };
|
||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
@@ -204,21 +309,7 @@ function buildDotNetNewNuGetPackage() {
|
|||||||
return glob.sync(path.join(outputRoot, './*.nupkg'))[0];
|
return glob.sync(path.join(outputRoot, './*.nupkg'))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
function runAllPrepublishScripts() {
|
function runPrepublishScripts(rootDir: string, scripts: string[]) {
|
||||||
Object.getOwnPropertyNames(templates).forEach(templateKey => {
|
|
||||||
const templateInfo = templates[templateKey];
|
|
||||||
|
|
||||||
// First run standard prepublish steps
|
|
||||||
runScripts(templateInfo.dir, commonTemplatePrepublishSteps);
|
|
||||||
|
|
||||||
// Second, run any template-specific prepublish steps
|
|
||||||
if (templateInfo.prepublish) {
|
|
||||||
runScripts(templateInfo.dir, templateInfo.prepublish);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function runScripts(rootDir: string, scripts: string[]) {
|
|
||||||
console.log(`[Prepublish] In directory: ${ rootDir }`);
|
console.log(`[Prepublish] In directory: ${ rootDir }`);
|
||||||
scripts.forEach(script => {
|
scripts.forEach(script => {
|
||||||
console.log(`[Prepublish] Running: ${ script }`);
|
console.log(`[Prepublish] Running: ${ script }`);
|
||||||
@@ -233,12 +324,8 @@ const yeomanOutputRoot = path.join(distDir, 'generator-aspnetcore-spa');
|
|||||||
|
|
||||||
rimraf.sync(distDir);
|
rimraf.sync(distDir);
|
||||||
mkdirp.sync(artifactsDir);
|
mkdirp.sync(artifactsDir);
|
||||||
runAllPrepublishScripts();
|
|
||||||
buildYeomanNpmPackage(yeomanOutputRoot);
|
buildYeomanNpmPackage(yeomanOutputRoot);
|
||||||
const dotNetNewNupkgPath = buildDotNetNewNuGetPackage();
|
buildDotNetNewNuGetPackages(artifactsDir);
|
||||||
|
|
||||||
// Move the .nupkg file to the artifacts dir
|
|
||||||
fs.renameSync(dotNetNewNupkgPath, path.join(artifactsDir, path.basename(dotNetNewNupkgPath)));
|
|
||||||
|
|
||||||
// Finally, create a .tar.gz file containing the built generator-aspnetcore-spa.
|
// Finally, create a .tar.gz file containing the built generator-aspnetcore-spa.
|
||||||
// The CI system can treat this as the final built artifact.
|
// The CI system can treat this as the final built artifact.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Microsoft.AspNetCore.SpaTemplates</id>
|
<id>Microsoft.AspNetCore.SpaTemplates</id>
|
||||||
<version>{version}</version>
|
<version>{yeomanversion}</version>
|
||||||
<description>Single Page Application templates for ASP.NET Core</description>
|
<description>Single Page Application templates for ASP.NET Core</description>
|
||||||
<authors>Microsoft</authors>
|
<authors>Microsoft</authors>
|
||||||
<language>en-US</language>
|
<language>en-US</language>
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
|
<metadata>
|
||||||
|
<id>Microsoft.DotNet.Web.Spa.ProjectTemplates</id>
|
||||||
|
<version>1.0.0-preview-{buildnumber}</version>
|
||||||
|
<description>Single Page Application templates for ASP.NET Core</description>
|
||||||
|
<authors>Microsoft</authors>
|
||||||
|
<language>en-US</language>
|
||||||
|
<projectUrl>https://github.com/aspnet/javascriptservices</projectUrl>
|
||||||
|
<licenseUrl>https://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm</licenseUrl>
|
||||||
|
<copyright>Copyright © Microsoft Corporation</copyright>
|
||||||
|
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||||
|
<packageTypes>
|
||||||
|
<packageType name="Template" />
|
||||||
|
</packageTypes>
|
||||||
|
</metadata>
|
||||||
|
</package>
|
||||||
Reference in New Issue
Block a user