mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-23 10:08:57 +00:00
Compare commits
43 Commits
release/2.
...
httpwithst
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1287709feb | ||
|
|
5f1450c9ba | ||
|
|
c83605baff | ||
|
|
fc12d722b8 | ||
|
|
372e597f34 | ||
|
|
3715ec7c3f | ||
|
|
d2eaa36372 | ||
|
|
169ef12cd8 | ||
|
|
f5d58f3f2e | ||
|
|
c2e4d4f261 | ||
|
|
50481fe23f | ||
|
|
895a61160e | ||
|
|
b8b769aa74 | ||
|
|
c4aad6bcab | ||
|
|
27f1d07d21 | ||
|
|
0cb14a3c68 | ||
|
|
2457b4ee5d | ||
|
|
789ea5a320 | ||
|
|
a902874754 | ||
|
|
f43ea777eb | ||
|
|
c79db4e8e2 | ||
|
|
d1198aeab2 | ||
|
|
9528dd7432 | ||
|
|
b8c006a3e9 | ||
|
|
a9ddf1413f | ||
|
|
8b37dc8561 | ||
|
|
7b07fb66eb | ||
|
|
cdb04c74f9 | ||
|
|
a74941e3c8 | ||
|
|
a0a710a0df | ||
|
|
d5f5ad7fdc | ||
|
|
dab0faea66 | ||
|
|
2df0febfba | ||
|
|
e65ecebac6 | ||
|
|
bb0727c34c | ||
|
|
4903e12373 | ||
|
|
56c806b34e | ||
|
|
8acba88160 | ||
|
|
b434eefd83 | ||
|
|
44360b6955 | ||
|
|
72b1e627b0 | ||
|
|
781c5dc37c | ||
|
|
c2f63f21fd |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -28,8 +28,6 @@ nuget.exe
|
|||||||
.vs/
|
.vs/
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
/.build/
|
/.build/
|
||||||
global.json
|
|
||||||
*.g.targets
|
|
||||||
|
|
||||||
# The templates can't contain their own .gitignore files, because Yeoman has strange default handling for
|
# The templates can't contain their own .gitignore files, because Yeoman has strange default handling for
|
||||||
# files with that name (https://github.com/npm/npm/issues/1862). So, each template instead has a template_gitignore
|
# files with that name (https://github.com/npm/npm/issues/1862). So, each template instead has a template_gitignore
|
||||||
@@ -42,3 +40,5 @@ global.json
|
|||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
/templates/*/Properties/launchSettings.json
|
/templates/*/Properties/launchSettings.json
|
||||||
|
global.json
|
||||||
|
korebuild-lock.txt
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
<Project>
|
|
||||||
<Import Project="version.props" />
|
|
||||||
<Import Project="build\dependencies.props" />
|
|
||||||
<Import Project="build\sources.props" />
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<Project>
|
|
||||||
<PropertyGroup>
|
|
||||||
<NETStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">$(NETStandardLibrary20PackageVersion)</NETStandardImplicitPackageVersion>
|
|
||||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">$(MicrosoftNETCoreApp20PackageVersion)</RuntimeFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<clear />
|
<clear />
|
||||||
<!-- Restore sources should be defined in build/sources.props. -->
|
<add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json" />
|
||||||
|
<add key="AspNetCoreTools" value="https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json" />
|
||||||
|
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
init:
|
init:
|
||||||
- git config --global core.autocrlf true
|
- git config --global core.autocrlf true
|
||||||
install:
|
install:
|
||||||
- ps: Install-Product node 6.9.2 x64
|
- ps: Install-Product node 6.9.2 x64
|
||||||
# .NET Core SDK binaries
|
# .NET Core SDK binaries
|
||||||
# Download .NET Core 2.0 Preview 3 SDK and add to PATH
|
# Download .NET Core 2.0 Preview 3 SDK and add to PATH
|
||||||
- ps: $urlCurrent = "https://dotnetcli.azureedge.net/dotnet/Sdk/2.0.0-preview3-006729/dotnet-sdk-2.0.0-preview3-006729-win-x64.zip"
|
- ps: $urlCurrent = "https://dotnetcli.azureedge.net/dotnet/Sdk/2.0.0-preview3-006857/dotnet-sdk-2.0.0-preview3-006857-win-x64.zip"
|
||||||
- ps: $env:DOTNET_INSTALL_DIR = "$pwd\.dotnetsdk"
|
- ps: $env:DOTNET_INSTALL_DIR = "$pwd\.dotnetsdk"
|
||||||
- ps: mkdir $env:DOTNET_INSTALL_DIR -Force | Out-Null
|
- ps: mkdir $env:DOTNET_INSTALL_DIR -Force | Out-Null
|
||||||
- ps: $tempFileCurrent = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
|
- ps: $tempFileCurrent = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
|
||||||
@@ -25,6 +25,10 @@ artifacts:
|
|||||||
type: NuGetPackage
|
type: NuGetPackage
|
||||||
# - ps: .\build.ps1
|
# - ps: .\build.ps1
|
||||||
clone_depth: 1
|
clone_depth: 1
|
||||||
|
environment:
|
||||||
|
global:
|
||||||
|
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
test_script:
|
test_script:
|
||||||
- dotnet restore
|
- dotnet restore
|
||||||
- ps: Push-Location
|
- ps: Push-Location
|
||||||
|
|||||||
37
build.ps1
37
build.ps1
@@ -24,7 +24,7 @@ The base url where build tools can be downloaded. Overrides the value from the c
|
|||||||
Updates KoreBuild to the latest version even if a lock file is present.
|
Updates KoreBuild to the latest version even if a lock file is present.
|
||||||
|
|
||||||
.PARAMETER ConfigFile
|
.PARAMETER ConfigFile
|
||||||
The path to the configuration file that stores values. Defaults to version.props.
|
The path to the configuration file that stores values. Defaults to version.xml.
|
||||||
|
|
||||||
.PARAMETER MSBuildArgs
|
.PARAMETER MSBuildArgs
|
||||||
Arguments to be passed to MSBuild
|
Arguments to be passed to MSBuild
|
||||||
@@ -33,17 +33,18 @@ Arguments to be passed to MSBuild
|
|||||||
This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be.
|
This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be.
|
||||||
When the lockfile is not present, KoreBuild will create one using latest available version from $Channel.
|
When the lockfile is not present, KoreBuild will create one using latest available version from $Channel.
|
||||||
|
|
||||||
The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set
|
The $ConfigFile is expected to be an XML file. It is optional, and the configuration values in it are optional as well.
|
||||||
in the file are overridden by command line parameters.
|
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Example config file:
|
Example config file:
|
||||||
```json
|
```xml
|
||||||
{
|
<!-- version.xml -->
|
||||||
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json",
|
<Project>
|
||||||
"channel": "dev",
|
<PropertyGroup>
|
||||||
"toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools"
|
<KoreBuildChannel>dev</KoreBuildChannel>
|
||||||
}
|
<KoreBuildToolsSource>https://aspnetcore.blob.core.windows.net/buildtools</KoreBuildToolsSource>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
```
|
```
|
||||||
#>
|
#>
|
||||||
[CmdletBinding(PositionalBinding = $false)]
|
[CmdletBinding(PositionalBinding = $false)]
|
||||||
@@ -57,7 +58,7 @@ param(
|
|||||||
[string]$ToolsSource,
|
[string]$ToolsSource,
|
||||||
[Alias('u')]
|
[Alias('u')]
|
||||||
[switch]$Update,
|
[switch]$Update,
|
||||||
[string]$ConfigFile = $null,
|
[string]$ConfigFile = (Join-Path $PSScriptRoot 'version.xml'),
|
||||||
[Parameter(ValueFromRemainingArguments = $true)]
|
[Parameter(ValueFromRemainingArguments = $true)]
|
||||||
[string[]]$MSBuildArgs
|
[string[]]$MSBuildArgs
|
||||||
)
|
)
|
||||||
@@ -146,20 +147,10 @@ function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
|
|||||||
|
|
||||||
# Load configuration or set defaults
|
# Load configuration or set defaults
|
||||||
|
|
||||||
$Path = Resolve-Path $Path
|
|
||||||
if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' }
|
|
||||||
|
|
||||||
if (Test-Path $ConfigFile) {
|
if (Test-Path $ConfigFile) {
|
||||||
try {
|
[xml] $config = Get-Content $ConfigFile
|
||||||
$config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json
|
if (!($Channel)) { [string] $Channel = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildChannel' }
|
||||||
if ($config) {
|
if (!($ToolsSource)) { [string] $ToolsSource = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildToolsSource' }
|
||||||
if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel }
|
|
||||||
if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
Write-Warning "$ConfigFile could not be read. Its settings will be ignored."
|
|
||||||
Write-Warning $Error[0]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$DotNetHome) {
|
if (!$DotNetHome) {
|
||||||
|
|||||||
49
build.sh
49
build.sh
@@ -8,11 +8,10 @@ set -euo pipefail
|
|||||||
|
|
||||||
RESET="\033[0m"
|
RESET="\033[0m"
|
||||||
RED="\033[0;31m"
|
RED="\033[0;31m"
|
||||||
YELLOW="\033[0;33m"
|
|
||||||
MAGENTA="\033[0;95m"
|
MAGENTA="\033[0;95m"
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet"
|
[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet"
|
||||||
config_file="$DIR/korebuild.json"
|
config_file="$DIR/version.xml"
|
||||||
verbose=false
|
verbose=false
|
||||||
update=false
|
update=false
|
||||||
repo_path="$DIR"
|
repo_path="$DIR"
|
||||||
@@ -31,7 +30,7 @@ __usage() {
|
|||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " --verbose Show verbose output."
|
echo " --verbose Show verbose output."
|
||||||
echo " -c|--channel <CHANNEL> The channel of KoreBuild to download. Overrides the value from the config file.."
|
echo " -c|--channel <CHANNEL> The channel of KoreBuild to download. Overrides the value from the config file.."
|
||||||
echo " --config-file <FILE> The path to the configuration file that stores values. Defaults to korebuild.json."
|
echo " --config-file <FILE> TThe path to the configuration file that stores values. Defaults to version.xml."
|
||||||
echo " -d|--dotnet-home <DIR> The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet."
|
echo " -d|--dotnet-home <DIR> The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet."
|
||||||
echo " --path <PATH> The directory to build. Defaults to the directory containing the script."
|
echo " --path <PATH> The directory to build. Defaults to the directory containing the script."
|
||||||
echo " -s|--tools-source <URL> The base url where build tools can be downloaded. Overrides the value from the config file."
|
echo " -s|--tools-source <URL> The base url where build tools can be downloaded. Overrides the value from the config file."
|
||||||
@@ -83,11 +82,7 @@ get_korebuild() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__error() {
|
__error() {
|
||||||
echo -e "${RED}error: $*${RESET}" 1>&2
|
echo -e "${RED}$*${RESET}" 1>&2
|
||||||
}
|
|
||||||
|
|
||||||
__warn() {
|
|
||||||
echo -e "${YELLOW}warning: $*${RESET}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__machine_has() {
|
__machine_has() {
|
||||||
@@ -104,11 +99,9 @@ __get_remote_file() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local failed=false
|
failed=false
|
||||||
if __machine_has wget; then
|
if __machine_has wget; then
|
||||||
wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true
|
wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true
|
||||||
else
|
|
||||||
failed=true
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$failed" = true ] && __machine_has curl; then
|
if [ "$failed" = true ] && __machine_has curl; then
|
||||||
@@ -122,6 +115,8 @@ __get_remote_file() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__read_dom () { local IFS=\> ; read -r -d \< ENTITY CONTENT ;}
|
||||||
|
|
||||||
#
|
#
|
||||||
# main
|
# main
|
||||||
#
|
#
|
||||||
@@ -141,10 +136,6 @@ while [[ $# -gt 0 ]]; do
|
|||||||
shift
|
shift
|
||||||
config_file="${1:-}"
|
config_file="${1:-}"
|
||||||
[ -z "$config_file" ] && __usage
|
[ -z "$config_file" ] && __usage
|
||||||
if [ ! -f "$config_file" ]; then
|
|
||||||
__error "Invalid value for --config-file. $config_file does not exist."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
-d|--dotnet-home|-DotNetHome)
|
-d|--dotnet-home|-DotNetHome)
|
||||||
shift
|
shift
|
||||||
@@ -188,28 +179,14 @@ if ! __machine_has curl && ! __machine_has wget; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json"
|
|
||||||
if [ -f "$config_file" ]; then
|
if [ -f "$config_file" ]; then
|
||||||
if __machine_has jq ; then
|
comment=false
|
||||||
if jq '.' "$config_file" >/dev/null ; then
|
while __read_dom; do
|
||||||
config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")"
|
if [ "$comment" = true ]; then [[ $CONTENT == *'-->'* ]] && comment=false ; continue; fi
|
||||||
config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")"
|
if [[ $ENTITY == '!--'* ]]; then comment=true; continue; fi
|
||||||
else
|
if [ -z "$channel" ] && [[ $ENTITY == "KoreBuildChannel" ]]; then channel=$CONTENT; fi
|
||||||
__warn "$config_file is invalid JSON. Its settings will be ignored."
|
if [ -z "$tools_source" ] && [[ $ENTITY == "KoreBuildToolsSource" ]]; then tools_source=$CONTENT; fi
|
||||||
fi
|
done < "$config_file"
|
||||||
elif __machine_has python ; then
|
|
||||||
if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then
|
|
||||||
config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")"
|
|
||||||
config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")"
|
|
||||||
else
|
|
||||||
__warn "$config_file is invalid JSON. Its settings will be ignored."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
__warn 'Missing required command: jq or pyton. Could not parse the JSON file. Its settings will be ignored.'
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ ! -z "${config_channel:-}" ] && channel="$config_channel"
|
|
||||||
[ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ -z "$channel" ] && channel='dev'
|
[ -z "$channel" ] && channel='dev'
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
|
<Import Project="dependencies.props" />
|
||||||
|
<Import Project="..\version.xml" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Product>Microsoft ASP.NET Core</Product>
|
<Product>Microsoft ASP.NET Core</Product>
|
||||||
@@ -7,11 +9,15 @@
|
|||||||
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)Key.snk</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)Key.snk</AssemblyOriginatorKeyFile>
|
||||||
<SignAssembly>true</SignAssembly>
|
<SignAssembly>true</SignAssembly>
|
||||||
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
|
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
|
||||||
|
<VersionSuffix Condition="'$(VersionSuffix)'!='' AND '$(BuildNumber)' != ''">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Internal.AspNetCore.Sdk" Version="$(InternalAspNetCoreSdkPackageVersion)" PrivateAssets="All" />
|
<PackageReference Include="Internal.AspNetCore.Sdk" Version="$(InternalAspNetCoreSdkVersion)" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFrameworkIdentifier)'=='.NETFramework'">
|
||||||
|
<PackageReference Include="NETStandard.Library" Version="$(NETStandardImplicitPackageVersion)" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,23 +1,11 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<InternalAspNetCoreSdkPackageVersion>2.0.2-rc1-15526</InternalAspNetCoreSdkPackageVersion>
|
<AspNetCoreVersion>2.1.0-*</AspNetCoreVersion>
|
||||||
<MicrosoftAspNetCoreDiagnosticsPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreDiagnosticsPackageVersion>
|
<InternalAspNetCoreSdkVersion>2.1.1-*</InternalAspNetCoreSdkVersion>
|
||||||
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
<JsonNetVersion>10.0.1</JsonNetVersion>
|
||||||
<MicrosoftAspNetCoreHostingPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreHostingPackageVersion>
|
<NETStandardImplicitPackageVersion>2.0.0-*</NETStandardImplicitPackageVersion>
|
||||||
<MicrosoftAspNetCoreMvcPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreMvcPackageVersion>
|
<NETStandardLibraryNETFrameworkVersion>2.0.0-*</NETStandardLibraryNETFrameworkVersion>
|
||||||
<MicrosoftAspNetCoreMvcTagHelpersPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreMvcTagHelpersPackageVersion>
|
<RuntimeFrameworkVersion Condition="'$(TargetFramework)'=='netcoreapp2.0'">2.0.0-*</RuntimeFrameworkVersion>
|
||||||
<MicrosoftAspNetCoreMvcViewFeaturesPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreMvcViewFeaturesPackageVersion>
|
<ThreadingDataflowVersion>4.8.0-*</ThreadingDataflowVersion>
|
||||||
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
|
|
||||||
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreServerKestrelPackageVersion>
|
|
||||||
<MicrosoftAspNetCoreStaticFilesPackageVersion>2.0.1-rtm-105</MicrosoftAspNetCoreStaticFilesPackageVersion>
|
|
||||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.0.0</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
|
||||||
<MicrosoftExtensionsLoggingConsolePackageVersion>2.0.0</MicrosoftExtensionsLoggingConsolePackageVersion>
|
|
||||||
<MicrosoftExtensionsLoggingDebugPackageVersion>2.0.0</MicrosoftExtensionsLoggingDebugPackageVersion>
|
|
||||||
<NewtonsoftJsonRuntimePackageVersion>10.0.1</NewtonsoftJsonRuntimePackageVersion>
|
|
||||||
<MicrosoftNETCoreApp20PackageVersion>2.0.5</MicrosoftNETCoreApp20PackageVersion>
|
|
||||||
<NETStandardLibrary20PackageVersion>2.0.1</NETStandardLibrary20PackageVersion>
|
|
||||||
<SystemThreadingTasksDataflowPackageVersion>4.8.0</SystemThreadingTasksDataflowPackageVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
<Project>
|
|
||||||
<Import Project="$(DotNetRestoreSourcePropsPath)" Condition="'$(DotNetRestoreSourcePropsPath)' != ''"/>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<RestoreSources>$(DotNetRestoreSources)</RestoreSources>
|
|
||||||
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true' AND '$(AspNetUniverseBuildOffline)' != 'true' ">
|
|
||||||
$(RestoreSources);
|
|
||||||
https://dotnet.myget.org/F/aspnet-2-0-2-october2017-patch/api/v3/index.json;
|
|
||||||
https://dotnet.myget.org/F/aspnetcore-master/api/v3/index.json;
|
|
||||||
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
|
|
||||||
</RestoreSources>
|
|
||||||
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'">
|
|
||||||
$(RestoreSources);
|
|
||||||
https://api.nuget.org/v3/index.json;
|
|
||||||
</RestoreSources>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
version:2.0.5-rtm-10016
|
|
||||||
commithash:02bda79ac9c564229da734a836f258d6c1321eb7
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.0/tools/korebuild.schema.json",
|
|
||||||
"channel": "release/2.0"
|
|
||||||
}
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionPackageVersion)" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(AspNetCoreVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<Import Project="..\..\..\build\common.props" />
|
<Import Project="..\..\..\build\common.props" />
|
||||||
|
|
||||||
@@ -13,13 +13,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(MicrosoftAspNetCoreDiagnosticsPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(MicrosoftAspNetCoreMvcPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftExtensionsLoggingDebugPackageVersion)" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(AspNetCoreVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
|
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<Import Project="..\..\..\build\common.props" />
|
<Import Project="..\..\..\build\common.props" />
|
||||||
|
|
||||||
@@ -13,13 +13,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(MicrosoftAspNetCoreDiagnosticsPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(MicrosoftAspNetCoreMvcPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftExtensionsLoggingDebugPackageVersion)" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(AspNetCoreVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
|
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Microsoft.AspNetCore.NodeServices\Microsoft.AspNetCore.NodeServices.csproj" />
|
<ProjectReference Include="..\Microsoft.AspNetCore.NodeServices\Microsoft.AspNetCore.NodeServices.csproj" />
|
||||||
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="$(SystemThreadingTasksDataflowPackageVersion)" />
|
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="$(ThreadingDataflowVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
|
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
options.DebuggingPort)
|
options.DebuggingPort)
|
||||||
{
|
{
|
||||||
_client = new HttpClient();
|
_client = new HttpClient();
|
||||||
|
_client.Timeout = TimeSpan.FromMilliseconds(options.InvocationTimeoutMilliseconds + 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string MakeCommandLineOptions(int port)
|
private static string MakeCommandLineOptions(int port)
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="$(MicrosoftAspNetCoreHostingAbstractionsPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonRuntimePackageVersion)" />
|
<PackageReference Include="Newtonsoft.Json" Version="$(JsonNetVersion)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
|
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
<None Remove="node_modules\**\*" />
|
<None Remove="node_modules\**\*" />
|
||||||
<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.TagHelpers" Version="$(MicrosoftAspNetCoreMvcTagHelpersPackageVersion)" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.TagHelpers" Version="$(AspNetCoreVersion)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="$(MicrosoftAspNetCoreMvcViewFeaturesPackageVersion)" />
|
<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' ">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Threading;
|
|||||||
using Microsoft.AspNetCore.NodeServices;
|
using Microsoft.AspNetCore.NodeServices;
|
||||||
using Microsoft.AspNetCore.SpaServices.Webpack;
|
using Microsoft.AspNetCore.SpaServices.Webpack;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Builder
|
namespace Microsoft.AspNetCore.Builder
|
||||||
{
|
{
|
||||||
@@ -87,7 +88,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||||||
};
|
};
|
||||||
var devServerInfo =
|
var devServerInfo =
|
||||||
nodeServices.InvokeExportAsync<WebpackDevServerInfo>(nodeScript.FileName, "createWebpackDevServer",
|
nodeServices.InvokeExportAsync<WebpackDevServerInfo>(nodeScript.FileName, "createWebpackDevServer",
|
||||||
JsonConvert.SerializeObject(devServerOptions)).Result;
|
JsonConvert.SerializeObject(devServerOptions, new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() })).Result;
|
||||||
|
|
||||||
// If we're talking to an older version of aspnet-webpack, it will return only a single PublicPath,
|
// If we're talking to an older version of aspnet-webpack, it will return only a single PublicPath,
|
||||||
// not an array of PublicPaths. Handle that scenario.
|
// not an array of PublicPaths. Handle that scenario.
|
||||||
|
|||||||
5
src/Microsoft.AspNetCore.SpaServices/npm/aspnet-angular/.gitignore
vendored
Normal file
5
src/Microsoft.AspNetCore.SpaServices/npm/aspnet-angular/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/node_modules/
|
||||||
|
**/*.js
|
||||||
|
**/*.d.ts
|
||||||
|
**/*.metadata.json
|
||||||
|
/compiled
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
!/*.js
|
||||||
|
!/*.d.ts
|
||||||
|
/compiled
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||||
|
these files except in compliance with the License. You may obtain a copy of the
|
||||||
|
License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations under the License.
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "aspnet-angular",
|
||||||
|
"version": "0.1.1",
|
||||||
|
"description": "Helpers for using Angular in ASP.NET Core projects",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"prepublish": "rimraf *.d.ts && ngc && echo 'Finished building NPM package \"aspnet-angular\"'",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/aspnet/JavaScriptServices.git"
|
||||||
|
},
|
||||||
|
"author": "Microsoft",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/aspnet/JavaScriptServices/issues"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@angular/common": "^4.3.2",
|
||||||
|
"@angular/compiler": "^4.3.2",
|
||||||
|
"@angular/compiler-cli": "^4.3.2",
|
||||||
|
"@angular/core": "^4.3.2",
|
||||||
|
"@angular/http": "^4.3.2",
|
||||||
|
"@angular/platform-browser": "^4.3.2",
|
||||||
|
"rimraf": "^2.6.1",
|
||||||
|
"rxjs": "^5.4.2",
|
||||||
|
"zone.js": "^0.8.16"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/core": "^4.2.5 || ^5.0.0-beta"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
import { Provider, NgModule, Inject } from '@angular/core';
|
||||||
|
import { Headers, Http, ResponseOptions, RequestOptionsArgs, Response } from '@angular/http';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import 'rxjs/add/observable/of';
|
||||||
|
import 'rxjs/add/operator/map';
|
||||||
|
const globalSerializedStateKey = 'HTTP_STATE_TRANSFER';
|
||||||
|
const backingStoreDIToken = 'HTTP_STATE_BACKING_STORE';
|
||||||
|
|
||||||
|
export interface CacheOptions {
|
||||||
|
permanent: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CachedHttpResponse {
|
||||||
|
headers: { [name: string]: any } | null;
|
||||||
|
status: number;
|
||||||
|
statusText: string | null;
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BackingStore = { [key: string]: CachedHttpResponse };
|
||||||
|
|
||||||
|
export class HttpWithStateTransfer {
|
||||||
|
private backingStore: BackingStore;
|
||||||
|
private http: Http;
|
||||||
|
|
||||||
|
constructor(@Inject(Http) http: Http, @Inject(backingStoreDIToken) backingStore: BackingStore) {
|
||||||
|
this.http = http;
|
||||||
|
this.backingStore = backingStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public stateForTransfer(): any {
|
||||||
|
return { [globalSerializedStateKey]: this.backingStore };
|
||||||
|
}
|
||||||
|
|
||||||
|
public get(url: string, options?: CacheOptions, requestOptions?: RequestOptionsArgs): Observable<Response> {
|
||||||
|
return this.getCachedResponse(/* cacheKey */ url, () => this.http.get(url, requestOptions), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCachedResponse(cacheKey: string, provider: () => Observable<Response>, options?: CacheOptions): Observable<Response> {
|
||||||
|
// By default, the cache is only used for the *first* client-side read. So, we're only performing
|
||||||
|
// a one-time transfer of server-side response to the client. If you want to keep and reuse cached
|
||||||
|
// responses continually during server-side and client-side execution, set 'permanent' to 'true.
|
||||||
|
const isClient = typeof window !== 'undefined';
|
||||||
|
const isPermanent = options && options.permanent;
|
||||||
|
|
||||||
|
const allowReadFromCache = isClient || isPermanent;
|
||||||
|
if (allowReadFromCache && this.backingStore.hasOwnProperty(cacheKey)) {
|
||||||
|
const cachedValue = this.backingStore[cacheKey];
|
||||||
|
if (!isPermanent) {
|
||||||
|
delete this.backingStore[cacheKey];
|
||||||
|
}
|
||||||
|
return Observable.of(new Response(new ResponseOptions({
|
||||||
|
body: cachedValue.text,
|
||||||
|
headers: new Headers(cachedValue.headers),
|
||||||
|
status: cachedValue.status,
|
||||||
|
url: cachedValue.url
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
return provider()
|
||||||
|
.map(response => {
|
||||||
|
const allowWriteToCache = !isClient || isPermanent;
|
||||||
|
if (allowWriteToCache) {
|
||||||
|
this.backingStore[cacheKey] = {
|
||||||
|
headers: response.headers ? response.headers.toJSON() : null,
|
||||||
|
status: response.status,
|
||||||
|
statusText: response.statusText,
|
||||||
|
text: response.text(),
|
||||||
|
url: response.url
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function defaultBackingStoreFactory() {
|
||||||
|
const transferredData = typeof window !== 'undefined' ? (window as any)[globalSerializedStateKey] : null;
|
||||||
|
return transferredData || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
providers: [
|
||||||
|
// The backing store is a separate DI service so you could override exactly how it gets
|
||||||
|
// transferred from server to client
|
||||||
|
{ provide: backingStoreDIToken, useFactory: defaultBackingStoreFactory },
|
||||||
|
|
||||||
|
{ provide: HttpWithStateTransfer, useClass: HttpWithStateTransfer },
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class HttpWithStateTransferModule {
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './HttpWithStateTransfer';
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": ".",
|
||||||
|
"lib": ["es2015", "dom"]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/index.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
],
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"genDir": "compiled"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "aspnet-prerendering",
|
"name": "aspnet-prerendering",
|
||||||
"version": "2.0.6",
|
"version": "3.0.1",
|
||||||
"description": "Helpers for server-side rendering of JavaScript applications in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
|
"description": "Helpers for server-side rendering of JavaScript applications in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"url": "https://github.com/aspnet/JavaScriptServices.git"
|
"url": "https://github.com/aspnet/JavaScriptServices.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"domain-task": "^2.0.2"
|
"domain-task": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^6.0.42",
|
"@types/node": "^6.0.42",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export function createServerRenderer(bootFunc: BootFunc): RenderToStringFunc {
|
|||||||
domainTasks: domainTaskCompletionPromise,
|
domainTasks: domainTaskCompletionPromise,
|
||||||
data: customDataParameter
|
data: customDataParameter
|
||||||
};
|
};
|
||||||
|
const absoluteBaseUrl = params.origin + params.baseUrl; // Should be same value as page's <base href>
|
||||||
|
|
||||||
// Open a new domain that can track all the async tasks involved in the app's execution
|
// Open a new domain that can track all the async tasks involved in the app's execution
|
||||||
domainTaskRun(/* code to run */ () => {
|
domainTaskRun(/* code to run */ () => {
|
||||||
@@ -35,7 +36,7 @@ export function createServerRenderer(bootFunc: BootFunc): RenderToStringFunc {
|
|||||||
bindPromiseContinuationsToDomain(domainTaskCompletionPromise, domain['active']);
|
bindPromiseContinuationsToDomain(domainTaskCompletionPromise, domain['active']);
|
||||||
|
|
||||||
// Make the base URL available to the 'domain-tasks/fetch' helper within this execution context
|
// Make the base URL available to the 'domain-tasks/fetch' helper within this execution context
|
||||||
domainTaskBaseUrl(absoluteRequestUrl);
|
domainTaskBaseUrl(absoluteBaseUrl);
|
||||||
|
|
||||||
// Begin rendering, and apply a timeout
|
// Begin rendering, and apply a timeout
|
||||||
const bootFuncPromise = bootFunc(params);
|
const bootFuncPromise = bootFunc(params);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "aspnet-webpack-react",
|
"name": "aspnet-webpack-react",
|
||||||
"version": "3.0.0-beta.1",
|
"version": "3.0.0",
|
||||||
"description": "Helpers for using Webpack with React in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
|
"description": "Helpers for using Webpack with React in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
1700
src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package-lock.json
generated
Normal file
1700
src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "aspnet-webpack",
|
"name": "aspnet-webpack",
|
||||||
"version": "1.0.29",
|
"version": "2.0.1",
|
||||||
"description": "Helpers for using Webpack in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
|
"description": "Helpers for using Webpack in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import * as fs from 'fs';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as querystring from 'querystring';
|
import * as querystring from 'querystring';
|
||||||
import { requireNewCopy } from './RequireNewCopy';
|
import { requireNewCopy } from './RequireNewCopy';
|
||||||
|
import { hasSufficientPermissions } from './WebpackTestPermissions';
|
||||||
|
|
||||||
export type CreateDevServerResult = {
|
export type CreateDevServerResult = {
|
||||||
Port: number,
|
Port: number,
|
||||||
PublicPaths: string[],
|
PublicPaths: string[]
|
||||||
PublicPath: string // For backward compatibility with older verions of Microsoft.AspNetCore.SpaServices. Will be removed soon.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface CreateDevServerCallback {
|
export interface CreateDevServerCallback {
|
||||||
@@ -108,7 +108,7 @@ function attachWebpackDevMiddleware(app: any, webpackConfig: webpack.Configurati
|
|||||||
const compiler = webpack(webpackConfig);
|
const compiler = webpack(webpackConfig);
|
||||||
app.use(require('webpack-dev-middleware')(compiler, {
|
app.use(require('webpack-dev-middleware')(compiler, {
|
||||||
noInfo: true,
|
noInfo: true,
|
||||||
publicPath: webpackConfig.output.publicPath,
|
publicPath: ensureLeadingSlash(webpackConfig.output.publicPath),
|
||||||
watchOptions: webpackConfig.watchOptions
|
watchOptions: webpackConfig.watchOptions
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -195,6 +195,14 @@ function copyRecursiveToRealFsSync(from: typeof fs, rootDir: string, exclude: Re
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureLeadingSlash(value: string) {
|
||||||
|
if (value !== null && value.substring(0, 1) !== '/') {
|
||||||
|
value = '/' + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
function pathJoinSafe(rootPath: string, filePath: string) {
|
function pathJoinSafe(rootPath: string, filePath: string) {
|
||||||
// On Windows, MemoryFileSystem's readdirSync output produces directory entries like 'C:'
|
// On Windows, MemoryFileSystem's readdirSync output produces directory entries like 'C:'
|
||||||
// which then trigger errors if you call statSync for them. Avoid this by detecting drive
|
// which then trigger errors if you call statSync for them. Avoid this by detecting drive
|
||||||
@@ -216,6 +224,16 @@ function beginWebpackWatcher(webpackConfig: webpack.Configuration) {
|
|||||||
export function createWebpackDevServer(callback: CreateDevServerCallback, optionsJson: string) {
|
export function createWebpackDevServer(callback: CreateDevServerCallback, optionsJson: string) {
|
||||||
const options: CreateDevServerOptions = JSON.parse(optionsJson);
|
const options: CreateDevServerOptions = JSON.parse(optionsJson);
|
||||||
|
|
||||||
|
// See the large comment in WebpackTestPermissions.ts for details about this
|
||||||
|
if (!hasSufficientPermissions()) {
|
||||||
|
console.log('WARNING: Webpack dev middleware is not enabled because the server process does not have sufficient permissions. You should either remove the UseWebpackDevMiddleware call from your code, or to make it work, give your server process user account permission to write to your application directory and to read all ancestor-level directories.');
|
||||||
|
callback(null, {
|
||||||
|
Port: 0,
|
||||||
|
PublicPaths: []
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Read the webpack config's export, and normalize it into the more general 'array of configs' format
|
// Read the webpack config's export, and normalize it into the more general 'array of configs' format
|
||||||
let webpackConfigExport: WebpackConfigFileExport = requireNewCopy(options.webpackConfigPath);
|
let webpackConfigExport: WebpackConfigFileExport = requireNewCopy(options.webpackConfigPath);
|
||||||
if (webpackConfigExport instanceof Function) {
|
if (webpackConfigExport instanceof Function) {
|
||||||
@@ -257,22 +275,32 @@ export function createWebpackDevServer(callback: CreateDevServerCallback, option
|
|||||||
if (!publicPath) {
|
if (!publicPath) {
|
||||||
throw new Error('To use the Webpack dev server, you must specify a value for \'publicPath\' on the \'output\' section of your webpack config (for any configuration that targets browsers)');
|
throw new Error('To use the Webpack dev server, you must specify a value for \'publicPath\' on the \'output\' section of your webpack config (for any configuration that targets browsers)');
|
||||||
}
|
}
|
||||||
normalizedPublicPaths.push(removeTrailingSlash(publicPath));
|
const publicPathNoTrailingSlash = removeTrailingSlash(publicPath);
|
||||||
|
normalizedPublicPaths.push(publicPathNoTrailingSlash);
|
||||||
|
|
||||||
// Newer versions of Microsoft.AspNetCore.SpaServices will explicitly pass an HMR endpoint URL
|
// This is the URL the client will connect to, except that since it's a relative URL
|
||||||
// (because it's relative to the app's URL space root, which the client doesn't otherwise know).
|
// (no leading slash), Webpack will resolve it against the runtime <base href> URL
|
||||||
// For back-compatibility, fall back on connecting directly to the underlying HMR server (though
|
// plus it also adds the publicPath
|
||||||
// that won't work if the app is hosted on HTTPS because of the mixed-content rule, and we can't
|
const hmrClientEndpoint = removeLeadingSlash(options.hotModuleReplacementEndpointUrl);
|
||||||
// run the HMR server itself on HTTPS because in general it has no valid cert).
|
|
||||||
const hmrClientEndpoint = options.hotModuleReplacementEndpointUrl // The URL that we'll proxy (e.g., /__asp_webpack_hmr)
|
// This is the URL inside the Webpack middleware Node server that we'll proxy to.
|
||||||
|| `http://localhost:${listener.address().port}/__webpack_hmr`; // Fall back on absolute URL to bypass proxying
|
// We have to prefix with the public path because Webpack will add the publicPath
|
||||||
const hmrServerEndpoint = options.hotModuleReplacementEndpointUrl
|
// when it resolves hmrClientEndpoint as a relative URL.
|
||||||
|| '/__webpack_hmr'; // URL is relative to webpack dev server root
|
const hmrServerEndpoint = ensureLeadingSlash(publicPathNoTrailingSlash + options.hotModuleReplacementEndpointUrl);
|
||||||
|
|
||||||
// We always overwrite the 'path' option as it needs to match what the .NET side is expecting
|
// We always overwrite the 'path' option as it needs to match what the .NET side is expecting
|
||||||
const hmrClientOptions = options.suppliedOptions.HotModuleReplacementClientOptions || <StringMap<string>>{};
|
const hmrClientOptions = options.suppliedOptions.HotModuleReplacementClientOptions || <StringMap<string>>{};
|
||||||
hmrClientOptions['path'] = hmrClientEndpoint;
|
hmrClientOptions['path'] = hmrClientEndpoint;
|
||||||
|
|
||||||
|
const dynamicPublicPathKey = 'dynamicPublicPath';
|
||||||
|
if (!(dynamicPublicPathKey in hmrClientOptions)) {
|
||||||
|
// dynamicPublicPath default to true, so we can work with nonempty pathbases (virtual directories)
|
||||||
|
hmrClientOptions[dynamicPublicPathKey] = true;
|
||||||
|
} else {
|
||||||
|
// ... but you can set it to any other value explicitly if you want (e.g., false)
|
||||||
|
hmrClientOptions[dynamicPublicPathKey] = JSON.parse(hmrClientOptions[dynamicPublicPathKey]);
|
||||||
|
}
|
||||||
|
|
||||||
attachWebpackDevMiddleware(app, webpackConfig, enableHotModuleReplacement, enableReactHotModuleReplacement, hmrClientOptions, hmrServerEndpoint);
|
attachWebpackDevMiddleware(app, webpackConfig, enableHotModuleReplacement, enableReactHotModuleReplacement, hmrClientOptions, hmrServerEndpoint);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -280,11 +308,7 @@ export function createWebpackDevServer(callback: CreateDevServerCallback, option
|
|||||||
// Tell the ASP.NET app what addresses we're listening on, so that it can proxy requests here
|
// Tell the ASP.NET app what addresses we're listening on, so that it can proxy requests here
|
||||||
callback(null, {
|
callback(null, {
|
||||||
Port: listener.address().port,
|
Port: listener.address().port,
|
||||||
PublicPaths: normalizedPublicPaths,
|
PublicPaths: normalizedPublicPaths
|
||||||
|
|
||||||
// For back-compatibility with older versions of Microsoft.AspNetCore.SpaServices, in the case where
|
|
||||||
// you have exactly one webpackConfigArray entry. This will be removed soon.
|
|
||||||
PublicPath: normalizedPublicPaths[0]
|
|
||||||
});
|
});
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
callback(ex.stack, null);
|
callback(ex.stack, null);
|
||||||
@@ -292,6 +316,14 @@ export function createWebpackDevServer(callback: CreateDevServerCallback, option
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeLeadingSlash(str: string) {
|
||||||
|
if (str.indexOf('/') === 0) {
|
||||||
|
str = str.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
function removeTrailingSlash(str: string) {
|
function removeTrailingSlash(str: string) {
|
||||||
if (str.lastIndexOf('/') === str.length - 1) {
|
if (str.lastIndexOf('/') === str.length - 1) {
|
||||||
str = str.substring(0, str.length - 1);
|
str = str.substring(0, str.length - 1);
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
const isWindows = /^win/.test(process.platform);
|
||||||
|
|
||||||
|
// On Windows, Node (still as of v8.1.3) has an issue whereby, when locating JavaScript modules
|
||||||
|
// on disk, it walks up the directory hierarchy to the disk root, testing whether each directory
|
||||||
|
// is a symlink or not. This fails with an exception if the process doesn't have permission to
|
||||||
|
// read those directories. This is a problem when hosting in full IIS, because in typical cases
|
||||||
|
// the process does not have read permission for higher-level directories.
|
||||||
|
//
|
||||||
|
// NodeServices itself works around this by injecting a patched version of Node's 'lstat' API that
|
||||||
|
// suppresses these irrelevant errors during module loads. This covers most scenarios, but isn't
|
||||||
|
// enough to make Webpack dev middleware work, because typical Webpack configs use loaders such as
|
||||||
|
// 'awesome-typescript-loader', which works by forking a child process to do some of its work. The
|
||||||
|
// child process does not get the patched 'lstat', and hence fails. It's an especially bad failure,
|
||||||
|
// because the Webpack compiler doesn't even surface the exception - it just never completes the
|
||||||
|
// compilation process, causing the application to hang indefinitely.
|
||||||
|
//
|
||||||
|
// Additionally, Webpack dev middleware will want to write its output to disk, which is also going
|
||||||
|
// to fail in a typical IIS process, because you won't have 'write' permission to the app dir by
|
||||||
|
// default. We have to actually write the build output to disk (and not purely keep it in the in-
|
||||||
|
// memory file system) because the server-side prerendering Node instance is a separate process
|
||||||
|
// that only knows about code changes when it sees the compiled files on disk change.
|
||||||
|
//
|
||||||
|
// In the future, we'll hopefully get Node to fix its underlying issue, and figure out whether VS
|
||||||
|
// could give 'write' access to the app dir when launching sites in IIS. But until then, disable
|
||||||
|
// Webpack dev middleware if we detect the server process doesn't have the necessary permissions.
|
||||||
|
|
||||||
|
export function hasSufficientPermissions() {
|
||||||
|
if (isWindows) {
|
||||||
|
return canReadDirectoryAndAllAncestors(process.cwd());
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function canReadDirectoryAndAllAncestors(dir: string): boolean {
|
||||||
|
if (!canReadDirectory(dir)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentDir = path.resolve(dir, '..');
|
||||||
|
if (parentDir === dir) {
|
||||||
|
// There are no more parent directories - we've reached the disk root
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return canReadDirectoryAndAllAncestors(parentDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function canReadDirectory(dir: string): boolean {
|
||||||
|
try {
|
||||||
|
fs.statSync(dir);
|
||||||
|
return true;
|
||||||
|
} catch(ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,17 +9,17 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0-rtm-26190" />
|
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import { AppComponent } from './components/app/app.component';
|
|||||||
AppModuleShared
|
AppModuleShared
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: 'ORIGIN_URL', useFactory: getOriginUrl }
|
{ provide: 'BASE_URL', useFactory: getBaseUrl }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOriginUrl() {
|
export function getBaseUrl() {
|
||||||
return location.origin;
|
return document.getElementsByTagName('base')[0].href;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { HttpModule } from '@angular/http';
|
import { HttpModule } from '@angular/http';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { HttpWithStateTransferModule } from 'aspnet-angular';
|
||||||
|
|
||||||
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';
|
||||||
@@ -21,6 +22,7 @@ import { CounterComponent } from './components/counter/counter.component';
|
|||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
HttpModule,
|
HttpModule,
|
||||||
|
HttpWithStateTransferModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
RouterModule.forRoot([
|
RouterModule.forRoot([
|
||||||
{ path: '', redirectTo: 'home', pathMatch: 'full' },
|
{ path: '', redirectTo: 'home', pathMatch: 'full' },
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, Inject } from '@angular/core';
|
import { Component, Inject } from '@angular/core';
|
||||||
import { Http } from '@angular/http';
|
import { HttpWithStateTransfer } from 'aspnet-angular';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'fetchdata',
|
selector: 'fetchdata',
|
||||||
@@ -8,8 +8,8 @@ import { Http } from '@angular/http';
|
|||||||
export class FetchDataComponent {
|
export class FetchDataComponent {
|
||||||
public forecasts: WeatherForecast[];
|
public forecasts: WeatherForecast[];
|
||||||
|
|
||||||
constructor(http: Http, @Inject('ORIGIN_URL') originUrl: string) {
|
constructor(http: HttpWithStateTransfer, @Inject('BASE_URL') baseUrl: string) {
|
||||||
http.get(originUrl + '/api/SampleData/WeatherForecasts').subscribe(result => {
|
http.get(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
|
||||||
this.forecasts = result.json() as WeatherForecast[];
|
this.forecasts = result.json() as WeatherForecast[];
|
||||||
}, error => console.error(error));
|
}, error => console.error(error));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,6 @@
|
|||||||
<li><strong>Client-side navigation</strong>. For example, click <em>Counter</em> then <em>Back</em> to return here.</li>
|
<li><strong>Client-side navigation</strong>. For example, click <em>Counter</em> then <em>Back</em> to return here.</li>
|
||||||
<li><strong>Server-side prerendering</strong>. For faster initial loading and improved SEO, your Angular app is prerendered on the server. The resulting HTML is then transferred to the browser where a client-side copy of the app takes over.</li>
|
<li><strong>Server-side prerendering</strong>. For faster initial loading and improved SEO, your Angular app is prerendered on the server. The resulting HTML is then transferred to the browser where a client-side copy of the app takes over.</li>
|
||||||
<li><strong>Webpack dev middleware</strong>. In development mode, there's no need to run the <code>webpack</code> build tool. Your client-side resources are dynamically built on demand. Updates are available as soon as you modify any file.</li>
|
<li><strong>Webpack dev middleware</strong>. In development mode, there's no need to run the <code>webpack</code> build tool. Your client-side resources are dynamically built on demand. Updates are available as soon as you modify any file.</li>
|
||||||
<li><strong>Hot module replacement</strong>. In development mode, you don't even need to reload the page after making most changes. Within seconds of saving changes to files, your Angular app will be rebuilt and a new instance injected is into the page.</li>
|
<li><strong>Hot module replacement</strong>. In development mode, you don't even need to reload the page after making most changes. Within seconds of saving changes to files, your Angular app will be rebuilt and a new instance injected into the page.</li>
|
||||||
<li><strong>Efficient production builds</strong>. In production mode, development-time features are disabled, and the <code>webpack</code> build tool produces minified static CSS and JavaScript files.</li>
|
<li><strong>Efficient production builds</strong>. In production mode, development-time features are disabled, and the <code>webpack</code> build tool produces minified static CSS and JavaScript files.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ 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.browser';
|
import { AppModule } from './app/app.module.browser';
|
||||||
|
|
||||||
if (module['hot']) {
|
if (module.hot) {
|
||||||
module['hot'].accept();
|
module.hot.accept();
|
||||||
module['hot'].dispose(() => {
|
module.hot.dispose(() => {
|
||||||
// Before restarting the app, we create a new root element and dispose the old one
|
// Before restarting the app, we create a new root element and dispose the old one
|
||||||
const oldRootElem = document.querySelector('app');
|
const oldRootElem = document.querySelector('app');
|
||||||
const newRootElem = document.createElement('app');
|
const newRootElem = document.createElement('app');
|
||||||
oldRootElem.parentNode.insertBefore(newRootElem, oldRootElem);
|
oldRootElem!.parentNode!.insertBefore(newRootElem, oldRootElem);
|
||||||
modulePromise.then(appModule => appModule.destroy());
|
modulePromise.then(appModule => appModule.destroy());
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,32 +1,37 @@
|
|||||||
import 'reflect-metadata';
|
import 'reflect-metadata';
|
||||||
import 'zone.js';
|
import 'zone.js';
|
||||||
import 'rxjs/add/operator/first';
|
import 'rxjs/add/operator/first';
|
||||||
|
import { APP_BASE_HREF } from '@angular/common';
|
||||||
import { enableProdMode, ApplicationRef, NgZone, ValueProvider } from '@angular/core';
|
import { enableProdMode, ApplicationRef, NgZone, ValueProvider } from '@angular/core';
|
||||||
import { platformDynamicServer, PlatformState, INITIAL_CONFIG } from '@angular/platform-server';
|
import { platformDynamicServer, PlatformState, INITIAL_CONFIG } from '@angular/platform-server';
|
||||||
import { createServerRenderer, RenderResult } from 'aspnet-prerendering';
|
import { createServerRenderer, RenderResult } from 'aspnet-prerendering';
|
||||||
import { AppModule } from './app/app.module.server';
|
import { AppModule } from './app/app.module.server';
|
||||||
|
import { HttpWithStateTransfer } from 'aspnet-angular';
|
||||||
|
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
|
|
||||||
export default createServerRenderer(params => {
|
export default createServerRenderer(params => {
|
||||||
const providers = [
|
const providers = [
|
||||||
{ provide: INITIAL_CONFIG, useValue: { document: '<app></app>', url: params.url } },
|
{ provide: INITIAL_CONFIG, useValue: { document: '<app></app>', url: params.url } },
|
||||||
{ provide: 'ORIGIN_URL', useValue: params.origin }
|
{ provide: APP_BASE_HREF, useValue: params.baseUrl },
|
||||||
|
{ provide: 'BASE_URL', useValue: params.origin + params.baseUrl },
|
||||||
];
|
];
|
||||||
|
|
||||||
return platformDynamicServer(providers).bootstrapModule(AppModule).then(moduleRef => {
|
return platformDynamicServer(providers).bootstrapModule(AppModule).then(moduleRef => {
|
||||||
const appRef = moduleRef.injector.get(ApplicationRef);
|
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||||
const state = moduleRef.injector.get(PlatformState);
|
const state = moduleRef.injector.get(PlatformState);
|
||||||
const zone = moduleRef.injector.get(NgZone);
|
const zone = moduleRef.injector.get(NgZone);
|
||||||
|
const http: HttpWithStateTransfer = moduleRef.injector.get(HttpWithStateTransfer);
|
||||||
|
|
||||||
return new Promise<RenderResult>((resolve, reject) => {
|
return new Promise<RenderResult>((resolve, reject) => {
|
||||||
zone.onError.subscribe(errorInfo => reject(errorInfo));
|
zone.onError.subscribe((errorInfo: any) => reject(errorInfo));
|
||||||
appRef.isStable.first(isStable => isStable).subscribe(() => {
|
appRef.isStable.first(isStable => isStable).subscribe(() => {
|
||||||
// Because 'onStable' fires before 'onError', we have to delay slightly before
|
// Because 'onStable' fires before 'onError', we have to delay slightly before
|
||||||
// completing the request in case there's an error to report
|
// completing the request in case there's an error to report
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
resolve({
|
resolve({
|
||||||
html: state.renderToString()
|
html: state.renderToString(),
|
||||||
|
globals: { ...http.stateForTransfer() }
|
||||||
});
|
});
|
||||||
moduleRef.destroy();
|
moduleRef.destroy();
|
||||||
});
|
});
|
||||||
|
|||||||
31
templates/AngularSpa/npm-shrinkwrap.json
generated
31
templates/AngularSpa/npm-shrinkwrap.json
generated
@@ -93,10 +93,10 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.5.53.tgz",
|
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.5.53.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/webpack-env": {
|
||||||
"version": "8.0.8",
|
"version": "1.13.0",
|
||||||
"from": "@types/node@8.0.8",
|
"from": "@types/webpack-env@1.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.8.tgz"
|
"resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.13.0.tgz"
|
||||||
},
|
},
|
||||||
"accepts": {
|
"accepts": {
|
||||||
"version": "1.3.3",
|
"version": "1.3.3",
|
||||||
@@ -273,15 +273,20 @@
|
|||||||
"from": "asn1.js@>=4.0.0 <5.0.0",
|
"from": "asn1.js@>=4.0.0 <5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz"
|
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz"
|
||||||
},
|
},
|
||||||
|
"aspnet-angular": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"from": "aspnet-angular@0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/aspnet-angular/-/aspnet-angular-0.1.1.tgz"
|
||||||
|
},
|
||||||
"aspnet-prerendering": {
|
"aspnet-prerendering": {
|
||||||
"version": "2.0.6",
|
"version": "3.0.1",
|
||||||
"from": "aspnet-prerendering@>=2.0.5 <3.0.0",
|
"from": "aspnet-prerendering@3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/aspnet-prerendering/-/aspnet-prerendering-2.0.6.tgz"
|
"resolved": "https://registry.npmjs.org/aspnet-prerendering/-/aspnet-prerendering-3.0.1.tgz"
|
||||||
},
|
},
|
||||||
"aspnet-webpack": {
|
"aspnet-webpack": {
|
||||||
"version": "1.0.29",
|
"version": "2.0.1",
|
||||||
"from": "aspnet-webpack@>=1.0.29 <2.0.0",
|
"from": "aspnet-webpack@2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-1.0.29.tgz"
|
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-2.0.1.tgz"
|
||||||
},
|
},
|
||||||
"assert": {
|
"assert": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
@@ -932,9 +937,9 @@
|
|||||||
"resolved": "https://registry.npmjs.org/domain-context/-/domain-context-0.5.1.tgz"
|
"resolved": "https://registry.npmjs.org/domain-context/-/domain-context-0.5.1.tgz"
|
||||||
},
|
},
|
||||||
"domain-task": {
|
"domain-task": {
|
||||||
"version": "2.0.3",
|
"version": "3.0.3",
|
||||||
"from": "domain-task@>=2.0.2 <3.0.0",
|
"from": "domain-task@>=3.0.0 <4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/domain-task/-/domain-task-2.0.3.tgz"
|
"resolved": "https://registry.npmjs.org/domain-task/-/domain-task-3.0.3.tgz"
|
||||||
},
|
},
|
||||||
"ee-first": {
|
"ee-first": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
|
|||||||
@@ -18,10 +18,11 @@
|
|||||||
"@angular/platform-server": "4.2.5",
|
"@angular/platform-server": "4.2.5",
|
||||||
"@angular/router": "4.2.5",
|
"@angular/router": "4.2.5",
|
||||||
"@ngtools/webpack": "1.5.0",
|
"@ngtools/webpack": "1.5.0",
|
||||||
"@types/node": "8.0.8",
|
"@types/webpack-env": "1.13.0",
|
||||||
"angular2-template-loader": "0.6.2",
|
"angular2-template-loader": "0.6.2",
|
||||||
"aspnet-prerendering": "^2.0.5",
|
"aspnet-angular": "^0.1.1",
|
||||||
"aspnet-webpack": "^1.0.29",
|
"aspnet-prerendering": "^3.0.1",
|
||||||
|
"aspnet-webpack": "^2.0.1",
|
||||||
"awesome-typescript-loader": "3.2.1",
|
"awesome-typescript-loader": "3.2.1",
|
||||||
"bootstrap": "3.3.7",
|
"bootstrap": "3.3.7",
|
||||||
"css": "2.2.1",
|
"css": "2.2.1",
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"module": "es2015",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"skipDefaultLibCheck": true,
|
"skipDefaultLibCheck": true,
|
||||||
|
"skipLibCheck": true, // Workaround for https://github.com/angular/angular/issues/17863. Remove this if you upgrade to a fixed version of Angular.
|
||||||
|
"strict": true,
|
||||||
"lib": [ "es6", "dom" ],
|
"lib": [ "es6", "dom" ],
|
||||||
"types": [ "node" ]
|
"types": [ "webpack-env" ]
|
||||||
},
|
},
|
||||||
"exclude": [ "bin", "node_modules" ],
|
"exclude": [ "bin", "node_modules" ],
|
||||||
"atom": { "rewriteTsconfig": false }
|
"atom": { "rewriteTsconfig": false }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ module.exports = (env) => {
|
|||||||
resolve: { extensions: [ '.js', '.ts' ] },
|
resolve: { extensions: [ '.js', '.ts' ] },
|
||||||
output: {
|
output: {
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
|
publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ module.exports = (env) => {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
publicPath: '/dist/',
|
publicPath: 'dist/',
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
library: '[name]_[hash]'
|
library: '[name]_[hash]'
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,17 +9,17 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||||
</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>
|
||||||
|
|
||||||
<!--/-:cnd:noEmit -->
|
<!--/-:cnd:noEmit -->
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export class Fetchdata {
|
|||||||
public forecasts: WeatherForecast[];
|
public forecasts: WeatherForecast[];
|
||||||
|
|
||||||
constructor(http: HttpClient) {
|
constructor(http: HttpClient) {
|
||||||
http.fetch('/api/SampleData/WeatherForecasts')
|
http.fetch('api/SampleData/WeatherForecasts')
|
||||||
.then(result => result.json() as Promise<WeatherForecast[]>)
|
.then(result => result.json() as Promise<WeatherForecast[]>)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
this.forecasts = data;
|
this.forecasts = data;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'isomorphic-fetch';
|
import 'isomorphic-fetch';
|
||||||
import { Aurelia, PLATFORM } from 'aurelia-framework';
|
import { Aurelia, PLATFORM } from 'aurelia-framework';
|
||||||
|
import { HttpClient } from 'aurelia-fetch-client';
|
||||||
import 'bootstrap/dist/css/bootstrap.css';
|
import 'bootstrap/dist/css/bootstrap.css';
|
||||||
import 'bootstrap';
|
import 'bootstrap';
|
||||||
declare const IS_DEV_BUILD: boolean; // The value is supplied by Webpack during the build
|
declare const IS_DEV_BUILD: boolean; // The value is supplied by Webpack during the build
|
||||||
@@ -11,5 +12,10 @@ export function configure(aurelia: Aurelia) {
|
|||||||
aurelia.use.developmentLogging();
|
aurelia.use.developmentLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new HttpClient().configure(config => {
|
||||||
|
const baseUrl = document.getElementsByTagName('base')[0].href;
|
||||||
|
config.withBaseUrl(baseUrl);
|
||||||
|
});
|
||||||
|
|
||||||
aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app/components/app/app')));
|
aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app/components/app/app')));
|
||||||
}
|
}
|
||||||
|
|||||||
14
templates/AureliaSpa/npm-shrinkwrap.json
generated
14
templates/AureliaSpa/npm-shrinkwrap.json
generated
@@ -2,10 +2,10 @@
|
|||||||
"name": "WebApplicationBasic",
|
"name": "WebApplicationBasic",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": {
|
"@types/webpack-env": {
|
||||||
"version": "7.0.32",
|
"version": "1.13.0",
|
||||||
"from": "@types/node@>=7.0.12 <8.0.0",
|
"from": "@types/webpack-env@>=1.13.0 <2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.32.tgz",
|
"resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.13.0.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
@@ -113,9 +113,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"aspnet-webpack": {
|
"aspnet-webpack": {
|
||||||
"version": "1.0.29",
|
"version": "2.0.1",
|
||||||
"from": "aspnet-webpack@>=1.0.28 <2.0.0",
|
"from": "aspnet-webpack@2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-1.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-2.0.1.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"assert": {
|
"assert": {
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
"jquery": "^3.2.1"
|
"jquery": "^3.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^7.0.12",
|
"@types/webpack-env": "^1.13.0",
|
||||||
"aspnet-webpack": "^1.0.28",
|
"aspnet-webpack": "^2.0.1",
|
||||||
"aurelia-webpack-plugin": "^2.0.0-rc.2",
|
"aurelia-webpack-plugin": "^2.0.0-rc.2",
|
||||||
"css-loader": "^0.28.0",
|
"css-loader": "^0.28.0",
|
||||||
"extract-text-webpack-plugin": "^2.1.0",
|
"extract-text-webpack-plugin": "^2.1.0",
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"module": "es2015",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"skipDefaultLibCheck": true,
|
"skipDefaultLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
"lib": [ "es2015", "dom" ],
|
"lib": [ "es2015", "dom" ],
|
||||||
"types": [ "node" ]
|
"types": [ "webpack-env" ]
|
||||||
},
|
},
|
||||||
"exclude": [ "bin", "node_modules" ],
|
"exclude": [ "bin", "node_modules" ],
|
||||||
"atom": { "rewriteTsconfig": false }
|
"atom": { "rewriteTsconfig": false }
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ module.exports = (env) => {
|
|||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(bundleOutputDir),
|
path: path.resolve(bundleOutputDir),
|
||||||
publicPath: '/dist/',
|
publicPath: 'dist/',
|
||||||
filename: '[name].js'
|
filename: '[name].js'
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ module.exports = ({ prod } = {}) => {
|
|||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'wwwroot', 'dist'),
|
path: path.join(__dirname, 'wwwroot', 'dist'),
|
||||||
publicPath: '/dist/',
|
publicPath: 'dist/',
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
library: '[name]_[hash]',
|
library: '[name]_[hash]',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
import './css/site.css';
|
import './css/site.css';
|
||||||
import 'bootstrap';
|
import 'bootstrap';
|
||||||
import * as ko from 'knockout';
|
import * as ko from 'knockout';
|
||||||
|
import { createBrowserHistory } from 'history';
|
||||||
import './webpack-component-loader';
|
import './webpack-component-loader';
|
||||||
import AppRootComponent from './components/app-root/app-root';
|
import AppRootComponent from './components/app-root/app-root';
|
||||||
const createHistory = require('history').createBrowserHistory;
|
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')!;
|
||||||
|
const basename = baseUrl.substring(0, baseUrl.length - 1); // History component needs no trailing slash
|
||||||
|
|
||||||
// Load and register the <app-root> component
|
// Load and register the <app-root> component
|
||||||
ko.components.register('app-root', AppRootComponent);
|
ko.components.register('app-root', AppRootComponent);
|
||||||
|
|
||||||
// Tell Knockout to start up an instance of your application
|
// Tell Knockout to start up an instance of your application
|
||||||
ko.applyBindings({ history: createHistory() });
|
ko.applyBindings({ history: createBrowserHistory({ basename }), basename });
|
||||||
|
|
||||||
// Basic hot reloading support. Automatically reloads and restarts the Knockout app each time
|
// Basic hot reloading support. Automatically reloads and restarts the Knockout app each time
|
||||||
// you modify source files. This will not preserve any application state other than the URL.
|
// you modify source files. This will not preserve any application state other than the URL.
|
||||||
declare var module: any;
|
|
||||||
if (module.hot) {
|
if (module.hot) {
|
||||||
module.hot.accept();
|
module.hot.accept();
|
||||||
module.hot.dispose(() => ko.cleanNode(document.body));
|
module.hot.dispose(() => ko.cleanNode(document.body));
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<div class='container-fluid'>
|
<div class='container-fluid'>
|
||||||
<div class='row'>
|
<div class='row'>
|
||||||
<div class='col-sm-3'>
|
<div class='col-sm-3'>
|
||||||
<nav-menu params='route: route'></nav-menu>
|
<nav-menu params='router: router'></nav-menu>
|
||||||
</div>
|
</div>
|
||||||
<div class='col-sm-9' data-bind='component: { name: route().page, params: route }'></div>
|
<div class='col-sm-9' data-bind='component: { name: route().page, params: route }'></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ const routes: Route[] = [
|
|||||||
|
|
||||||
class AppRootViewModel {
|
class AppRootViewModel {
|
||||||
public route: KnockoutObservable<Route>;
|
public route: KnockoutObservable<Route>;
|
||||||
private _router: Router;
|
public router: Router;
|
||||||
|
|
||||||
constructor(params: { history: History.History }) {
|
constructor(params: { history: History.History, basename: string }) {
|
||||||
// Activate the client-side router
|
// Activate the client-side router
|
||||||
this._router = new Router(params.history, routes)
|
this.router = new Router(params.history, routes, params.basename);
|
||||||
this.route = this._router.currentRoute;
|
this.route = this.router.currentRoute;
|
||||||
|
|
||||||
// Load and register all the KO components needed to handle the routes
|
// Load and register all the KO components needed to handle the routes
|
||||||
// The optional 'bundle-loader?lazy!' prefix is a Webpack feature that causes the referenced modules
|
// The optional 'bundle-loader?lazy!' prefix is a Webpack feature that causes the referenced modules
|
||||||
@@ -32,7 +32,7 @@ class AppRootViewModel {
|
|||||||
// To support hot module replacement, this method unregisters the router and KO components.
|
// To support hot module replacement, this method unregisters the router and KO components.
|
||||||
// In production scenarios where hot module replacement is disabled, this would not be invoked.
|
// In production scenarios where hot module replacement is disabled, this would not be invoked.
|
||||||
public dispose() {
|
public dispose() {
|
||||||
this._router.dispose();
|
this.router.dispose();
|
||||||
|
|
||||||
// TODO: Need a better API for this
|
// TODO: Need a better API for this
|
||||||
Object.getOwnPropertyNames((<any>ko).components._allRegisteredComponents).forEach(componentName => {
|
Object.getOwnPropertyNames((<any>ko).components._allRegisteredComponents).forEach(componentName => {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class FetchDataViewModel {
|
|||||||
public forecasts = ko.observableArray<WeatherForecast>();
|
public forecasts = ko.observableArray<WeatherForecast>();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
fetch('/api/SampleData/WeatherForecasts')
|
fetch('api/SampleData/WeatherForecasts')
|
||||||
.then(response => response.json() as Promise<WeatherForecast[]>)
|
.then(response => response.json() as Promise<WeatherForecast[]>)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
this.forecasts(data);
|
this.forecasts(data);
|
||||||
|
|||||||
@@ -13,17 +13,17 @@
|
|||||||
<div class='navbar-collapse collapse'>
|
<div class='navbar-collapse collapse'>
|
||||||
<ul class='nav navbar-nav'>
|
<ul class='nav navbar-nav'>
|
||||||
<li>
|
<li>
|
||||||
<a href='/' data-bind='css: { active: route().page === "home-page" }'>
|
<a data-bind='attr: { href: router.link("/") }, css: { active: route().page === "home-page" }'>
|
||||||
<span class='glyphicon glyphicon-home'></span> Home
|
<span class='glyphicon glyphicon-home'></span> Home
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='/counter' data-bind='css: { active: route().page === "counter-example" }'>
|
<a data-bind='attr: { href: router.link("/counter") }, css: { active: route().page === "counter-example" }'>
|
||||||
<span class='glyphicon glyphicon-education'></span> Counter
|
<span class='glyphicon glyphicon-education'></span> Counter
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='/fetch-data' data-bind='css: { active: route().page === "fetch-data" }'>
|
<a data-bind='attr: { href: router.link("/fetch-data") }, css: { active: route().page === "fetch-data" }'>
|
||||||
<span class='glyphicon glyphicon-th-list'></span> Fetch data
|
<span class='glyphicon glyphicon-th-list'></span> Fetch data
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
import * as ko from 'knockout';
|
import * as ko from 'knockout';
|
||||||
import { Route } from '../../router';
|
import { Route, Router } from '../../router';
|
||||||
|
|
||||||
interface NavMenuParams {
|
interface NavMenuParams {
|
||||||
route: KnockoutObservable<Route>;
|
router: Router;
|
||||||
}
|
}
|
||||||
|
|
||||||
class NavMenuViewModel {
|
class NavMenuViewModel {
|
||||||
|
public router: Router;
|
||||||
public route: KnockoutObservable<Route>;
|
public route: KnockoutObservable<Route>;
|
||||||
|
|
||||||
constructor(params: NavMenuParams) {
|
constructor(params: NavMenuParams) {
|
||||||
// This viewmodel doesn't do anything except pass through the 'route' parameter to the view.
|
// This viewmodel doesn't do anything except pass through the 'route' parameter to the view.
|
||||||
// You could remove this viewmodel entirely, and define 'nav-menu' as a template-only component.
|
// You could remove this viewmodel entirely, and define 'nav-menu' as a template-only component.
|
||||||
// But in most apps, you'll want some viewmodel logic to determine what navigation options appear.
|
// But in most apps, you'll want some viewmodel logic to determine what navigation options appear.
|
||||||
this.route = params.route;
|
this.router = params.router;
|
||||||
|
this.route = this.router.currentRoute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as ko from 'knockout';
|
import * as ko from 'knockout';
|
||||||
import * as $ from 'jquery';
|
import * as $ from 'jquery';
|
||||||
import * as History from 'history';
|
import * as History from 'history';
|
||||||
import crossroads = require('crossroads');
|
import * as crossroads from 'crossroads';
|
||||||
|
|
||||||
// This module configures crossroads.js, a routing library. If you prefer, you
|
// This module configures crossroads.js, a routing library. If you prefer, you
|
||||||
// can use any other routing library (or none at all) as Knockout is designed to
|
// can use any other routing library (or none at all) as Knockout is designed to
|
||||||
@@ -16,13 +16,13 @@ export class Router {
|
|||||||
private disposeHistory: () => void;
|
private disposeHistory: () => void;
|
||||||
private clickEventListener: EventListener;
|
private clickEventListener: EventListener;
|
||||||
|
|
||||||
constructor(history: History.History, routes: Route[]) {
|
constructor(private history: History.History, routes: Route[], basename: string) {
|
||||||
// Reset and configure Crossroads so it matches routes and updates this.currentRoute
|
// Reset and configure Crossroads so it matches routes and updates this.currentRoute
|
||||||
crossroads.removeAllRoutes();
|
crossroads.removeAllRoutes();
|
||||||
crossroads.resetState();
|
crossroads.resetState();
|
||||||
crossroads.normalizeFn = crossroads.NORM_AS_OBJECT;
|
(crossroads as any).normalizeFn = crossroads.NORM_AS_OBJECT;
|
||||||
routes.forEach(route => {
|
routes.forEach(route => {
|
||||||
crossroads.addRoute(route.url, (requestParams) => {
|
crossroads.addRoute(route.url, (requestParams: any) => {
|
||||||
this.currentRoute(ko.utils.extend(requestParams, route.params));
|
this.currentRoute(ko.utils.extend(requestParams, route.params));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -33,8 +33,9 @@ export class Router {
|
|||||||
let target: any = evt.currentTarget;
|
let target: any = evt.currentTarget;
|
||||||
if (target && target.tagName === 'A') {
|
if (target && target.tagName === 'A') {
|
||||||
let href = target.getAttribute('href');
|
let href = target.getAttribute('href');
|
||||||
if (href && href.charAt(0) == '/') {
|
if (href && href.indexOf(basename + '/') === 0) {
|
||||||
history.push(href);
|
const hrefAfterBasename = href.substring(basename.length);
|
||||||
|
history.push(hrefAfterBasename);
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,6 +47,10 @@ export class Router {
|
|||||||
crossroads.parse((history as any).location.pathname);
|
crossroads.parse((history as any).location.pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public link(url: string): string {
|
||||||
|
return this.history.createHref({ pathname: url });
|
||||||
|
}
|
||||||
|
|
||||||
public dispose() {
|
public dispose() {
|
||||||
this.disposeHistory();
|
this.disposeHistory();
|
||||||
$(document).off('click', 'a', this.clickEventListener);
|
$(document).off('click', 'a', this.clickEventListener);
|
||||||
|
|||||||
@@ -8,18 +8,18 @@ ko.components.loaders.unshift({
|
|||||||
loadComponent: (name, componentConfig, callback) => {
|
loadComponent: (name, componentConfig, callback) => {
|
||||||
if (typeof componentConfig === 'function') {
|
if (typeof componentConfig === 'function') {
|
||||||
// It's a lazy-loaded Webpack bundle
|
// It's a lazy-loaded Webpack bundle
|
||||||
(componentConfig as any)(loadedModule => {
|
(componentConfig as any)((loadedModule: any) => {
|
||||||
// Handle TypeScript-style default exports
|
// Handle TypeScript-style default exports
|
||||||
if (loadedModule.__esModule && loadedModule.default) {
|
if (loadedModule.__esModule && loadedModule.default) {
|
||||||
loadedModule = loadedModule.default;
|
loadedModule = loadedModule.default;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass the loaded module to KO's default loader
|
// Pass the loaded module to KO's default loader
|
||||||
ko.components.defaultLoader.loadComponent(name, loadedModule, callback);
|
ko.components.defaultLoader.loadComponent!(name, loadedModule as KnockoutComponentTypes.ComponentConfig, callback);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// It's something else - let another component loader handle it
|
// It's something else - let another component loader handle it
|
||||||
callback(null);
|
callback((null as any) as KnockoutComponentTypes.Definition); // workaround until https://github.com/DefinitelyTyped/DefinitelyTyped/pull/17999
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,17 +9,17 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||||
</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>
|
||||||
|
|
||||||
<!--/-:cnd:noEmit -->
|
<!--/-:cnd:noEmit -->
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
ViewData["Title"] = "Home Page";
|
ViewData["Title"] = "Home Page";
|
||||||
}
|
}
|
||||||
|
|
||||||
<app-root params="history: history"></app-root>
|
<app-root params="history: history, basename: basename"></app-root>
|
||||||
|
|
||||||
@section scripts {
|
@section scripts {
|
||||||
<script src="~/dist/main.js" asp-append-version="true"></script>
|
<script src="~/dist/main.js" asp-append-version="true"></script>
|
||||||
|
|||||||
36
templates/KnockoutSpa/npm-shrinkwrap.json
generated
36
templates/KnockoutSpa/npm-shrinkwrap.json
generated
@@ -21,9 +21,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/history": {
|
"@types/history": {
|
||||||
"version": "2.0.48",
|
"version": "4.6.0",
|
||||||
"from": "@types/history@>=2.0.38 <3.0.0",
|
"from": "@types/history@4.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/history/-/history-2.0.48.tgz",
|
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.6.0.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/jquery": {
|
"@types/jquery": {
|
||||||
@@ -38,30 +38,18 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/knockout/-/knockout-3.4.41.tgz",
|
"resolved": "https://registry.npmjs.org/@types/knockout/-/knockout-3.4.41.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/react": {
|
|
||||||
"version": "15.0.31",
|
|
||||||
"from": "@types/react@*",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-15.0.31.tgz",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/react-router": {
|
|
||||||
"version": "2.0.50",
|
|
||||||
"from": "@types/react-router@>=2.0.37 <3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-2.0.50.tgz",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/requirejs": {
|
|
||||||
"version": "2.1.29",
|
|
||||||
"from": "@types/requirejs@>=2.1.26 <3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/requirejs/-/requirejs-2.1.29.tgz",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/signals": {
|
"@types/signals": {
|
||||||
"version": "0.0.16",
|
"version": "0.0.16",
|
||||||
"from": "@types/signals@0.0.16",
|
"from": "@types/signals@0.0.16",
|
||||||
"resolved": "https://registry.npmjs.org/@types/signals/-/signals-0.0.16.tgz",
|
"resolved": "https://registry.npmjs.org/@types/signals/-/signals-0.0.16.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/webpack-env": {
|
||||||
|
"version": "1.13.0",
|
||||||
|
"from": "@types/webpack-env@>=1.13.0 <2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.13.0.tgz",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "5.0.3",
|
"version": "5.0.3",
|
||||||
"from": "acorn@>=5.0.0 <6.0.0",
|
"from": "acorn@>=5.0.0 <6.0.0",
|
||||||
@@ -167,9 +155,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"aspnet-webpack": {
|
"aspnet-webpack": {
|
||||||
"version": "1.0.29",
|
"version": "2.0.1",
|
||||||
"from": "aspnet-webpack@>=1.0.27 <2.0.0",
|
"from": "aspnet-webpack@2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-1.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-2.0.1.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"assert": {
|
"assert": {
|
||||||
|
|||||||
@@ -6,13 +6,12 @@
|
|||||||
"@types/core-js": "^0.9.34",
|
"@types/core-js": "^0.9.34",
|
||||||
"@types/crossroads": "0.0.29",
|
"@types/crossroads": "0.0.29",
|
||||||
"@types/es6-promise": "0.0.32",
|
"@types/es6-promise": "0.0.32",
|
||||||
"@types/history": "^2.0.38",
|
"@types/history": "^4.6.0",
|
||||||
"@types/jquery": "^2.0.32",
|
"@types/jquery": "^2.0.32",
|
||||||
"@types/knockout": "^3.4.35",
|
"@types/knockout": "^3.4.41",
|
||||||
"@types/react-router": "^2.0.37",
|
|
||||||
"@types/requirejs": "^2.1.26",
|
|
||||||
"@types/signals": "0.0.16",
|
"@types/signals": "0.0.16",
|
||||||
"aspnet-webpack": "^1.0.27",
|
"@types/webpack-env": "^1.13.0",
|
||||||
|
"aspnet-webpack": "^2.0.1",
|
||||||
"awesome-typescript-loader": "^3.0.0",
|
"awesome-typescript-loader": "^3.0.0",
|
||||||
"bootstrap": "^3.3.6",
|
"bootstrap": "^3.3.6",
|
||||||
"bundle-loader": "^0.5.4",
|
"bundle-loader": "^0.5.4",
|
||||||
@@ -21,7 +20,7 @@
|
|||||||
"event-source-polyfill": "^0.0.7",
|
"event-source-polyfill": "^0.0.7",
|
||||||
"extract-text-webpack-plugin": "^2.0.0-rc",
|
"extract-text-webpack-plugin": "^2.0.0-rc",
|
||||||
"file-loader": "^0.9.0",
|
"file-loader": "^0.9.0",
|
||||||
"history": "^4.3.0",
|
"history": "^4.6.3",
|
||||||
"isomorphic-fetch": "^2.2.1",
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"jquery": "^2.2.1",
|
"jquery": "^2.2.1",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"module": "es2015",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"skipDefaultLibCheck": true,
|
"skipDefaultLibCheck": true,
|
||||||
"types": ["es6-promise", "history", "requirejs"]
|
"strict": true,
|
||||||
|
"types": ["es6-promise", "webpack-env"]
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"bin",
|
"bin",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ module.exports = (env) => {
|
|||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, bundleOutputDir),
|
path: path.join(__dirname, bundleOutputDir),
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
publicPath: '/dist/'
|
publicPath: 'dist/'
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ module.exports = (env) => {
|
|||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'wwwroot', 'dist'),
|
path: path.join(__dirname, 'wwwroot', 'dist'),
|
||||||
publicPath: '/dist/',
|
publicPath: 'dist/',
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
library: '[name]_[hash]',
|
library: '[name]_[hash]',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ import * as RoutesModule from './routes';
|
|||||||
let routes = RoutesModule.routes;
|
let routes = RoutesModule.routes;
|
||||||
|
|
||||||
// Create browser history to use in the Redux store
|
// Create browser history to use in the Redux store
|
||||||
const history = createBrowserHistory();
|
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')!;
|
||||||
|
const history = createBrowserHistory({ basename: baseUrl });
|
||||||
|
|
||||||
// Get the application-wide store instance, prepopulating with state from the server where available.
|
// Get the application-wide store instance, prepopulating with state from the server where available.
|
||||||
const initialState = (window as any).initialReduxState as ApplicationState;
|
const initialState = (window as any).initialReduxState as ApplicationState;
|
||||||
|
|||||||
@@ -12,15 +12,17 @@ export default createServerRenderer(params => {
|
|||||||
return new Promise<RenderResult>((resolve, reject) => {
|
return new Promise<RenderResult>((resolve, reject) => {
|
||||||
// Prepare Redux store with in-memory history, and dispatch a navigation event
|
// Prepare Redux store with in-memory history, and dispatch a navigation event
|
||||||
// corresponding to the incoming URL
|
// corresponding to the incoming URL
|
||||||
|
const basename = params.baseUrl.substring(0, params.baseUrl.length - 1); // Remove trailing slash
|
||||||
|
const urlAfterBasename = params.url.substring(basename.length);
|
||||||
const store = configureStore(createMemoryHistory());
|
const store = configureStore(createMemoryHistory());
|
||||||
store.dispatch(replace(params.location));
|
store.dispatch(replace(urlAfterBasename));
|
||||||
|
|
||||||
// Prepare an instance of the application and perform an inital render that will
|
// Prepare an instance of the application and perform an inital render that will
|
||||||
// cause any async tasks (e.g., data access) to begin
|
// cause any async tasks (e.g., data access) to begin
|
||||||
const routerContext: any = {};
|
const routerContext: any = {};
|
||||||
const app = (
|
const app = (
|
||||||
<Provider store={ store }>
|
<Provider store={ store }>
|
||||||
<StaticRouter context={ routerContext } location={ params.location.path } children={ routes } />
|
<StaticRouter basename={ basename } context={ routerContext } location={ params.location.path } children={ routes } />
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
renderToString(app);
|
renderToString(app);
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ class FetchData extends React.Component<WeatherForecastProps, {}> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private renderPagination() {
|
private renderPagination() {
|
||||||
let prevStartDateIndex = this.props.startDateIndex - 5;
|
let prevStartDateIndex = (this.props.startDateIndex || 0) - 5;
|
||||||
let nextStartDateIndex = this.props.startDateIndex + 5;
|
let nextStartDateIndex = (this.props.startDateIndex || 0) + 5;
|
||||||
|
|
||||||
return <p className='clearfix text-center'>
|
return <p className='clearfix text-center'>
|
||||||
<Link className='btn btn-default pull-left' to={ `/fetchdata/${ prevStartDateIndex }` }>Previous</Link>
|
<Link className='btn btn-default pull-left' to={ `/fetchdata/${ prevStartDateIndex }` }>Previous</Link>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { createStore, applyMiddleware, compose, combineReducers, GenericStoreEnhancer, Store } from 'redux';
|
import { createStore, applyMiddleware, compose, combineReducers, GenericStoreEnhancer, Store, StoreEnhancerStoreCreator, ReducersMapObject } from 'redux';
|
||||||
import thunk from 'redux-thunk';
|
import thunk from 'redux-thunk';
|
||||||
import { routerReducer, routerMiddleware } from 'react-router-redux';
|
import { routerReducer, routerMiddleware } from 'react-router-redux';
|
||||||
import * as StoreModule from './store';
|
import * as StoreModule from './store';
|
||||||
@@ -12,7 +12,7 @@ export default function configureStore(history: History, initialState?: Applicat
|
|||||||
const devToolsExtension = windowIfDefined && windowIfDefined.devToolsExtension as () => GenericStoreEnhancer;
|
const devToolsExtension = windowIfDefined && windowIfDefined.devToolsExtension as () => GenericStoreEnhancer;
|
||||||
const createStoreWithMiddleware = compose(
|
const createStoreWithMiddleware = compose(
|
||||||
applyMiddleware(thunk, routerMiddleware(history)),
|
applyMiddleware(thunk, routerMiddleware(history)),
|
||||||
devToolsExtension ? devToolsExtension() : f => f
|
devToolsExtension ? devToolsExtension() : <S>(next: StoreEnhancerStoreCreator<S>) => next
|
||||||
)(createStore);
|
)(createStore);
|
||||||
|
|
||||||
// Combine all reducers and instantiate the app-wide store instance
|
// Combine all reducers and instantiate the app-wide store instance
|
||||||
@@ -30,6 +30,6 @@ export default function configureStore(history: History, initialState?: Applicat
|
|||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildRootReducer(allReducers) {
|
function buildRootReducer(allReducers: ReducersMapObject) {
|
||||||
return combineReducers<ApplicationState>(Object.assign({}, allReducers, { routing: routerReducer }));
|
return combineReducers<ApplicationState>(Object.assign({}, allReducers, { routing: routerReducer }));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { AppThunkAction } from './';
|
|||||||
|
|
||||||
export interface WeatherForecastsState {
|
export interface WeatherForecastsState {
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
startDateIndex: number;
|
startDateIndex?: number;
|
||||||
forecasts: WeatherForecast[];
|
forecasts: WeatherForecast[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,14 +23,14 @@ export interface WeatherForecast {
|
|||||||
// They do not themselves have any side-effects; they just describe something that is going to happen.
|
// They do not themselves have any side-effects; they just describe something that is going to happen.
|
||||||
|
|
||||||
interface RequestWeatherForecastsAction {
|
interface RequestWeatherForecastsAction {
|
||||||
type: 'REQUEST_WEATHER_FORECASTS',
|
type: 'REQUEST_WEATHER_FORECASTS';
|
||||||
startDateIndex: number;
|
startDateIndex: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ReceiveWeatherForecastsAction {
|
interface ReceiveWeatherForecastsAction {
|
||||||
type: 'RECEIVE_WEATHER_FORECASTS',
|
type: 'RECEIVE_WEATHER_FORECASTS';
|
||||||
startDateIndex: number;
|
startDateIndex: number;
|
||||||
forecasts: WeatherForecast[]
|
forecasts: WeatherForecast[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare a 'discriminated union' type. This guarantees that all references to 'type' properties contain one of the
|
// Declare a 'discriminated union' type. This guarantees that all references to 'type' properties contain one of the
|
||||||
@@ -45,7 +45,7 @@ export const actionCreators = {
|
|||||||
requestWeatherForecasts: (startDateIndex: number): AppThunkAction<KnownAction> => (dispatch, getState) => {
|
requestWeatherForecasts: (startDateIndex: number): AppThunkAction<KnownAction> => (dispatch, getState) => {
|
||||||
// Only load data if it's something we don't already have (and are not already loading)
|
// Only load data if it's something we don't already have (and are not already loading)
|
||||||
if (startDateIndex !== getState().weatherForecasts.startDateIndex) {
|
if (startDateIndex !== getState().weatherForecasts.startDateIndex) {
|
||||||
let fetchTask = fetch(`/api/SampleData/WeatherForecasts?startDateIndex=${ startDateIndex }`)
|
let fetchTask = fetch(`api/SampleData/WeatherForecasts?startDateIndex=${ startDateIndex }`)
|
||||||
.then(response => response.json() as Promise<WeatherForecast[]>)
|
.then(response => response.json() as Promise<WeatherForecast[]>)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
dispatch({ type: 'RECEIVE_WEATHER_FORECASTS', startDateIndex: startDateIndex, forecasts: data });
|
dispatch({ type: 'RECEIVE_WEATHER_FORECASTS', startDateIndex: startDateIndex, forecasts: data });
|
||||||
@@ -60,7 +60,7 @@ export const actionCreators = {
|
|||||||
// ----------------
|
// ----------------
|
||||||
// REDUCER - For a given state and action, returns the new state. To support time travel, this must not mutate the old state.
|
// REDUCER - For a given state and action, returns the new state. To support time travel, this must not mutate the old state.
|
||||||
|
|
||||||
const unloadedState: WeatherForecastsState = { startDateIndex: null, forecasts: [], isLoading: false };
|
const unloadedState: WeatherForecastsState = { forecasts: [], isLoading: false };
|
||||||
|
|
||||||
export const reducer: Reducer<WeatherForecastsState> = (state: WeatherForecastsState, incomingAction: Action) => {
|
export const reducer: Reducer<WeatherForecastsState> = (state: WeatherForecastsState, incomingAction: Action) => {
|
||||||
const action = incomingAction as KnownAction;
|
const action = incomingAction as KnownAction;
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import * as Counter from './Counter';
|
|||||||
|
|
||||||
// The top-level state object
|
// The top-level state object
|
||||||
export interface ApplicationState {
|
export interface ApplicationState {
|
||||||
counter: Counter.CounterState,
|
counter: Counter.CounterState;
|
||||||
weatherForecasts: WeatherForecasts.WeatherForecastsState
|
weatherForecasts: WeatherForecasts.WeatherForecastsState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whenever an action is dispatched, Redux will update each top-level application state property using
|
// Whenever an action is dispatched, Redux will update each top-level application state property using
|
||||||
|
|||||||
@@ -9,17 +9,17 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||||
</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>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
30
templates/ReactReduxSpa/npm-shrinkwrap.json
generated
30
templates/ReactReduxSpa/npm-shrinkwrap.json
generated
@@ -22,6 +22,11 @@
|
|||||||
"from": "@types/react-dom@15.5.1",
|
"from": "@types/react-dom@15.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-15.5.1.tgz"
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-15.5.1.tgz"
|
||||||
},
|
},
|
||||||
|
"@types/react-hot-loader": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"from": "@types/react-hot-loader@3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-hot-loader/-/react-hot-loader-3.0.3.tgz"
|
||||||
|
},
|
||||||
"@types/react-redux": {
|
"@types/react-redux": {
|
||||||
"version": "4.4.45",
|
"version": "4.4.45",
|
||||||
"from": "@types/react-redux@4.4.45",
|
"from": "@types/react-redux@4.4.45",
|
||||||
@@ -170,26 +175,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz"
|
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz"
|
||||||
},
|
},
|
||||||
"aspnet-prerendering": {
|
"aspnet-prerendering": {
|
||||||
"version": "2.0.6",
|
"version": "3.0.1",
|
||||||
"from": "aspnet-prerendering@>=2.0.5 <3.0.0",
|
"from": "aspnet-prerendering@3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/aspnet-prerendering/-/aspnet-prerendering-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/aspnet-prerendering/-/aspnet-prerendering-3.0.1.tgz"
|
||||||
"dependencies": {
|
|
||||||
"domain-task": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"from": "domain-task@>=2.0.2 <3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/domain-task/-/domain-task-2.0.3.tgz"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"aspnet-webpack": {
|
"aspnet-webpack": {
|
||||||
"version": "1.0.29",
|
"version": "2.0.1",
|
||||||
"from": "aspnet-webpack@>=1.0.29 <2.0.0",
|
"from": "aspnet-webpack@2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-1.0.29.tgz"
|
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-2.0.1.tgz"
|
||||||
},
|
},
|
||||||
"aspnet-webpack-react": {
|
"aspnet-webpack-react": {
|
||||||
"version": "3.0.0-beta.1",
|
"version": "3.0.0",
|
||||||
"from": "aspnet-webpack-react@>=3.0.0-beta <4.0.0",
|
"from": "aspnet-webpack-react@3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/aspnet-webpack-react/-/aspnet-webpack-react-3.0.0-beta.1.tgz"
|
"resolved": "https://registry.npmjs.org/aspnet-webpack-react/-/aspnet-webpack-react-3.0.0.tgz"
|
||||||
},
|
},
|
||||||
"assert": {
|
"assert": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
|
|||||||
@@ -6,15 +6,16 @@
|
|||||||
"@types/history": "4.6.0",
|
"@types/history": "4.6.0",
|
||||||
"@types/react": "15.0.35",
|
"@types/react": "15.0.35",
|
||||||
"@types/react-dom": "15.5.1",
|
"@types/react-dom": "15.5.1",
|
||||||
|
"@types/react-hot-loader": "3.0.3",
|
||||||
"@types/react-redux": "4.4.45",
|
"@types/react-redux": "4.4.45",
|
||||||
"@types/react-router": "4.0.12",
|
"@types/react-router": "4.0.12",
|
||||||
"@types/react-router-dom": "4.0.5",
|
"@types/react-router-dom": "4.0.5",
|
||||||
"@types/react-router-redux": "5.0.3",
|
"@types/react-router-redux": "5.0.3",
|
||||||
"@types/webpack": "2.2.15",
|
"@types/webpack": "2.2.15",
|
||||||
"@types/webpack-env": "1.13.0",
|
"@types/webpack-env": "1.13.0",
|
||||||
"aspnet-prerendering": "^2.0.5",
|
"aspnet-prerendering": "^3.0.1",
|
||||||
"aspnet-webpack": "^1.0.29",
|
"aspnet-webpack": "^2.0.1",
|
||||||
"aspnet-webpack-react": "^3.0.0-beta",
|
"aspnet-webpack-react": "^3.0.0",
|
||||||
"awesome-typescript-loader": "3.2.1",
|
"awesome-typescript-loader": "3.2.1",
|
||||||
"bootstrap": "3.3.7",
|
"bootstrap": "3.3.7",
|
||||||
"css-loader": "0.28.4",
|
"css-loader": "0.28.4",
|
||||||
|
|||||||
@@ -1,21 +1,16 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
"module": "es2015",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"skipDefaultLibCheck": true,
|
"skipDefaultLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
"lib": ["es6", "dom"],
|
"lib": ["es6", "dom"],
|
||||||
"types": [ "webpack-env" ],
|
"types": ["webpack-env"]
|
||||||
"paths": {
|
|
||||||
// Fix "Duplicate identifier" errors caused by multiple dependencies fetching their own copies of type definitions.
|
|
||||||
// We tell TypeScript which type definitions module to treat as the canonical one (instead of combining all of them).
|
|
||||||
"history": ["./node_modules/@types/history/index"],
|
|
||||||
"redux": ["./node_modules/@types/redux/index"],
|
|
||||||
"react": ["./node_modules/@types/react/index"]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"bin",
|
"bin",
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ module.exports = (env) => {
|
|||||||
resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
|
resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
|
||||||
output: {
|
output: {
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
|
publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{ test: /\.tsx?$/, include: /ClientApp/, use: 'awesome-typescript-loader?silent=true' }
|
{ test: /\.tsx?$/, include: /ClientApp/, use: 'awesome-typescript-loader?silent=true' },
|
||||||
|
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
plugins: [new CheckerPlugin()]
|
plugins: [new CheckerPlugin()]
|
||||||
@@ -29,8 +30,7 @@ module.exports = (env) => {
|
|||||||
entry: { 'main-client': './ClientApp/boot-client.tsx' },
|
entry: { 'main-client': './ClientApp/boot-client.tsx' },
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{ test: /\.css$/, use: ExtractTextPlugin.extract({ use: isDevBuild ? 'css-loader' : 'css-loader?minimize' }) },
|
{ test: /\.css$/, use: ExtractTextPlugin.extract({ use: isDevBuild ? 'css-loader' : 'css-loader?minimize' }) }
|
||||||
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
output: { path: path.join(__dirname, clientBundleOutputDir) },
|
output: { path: path.join(__dirname, clientBundleOutputDir) },
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ module.exports = (env) => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
publicPath: '/dist/',
|
publicPath: 'dist/',
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
library: '[name]_[hash]',
|
library: '[name]_[hash]',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ let routes = RoutesModule.routes;
|
|||||||
function renderApp() {
|
function renderApp() {
|
||||||
// This code starts up the React app when it runs in a browser. It sets up the routing
|
// This code starts up the React app when it runs in a browser. It sets up the routing
|
||||||
// configuration and injects the app into a DOM element.
|
// configuration and injects the app into a DOM element.
|
||||||
|
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')!;
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<AppContainer>
|
<AppContainer>
|
||||||
<BrowserRouter children={ routes } />
|
<BrowserRouter children={ routes } basename={ baseUrl } />
|
||||||
</AppContainer>,
|
</AppContainer>,
|
||||||
document.getElementById('react-app')
|
document.getElementById('react-app')
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { RouteComponentProps } from 'react-router';
|
||||||
|
|
||||||
interface CounterState {
|
interface CounterState {
|
||||||
currentCount: number;
|
currentCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Counter extends React.Component<{}, CounterState> {
|
export class Counter extends React.Component<RouteComponentProps<{}>, CounterState> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.state = { currentCount: 0 };
|
this.state = { currentCount: 0 };
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { RouteComponentProps } from 'react-router';
|
||||||
import 'isomorphic-fetch';
|
import 'isomorphic-fetch';
|
||||||
|
|
||||||
interface FetchDataExampleState {
|
interface FetchDataExampleState {
|
||||||
@@ -6,12 +7,12 @@ interface FetchDataExampleState {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FetchData extends React.Component<{}, FetchDataExampleState> {
|
export class FetchData extends React.Component<RouteComponentProps<{}>, FetchDataExampleState> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.state = { forecasts: [], loading: true };
|
this.state = { forecasts: [], loading: true };
|
||||||
|
|
||||||
fetch('/api/SampleData/WeatherForecasts')
|
fetch('api/SampleData/WeatherForecasts')
|
||||||
.then(response => response.json() as Promise<WeatherForecast[]>)
|
.then(response => response.json() as Promise<WeatherForecast[]>)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
this.setState({ forecasts: data, loading: false });
|
this.setState({ forecasts: data, loading: false });
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { RouteComponentProps } from 'react-router';
|
||||||
|
|
||||||
export class Home extends React.Component<{}, {}> {
|
export class Home extends React.Component<RouteComponentProps<{}>, {}> {
|
||||||
public render() {
|
public render() {
|
||||||
return <div>
|
return <div>
|
||||||
<h1>Hello, world!</h1>
|
<h1>Hello, world!</h1>
|
||||||
|
|||||||
@@ -9,17 +9,17 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||||
</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>
|
||||||
|
|
||||||
<!--/-:cnd:noEmit -->
|
<!--/-:cnd:noEmit -->
|
||||||
|
|||||||
24
templates/ReactSpa/npm-shrinkwrap.json
generated
24
templates/ReactSpa/npm-shrinkwrap.json
generated
@@ -20,12 +20,24 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-15.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-15.5.1.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/react-hot-loader": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"from": "@types/react-hot-loader@3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-hot-loader/-/react-hot-loader-3.0.3.tgz",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/react-router": {
|
"@types/react-router": {
|
||||||
"version": "4.0.12",
|
"version": "4.0.12",
|
||||||
"from": "@types/react-router@4.0.12",
|
"from": "@types/react-router@4.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-4.0.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-4.0.12.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/react-router-dom": {
|
||||||
|
"version": "4.0.5",
|
||||||
|
"from": "@types/react-router-dom@4.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-4.0.5.tgz",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/webpack-env": {
|
"@types/webpack-env": {
|
||||||
"version": "1.13.0",
|
"version": "1.13.0",
|
||||||
"from": "@types/webpack-env@1.13.0",
|
"from": "@types/webpack-env@1.13.0",
|
||||||
@@ -155,15 +167,15 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"aspnet-webpack": {
|
"aspnet-webpack": {
|
||||||
"version": "1.0.29",
|
"version": "2.0.1",
|
||||||
"from": "aspnet-webpack@>=1.0.29 <2.0.0",
|
"from": "aspnet-webpack@2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-1.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-2.0.1.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"aspnet-webpack-react": {
|
"aspnet-webpack-react": {
|
||||||
"version": "3.0.0-beta.1",
|
"version": "3.0.0",
|
||||||
"from": "aspnet-webpack-react@>=3.0.0-beta <4.0.0",
|
"from": "aspnet-webpack-react@3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/aspnet-webpack-react/-/aspnet-webpack-react-3.0.0-beta.1.tgz",
|
"resolved": "https://registry.npmjs.org/aspnet-webpack-react/-/aspnet-webpack-react-3.0.0.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"assert": {
|
"assert": {
|
||||||
|
|||||||
@@ -6,10 +6,12 @@
|
|||||||
"@types/history": "4.6.0",
|
"@types/history": "4.6.0",
|
||||||
"@types/react": "15.0.35",
|
"@types/react": "15.0.35",
|
||||||
"@types/react-dom": "15.5.1",
|
"@types/react-dom": "15.5.1",
|
||||||
|
"@types/react-hot-loader": "3.0.3",
|
||||||
"@types/react-router": "4.0.12",
|
"@types/react-router": "4.0.12",
|
||||||
|
"@types/react-router-dom": "4.0.5",
|
||||||
"@types/webpack-env": "1.13.0",
|
"@types/webpack-env": "1.13.0",
|
||||||
"aspnet-webpack": "^1.0.29",
|
"aspnet-webpack": "^2.0.1",
|
||||||
"aspnet-webpack-react": "^3.0.0-beta",
|
"aspnet-webpack-react": "^3.0.0",
|
||||||
"awesome-typescript-loader": "3.2.1",
|
"awesome-typescript-loader": "3.2.1",
|
||||||
"bootstrap": "3.3.7",
|
"bootstrap": "3.3.7",
|
||||||
"css-loader": "0.28.4",
|
"css-loader": "0.28.4",
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
"module": "es2015",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"skipDefaultLibCheck": true,
|
"skipDefaultLibCheck": true,
|
||||||
"types": [ "webpack-env" ],
|
"strict": true,
|
||||||
"paths": {
|
"types": ["webpack-env"]
|
||||||
// Fix "Duplicate identifier" errors caused by multiple dependencies fetching their own copies of type definitions.
|
|
||||||
// We tell TypeScript which type definitions module to treat as the canonical one (instead of combining all of them).
|
|
||||||
"history": ["./node_modules/@types/history/index"],
|
|
||||||
"react": ["./node_modules/@types/react/index"]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"bin",
|
"bin",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ module.exports = (env) => {
|
|||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, bundleOutputDir),
|
path: path.join(__dirname, bundleOutputDir),
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
publicPath: '/dist/'
|
publicPath: 'dist/'
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ module.exports = (env) => {
|
|||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'wwwroot', 'dist'),
|
path: path.join(__dirname, 'wwwroot', 'dist'),
|
||||||
publicPath: '/dist/',
|
publicPath: 'dist/',
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
library: '[name]_[hash]',
|
library: '[name]_[hash]',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export default class FetchDataComponent extends Vue {
|
|||||||
forecasts: WeatherForecast[] = [];
|
forecasts: WeatherForecast[] = [];
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
fetch('/api/SampleData/WeatherForecasts')
|
fetch('api/SampleData/WeatherForecasts')
|
||||||
.then(response => response.json() as Promise<WeatherForecast[]>)
|
.then(response => response.json() as Promise<WeatherForecast[]>)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
this.forecasts = data;
|
this.forecasts = data;
|
||||||
|
|||||||
@@ -9,17 +9,17 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0-rtm-26190" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||||
</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>
|
||||||
|
|
||||||
<!--/-:cnd:noEmit -->
|
<!--/-:cnd:noEmit -->
|
||||||
|
|||||||
14
templates/VueSpa/npm-shrinkwrap.json
generated
14
templates/VueSpa/npm-shrinkwrap.json
generated
@@ -2,10 +2,10 @@
|
|||||||
"name": "WebApplicationBasic",
|
"name": "WebApplicationBasic",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/requirejs": {
|
"@types/webpack-env": {
|
||||||
"version": "2.1.29",
|
"version": "1.13.0",
|
||||||
"from": "@types/requirejs@>=2.1.28 <3.0.0",
|
"from": "@types/webpack-env@>=1.13.0 <2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/requirejs/-/requirejs-2.1.29.tgz",
|
"resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.13.0.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"abbrev": {
|
"abbrev": {
|
||||||
@@ -119,9 +119,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"aspnet-webpack": {
|
"aspnet-webpack": {
|
||||||
"version": "1.0.29",
|
"version": "2.0.1",
|
||||||
"from": "aspnet-webpack@>=1.0.27 <2.0.0",
|
"from": "aspnet-webpack@2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-1.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/aspnet-webpack/-/aspnet-webpack-2.0.1.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"assert": {
|
"assert": {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/requirejs": "^2.1.28",
|
"@types/webpack-env": "^1.13.0",
|
||||||
"aspnet-webpack": "^1.0.27",
|
"aspnet-webpack": "^2.0.1",
|
||||||
"awesome-typescript-loader": "^3.0.0",
|
"awesome-typescript-loader": "^3.0.0",
|
||||||
"bootstrap": "^3.3.6",
|
"bootstrap": "^3.3.6",
|
||||||
"css-loader": "^0.25.0",
|
"css-loader": "^0.25.0",
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
"target": "es5",
|
"target": "es5",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"skipDefaultLibCheck": true,
|
"skipDefaultLibCheck": true,
|
||||||
"types": ["requirejs"]
|
"strict": true,
|
||||||
|
"types": ["webpack-env"]
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"bin",
|
"bin",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ module.exports = (env) => {
|
|||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, bundleOutputDir),
|
path: path.join(__dirname, bundleOutputDir),
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
publicPath: '/dist/'
|
publicPath: 'dist/'
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new CheckerPlugin(),
|
new CheckerPlugin(),
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ module.exports = (env) => {
|
|||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'wwwroot', 'dist'),
|
path: path.join(__dirname, 'wwwroot', 'dist'),
|
||||||
publicPath: '/dist/',
|
publicPath: 'dist/',
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
library: '[name]_[hash]'
|
library: '[name]_[hash]'
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -91,20 +91,13 @@ 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 {
|
function getBuildNumber(): string {
|
||||||
if (process.env.APPVEYOR_BUILD_NUMBER) {
|
if (process.env.APPVEYOR_BUILD_NUMBER) {
|
||||||
return leftPad(process.env.APPVEYOR_BUILD_NUMBER, 6, '0');
|
return process.env.APPVEYOR_BUILD_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For local builds, use timestamp
|
// For local builds, use timestamp
|
||||||
return 't-' + Math.floor((new Date().valueOf() - new Date(2017, 0, 1).valueOf()) / (60*1000));
|
return Math.floor((new Date().valueOf() - new Date(2017, 0, 1).valueOf()) / (60*1000)) + '-local';
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildYeomanNpmPackage(outputRoot: string) {
|
function buildYeomanNpmPackage(outputRoot: string) {
|
||||||
@@ -206,10 +199,23 @@ function buildDotNetNewNuGetPackage(packageId: string) {
|
|||||||
HostIdentifier: {
|
HostIdentifier: {
|
||||||
type: 'bind',
|
type: 'bind',
|
||||||
binding: 'HostIdentifier'
|
binding: 'HostIdentifier'
|
||||||
|
},
|
||||||
|
skipRestore: {
|
||||||
|
type: 'parameter',
|
||||||
|
datatype: 'bool',
|
||||||
|
description: 'If specified, skips the automatic restore of the project on create.',
|
||||||
|
defaultValue: 'false'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tags: { language: 'C#', type: 'project' },
|
tags: { language: 'C#', type: 'project' },
|
||||||
postActions: [
|
postActions: [
|
||||||
|
{
|
||||||
|
condition: '(!skipRestore)',
|
||||||
|
description: 'Restore 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
|
// Currently it doesn't appear to be possible to run `npm install` from a
|
||||||
// postAction, due to https://github.com/dotnet/templating/issues/849
|
// postAction, due to https://github.com/dotnet/templating/issues/849
|
||||||
@@ -245,7 +251,11 @@ function buildDotNetNewNuGetPackage(packageId: string) {
|
|||||||
},
|
},
|
||||||
Framework: {
|
Framework: {
|
||||||
longName: 'framework'
|
longName: 'framework'
|
||||||
}
|
},
|
||||||
|
skipRestore: {
|
||||||
|
longName: 'no-restore',
|
||||||
|
shortName: ''
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}, null, 2));
|
}, null, 2));
|
||||||
|
|
||||||
|
|||||||
@@ -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.DotNet.Web.Spa.ProjectTemplates</id>
|
<id>Microsoft.DotNet.Web.Spa.ProjectTemplates</id>
|
||||||
<version>1.0.0-preview-{buildnumber}</version>
|
<version>1.0.{buildnumber}</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>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user