mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-23 10:08:57 +00:00
Compare commits
2 Commits
httpwithst
...
fix-angula
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ed1a35ce0 | ||
|
|
287c10fd2e |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -40,5 +40,3 @@ npm-debug.log
|
||||
.vscode/
|
||||
|
||||
/templates/*/Properties/launchSettings.json
|
||||
global.json
|
||||
korebuild-lock.txt
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<clear />
|
||||
<add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json" />
|
||||
<add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-ci-release/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>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
init:
|
||||
init:
|
||||
- git config --global core.autocrlf true
|
||||
install:
|
||||
- ps: Install-Product node 6.9.2 x64
|
||||
@@ -25,10 +25,6 @@ artifacts:
|
||||
type: NuGetPackage
|
||||
# - ps: .\build.ps1
|
||||
clone_depth: 1
|
||||
environment:
|
||||
global:
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
test_script:
|
||||
- dotnet restore
|
||||
- ps: Push-Location
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
@ECHO OFF
|
||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE"
|
||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE"
|
||||
218
build.ps1
218
build.ps1
@@ -1,177 +1,67 @@
|
||||
#!/usr/bin/env powershell
|
||||
#requires -version 4
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Build this repository
|
||||
function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries)
|
||||
{
|
||||
while($true)
|
||||
{
|
||||
try
|
||||
{
|
||||
Invoke-WebRequest $url -OutFile $downloadLocation
|
||||
break
|
||||
}
|
||||
catch
|
||||
{
|
||||
$exceptionMessage = $_.Exception.Message
|
||||
Write-Host "Failed to download '$url': $exceptionMessage"
|
||||
if ($retries -gt 0) {
|
||||
$retries--
|
||||
Write-Host "Waiting 10 seconds before retrying. Retries left: $retries"
|
||||
Start-Sleep -Seconds 10
|
||||
|
||||
.DESCRIPTION
|
||||
Downloads korebuild if required. Then builds the repository.
|
||||
|
||||
.PARAMETER Path
|
||||
The folder to build. Defaults to the folder containing this script.
|
||||
|
||||
.PARAMETER Channel
|
||||
The channel of KoreBuild to download. Overrides the value from the config file.
|
||||
|
||||
.PARAMETER DotNetHome
|
||||
The directory where .NET Core tools will be stored.
|
||||
|
||||
.PARAMETER ToolsSource
|
||||
The base url where build tools can be downloaded. Overrides the value from the config file.
|
||||
|
||||
.PARAMETER Update
|
||||
Updates KoreBuild to the latest version even if a lock file is present.
|
||||
|
||||
.PARAMETER ConfigFile
|
||||
The path to the configuration file that stores values. Defaults to version.xml.
|
||||
|
||||
.PARAMETER MSBuildArgs
|
||||
Arguments to be passed to MSBuild
|
||||
|
||||
.NOTES
|
||||
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.
|
||||
|
||||
The $ConfigFile is expected to be an XML file. It is optional, and the configuration values in it are optional as well.
|
||||
|
||||
.EXAMPLE
|
||||
Example config file:
|
||||
```xml
|
||||
<!-- version.xml -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<KoreBuildChannel>dev</KoreBuildChannel>
|
||||
<KoreBuildToolsSource>https://aspnetcore.blob.core.windows.net/buildtools</KoreBuildToolsSource>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
```
|
||||
#>
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param(
|
||||
[string]$Path = $PSScriptRoot,
|
||||
[Alias('c')]
|
||||
[string]$Channel,
|
||||
[Alias('d')]
|
||||
[string]$DotNetHome,
|
||||
[Alias('s')]
|
||||
[string]$ToolsSource,
|
||||
[Alias('u')]
|
||||
[switch]$Update,
|
||||
[string]$ConfigFile = (Join-Path $PSScriptRoot 'version.xml'),
|
||||
[Parameter(ValueFromRemainingArguments = $true)]
|
||||
[string[]]$MSBuildArgs
|
||||
)
|
||||
|
||||
Set-StrictMode -Version 2
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
|
||||
function Get-KoreBuild {
|
||||
|
||||
$lockFile = Join-Path $Path 'korebuild-lock.txt'
|
||||
|
||||
if (!(Test-Path $lockFile) -or $Update) {
|
||||
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile
|
||||
}
|
||||
|
||||
$version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
|
||||
if (!$version) {
|
||||
Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'"
|
||||
}
|
||||
$version = $version.TrimStart('version:').Trim()
|
||||
$korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version)
|
||||
|
||||
if (!(Test-Path $korebuildPath)) {
|
||||
Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version"
|
||||
New-Item -ItemType Directory -Path $korebuildPath | Out-Null
|
||||
$remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip"
|
||||
|
||||
try {
|
||||
$tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
|
||||
Get-RemoteFile $remotePath $tmpfile
|
||||
if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) {
|
||||
# Use built-in commands where possible as they are cross-plat compatible
|
||||
Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
|
||||
}
|
||||
else {
|
||||
# Fallback to old approach for old installations of PowerShell
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath)
|
||||
else
|
||||
{
|
||||
$exception = $_.Exception
|
||||
throw $exception
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore
|
||||
throw
|
||||
}
|
||||
finally {
|
||||
Remove-Item $tmpfile -ErrorAction Ignore
|
||||
}
|
||||
}
|
||||
|
||||
return $korebuildPath
|
||||
}
|
||||
|
||||
function Join-Paths([string]$path, [string[]]$childPaths) {
|
||||
$childPaths | ForEach-Object { $path = Join-Path $path $_ }
|
||||
return $path
|
||||
cd $PSScriptRoot
|
||||
|
||||
$repoFolder = $PSScriptRoot
|
||||
$env:REPO_FOLDER = $repoFolder
|
||||
|
||||
$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0.zip"
|
||||
if ($env:KOREBUILD_ZIP)
|
||||
{
|
||||
$koreBuildZip=$env:KOREBUILD_ZIP
|
||||
}
|
||||
|
||||
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
|
||||
if ($RemotePath -notlike 'http*') {
|
||||
Copy-Item $RemotePath $LocalPath
|
||||
return
|
||||
$buildFolder = ".build"
|
||||
$buildFile="$buildFolder\KoreBuild.ps1"
|
||||
|
||||
if (!(Test-Path $buildFolder)) {
|
||||
Write-Host "Downloading KoreBuild from $koreBuildZip"
|
||||
|
||||
$tempFolder=$env:TEMP + "\KoreBuild-" + [guid]::NewGuid()
|
||||
New-Item -Path "$tempFolder" -Type directory | Out-Null
|
||||
|
||||
$localZipFile="$tempFolder\korebuild.zip"
|
||||
|
||||
DownloadWithRetry -url $koreBuildZip -downloadLocation $localZipFile -retries 6
|
||||
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder)
|
||||
|
||||
New-Item -Path "$buildFolder" -Type directory | Out-Null
|
||||
copy-item "$tempFolder\**\build\*" $buildFolder -Recurse
|
||||
|
||||
# Cleanup
|
||||
if (Test-Path $tempFolder) {
|
||||
Remove-Item -Recurse -Force $tempFolder
|
||||
}
|
||||
|
||||
$retries = 10
|
||||
while ($retries -gt 0) {
|
||||
$retries -= 1
|
||||
try {
|
||||
Invoke-WebRequest -UseBasicParsing -Uri $RemotePath -OutFile $LocalPath
|
||||
return
|
||||
}
|
||||
catch {
|
||||
Write-Verbose "Request failed. $retries retries remaining"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Error "Download failed: '$RemotePath'."
|
||||
}
|
||||
|
||||
#
|
||||
# Main
|
||||
#
|
||||
|
||||
# Load configuration or set defaults
|
||||
|
||||
if (Test-Path $ConfigFile) {
|
||||
[xml] $config = Get-Content $ConfigFile
|
||||
if (!($Channel)) { [string] $Channel = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildChannel' }
|
||||
if (!($ToolsSource)) { [string] $ToolsSource = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildToolsSource' }
|
||||
}
|
||||
|
||||
if (!$DotNetHome) {
|
||||
$DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } `
|
||||
elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} `
|
||||
elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}`
|
||||
else { Join-Path $PSScriptRoot '.dotnet'}
|
||||
}
|
||||
|
||||
if (!$Channel) { $Channel = 'dev' }
|
||||
if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' }
|
||||
|
||||
# Execute
|
||||
|
||||
$korebuildPath = Get-KoreBuild
|
||||
Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1')
|
||||
|
||||
try {
|
||||
Install-Tools $ToolsSource $DotNetHome
|
||||
Invoke-RepositoryBuild $Path @MSBuildArgs
|
||||
}
|
||||
finally {
|
||||
Remove-Module 'KoreBuild' -ErrorAction Ignore
|
||||
}
|
||||
&"$buildFile" @args
|
||||
|
||||
213
build.sh
213
build.sh
@@ -1,197 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd $repoFolder
|
||||
|
||||
set -euo pipefail
|
||||
koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0.zip"
|
||||
if [ ! -z $KOREBUILD_ZIP ]; then
|
||||
koreBuildZip=$KOREBUILD_ZIP
|
||||
fi
|
||||
|
||||
#
|
||||
# variables
|
||||
#
|
||||
buildFolder=".build"
|
||||
buildFile="$buildFolder/KoreBuild.sh"
|
||||
|
||||
RESET="\033[0m"
|
||||
RED="\033[0;31m"
|
||||
MAGENTA="\033[0;95m"
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet"
|
||||
config_file="$DIR/version.xml"
|
||||
verbose=false
|
||||
update=false
|
||||
repo_path="$DIR"
|
||||
channel=''
|
||||
tools_source=''
|
||||
if test ! -d $buildFolder; then
|
||||
echo "Downloading KoreBuild from $koreBuildZip"
|
||||
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
__usage() {
|
||||
echo "Usage: $(basename "${BASH_SOURCE[0]}") [options] [[--] <MSBUILD_ARG>...]"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " <MSBUILD_ARG>... Arguments passed to MSBuild. Variable number of arguments allowed."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --verbose Show verbose output."
|
||||
echo " -c|--channel <CHANNEL> The channel of KoreBuild to download. Overrides the value from the config file.."
|
||||
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 " --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 " -u|--update Update to the latest KoreBuild even if the lock file is present."
|
||||
echo ""
|
||||
echo "Description:"
|
||||
echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be."
|
||||
echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel."
|
||||
tempFolder="/tmp/KoreBuild-$(uuidgen)"
|
||||
mkdir $tempFolder
|
||||
|
||||
if [[ "${1:-}" != '--no-exit' ]]; then
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
localZipFile="$tempFolder/korebuild.zip"
|
||||
|
||||
get_korebuild() {
|
||||
local version
|
||||
local lock_file="$repo_path/korebuild-lock.txt"
|
||||
if [ ! -f "$lock_file" ] || [ "$update" = true ]; then
|
||||
__get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file"
|
||||
fi
|
||||
version="$(grep 'version:*' -m 1 "$lock_file")"
|
||||
if [[ "$version" == '' ]]; then
|
||||
__error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'"
|
||||
return 1
|
||||
fi
|
||||
version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
|
||||
local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version"
|
||||
|
||||
{
|
||||
if [ ! -d "$korebuild_path" ]; then
|
||||
mkdir -p "$korebuild_path"
|
||||
local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip"
|
||||
tmpfile="$(mktemp)"
|
||||
echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}"
|
||||
if __get_remote_file "$remote_path" "$tmpfile"; then
|
||||
unzip -q -d "$korebuild_path" "$tmpfile"
|
||||
fi
|
||||
rm "$tmpfile" || true
|
||||
retries=6
|
||||
until (wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip 2>/dev/null)
|
||||
do
|
||||
echo "Failed to download '$koreBuildZip'"
|
||||
if [ "$retries" -le 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
echo "Waiting 10 seconds before retrying. Retries left: $retries"
|
||||
sleep 10s
|
||||
done
|
||||
|
||||
source "$korebuild_path/KoreBuild.sh"
|
||||
} || {
|
||||
if [ -d "$korebuild_path" ]; then
|
||||
echo "Cleaning up after failed installation"
|
||||
rm -rf "$korebuild_path" || true
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
}
|
||||
unzip -q -d $tempFolder $localZipFile
|
||||
|
||||
__error() {
|
||||
echo -e "${RED}$*${RESET}" 1>&2
|
||||
}
|
||||
mkdir $buildFolder
|
||||
cp -r $tempFolder/**/build/** $buildFolder
|
||||
|
||||
__machine_has() {
|
||||
hash "$1" > /dev/null 2>&1
|
||||
return $?
|
||||
}
|
||||
chmod +x $buildFile
|
||||
|
||||
__get_remote_file() {
|
||||
local remote_path=$1
|
||||
local local_path=$2
|
||||
|
||||
if [[ "$remote_path" != 'http'* ]]; then
|
||||
cp "$remote_path" "$local_path"
|
||||
return 0
|
||||
# Cleanup
|
||||
if test -d $tempFolder; then
|
||||
rm -rf $tempFolder
|
||||
fi
|
||||
|
||||
failed=false
|
||||
if __machine_has wget; then
|
||||
wget --tries 10 --quiet -O "$local_path" "$remote_path" || failed=true
|
||||
fi
|
||||
|
||||
if [ "$failed" = true ] && __machine_has curl; then
|
||||
failed=false
|
||||
curl --retry 10 -sSL -f --create-dirs -o "$local_path" "$remote_path" || failed=true
|
||||
fi
|
||||
|
||||
if [ "$failed" = true ]; then
|
||||
__error "Download failed: $remote_path" 1>&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
__read_dom () { local IFS=\> ; read -r -d \< ENTITY CONTENT ;}
|
||||
|
||||
#
|
||||
# main
|
||||
#
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-\?|-h|--help)
|
||||
__usage --no-exit
|
||||
exit 0
|
||||
;;
|
||||
-c|--channel|-Channel)
|
||||
shift
|
||||
channel="${1:-}"
|
||||
[ -z "$channel" ] && __usage
|
||||
;;
|
||||
--config-file|-ConfigFile)
|
||||
shift
|
||||
config_file="${1:-}"
|
||||
[ -z "$config_file" ] && __usage
|
||||
;;
|
||||
-d|--dotnet-home|-DotNetHome)
|
||||
shift
|
||||
DOTNET_HOME="${1:-}"
|
||||
[ -z "$DOTNET_HOME" ] && __usage
|
||||
;;
|
||||
--path|-Path)
|
||||
shift
|
||||
repo_path="${1:-}"
|
||||
[ -z "$repo_path" ] && __usage
|
||||
;;
|
||||
-s|--tools-source|-ToolsSource)
|
||||
shift
|
||||
tools_source="${1:-}"
|
||||
[ -z "$tools_source" ] && __usage
|
||||
;;
|
||||
-u|--update|-Update)
|
||||
update=true
|
||||
;;
|
||||
--verbose|-Verbose)
|
||||
verbose=true
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if ! __machine_has unzip; then
|
||||
__error 'Missing required command: unzip'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! __machine_has curl && ! __machine_has wget; then
|
||||
__error 'Missing required command. Either wget or curl is required.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "$config_file" ]; then
|
||||
comment=false
|
||||
while __read_dom; do
|
||||
if [ "$comment" = true ]; then [[ $CONTENT == *'-->'* ]] && comment=false ; continue; fi
|
||||
if [[ $ENTITY == '!--'* ]]; then comment=true; continue; fi
|
||||
if [ -z "$channel" ] && [[ $ENTITY == "KoreBuildChannel" ]]; then channel=$CONTENT; fi
|
||||
if [ -z "$tools_source" ] && [[ $ENTITY == "KoreBuildToolsSource" ]]; then tools_source=$CONTENT; fi
|
||||
done < "$config_file"
|
||||
fi
|
||||
|
||||
[ -z "$channel" ] && channel='dev'
|
||||
[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools'
|
||||
|
||||
get_korebuild
|
||||
install_tools "$tools_source" "$DOTNET_HOME"
|
||||
invoke_repository_build "$repo_path" "$@"
|
||||
$buildFile -r $repoFolder "$@"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<Import Project="dependencies.props" />
|
||||
<Import Project="..\version.xml" />
|
||||
<Import Project="..\version.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<Product>Microsoft ASP.NET Core</Product>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<AspNetCoreVersion>2.1.0-*</AspNetCoreVersion>
|
||||
<InternalAspNetCoreSdkVersion>2.1.1-*</InternalAspNetCoreSdkVersion>
|
||||
<AspNetCoreVersion>2.0.0-*</AspNetCoreVersion>
|
||||
<AutoMapperVersion>5.0.2</AutoMapperVersion>
|
||||
<InternalAspNetCoreSdkVersion>2.0.1-*</InternalAspNetCoreSdkVersion>
|
||||
<JsonNetVersion>10.0.1</JsonNetVersion>
|
||||
<NETStandardImplicitPackageVersion>2.0.0-*</NETStandardImplicitPackageVersion>
|
||||
<NETStandardLibraryNETFrameworkVersion>2.0.0-*</NETStandardLibraryNETFrameworkVersion>
|
||||
|
||||
@@ -50,7 +50,6 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
||||
options.DebuggingPort)
|
||||
{
|
||||
_client = new HttpClient();
|
||||
_client.Timeout = TimeSpan.FromMilliseconds(options.InvocationTimeoutMilliseconds + 1000);
|
||||
}
|
||||
|
||||
private static string MakeCommandLineOptions(int port)
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Threading;
|
||||
using Microsoft.AspNetCore.NodeServices;
|
||||
using Microsoft.AspNetCore.SpaServices.Webpack;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
@@ -88,7 +87,7 @@ namespace Microsoft.AspNetCore.Builder
|
||||
};
|
||||
var devServerInfo =
|
||||
nodeServices.InvokeExportAsync<WebpackDevServerInfo>(nodeScript.FileName, "createWebpackDevServer",
|
||||
JsonConvert.SerializeObject(devServerOptions, new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() })).Result;
|
||||
JsonConvert.SerializeObject(devServerOptions)).Result;
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
/node_modules/
|
||||
**/*.js
|
||||
**/*.d.ts
|
||||
**/*.metadata.json
|
||||
/compiled
|
||||
@@ -1,3 +0,0 @@
|
||||
!/*.js
|
||||
!/*.d.ts
|
||||
/compiled
|
||||
@@ -1,12 +0,0 @@
|
||||
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.
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
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 {
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export * from './HttpWithStateTransfer';
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpModule } from '@angular/http';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { HttpWithStateTransferModule } from 'aspnet-angular';
|
||||
|
||||
import { AppComponent } from './components/app/app.component';
|
||||
import { NavMenuComponent } from './components/navmenu/navmenu.component';
|
||||
@@ -22,7 +21,6 @@ import { CounterComponent } from './components/counter/counter.component';
|
||||
imports: [
|
||||
CommonModule,
|
||||
HttpModule,
|
||||
HttpWithStateTransferModule,
|
||||
FormsModule,
|
||||
RouterModule.forRoot([
|
||||
{ path: '', redirectTo: 'home', pathMatch: 'full' },
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { HttpWithStateTransfer } from 'aspnet-angular';
|
||||
import { Http } from '@angular/http';
|
||||
|
||||
@Component({
|
||||
selector: 'fetchdata',
|
||||
@@ -8,7 +8,7 @@ import { HttpWithStateTransfer } from 'aspnet-angular';
|
||||
export class FetchDataComponent {
|
||||
public forecasts: WeatherForecast[];
|
||||
|
||||
constructor(http: HttpWithStateTransfer, @Inject('BASE_URL') baseUrl: string) {
|
||||
constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
|
||||
http.get(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
|
||||
this.forecasts = result.json() as WeatherForecast[];
|
||||
}, 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>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>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>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>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>
|
||||
|
||||
@@ -6,7 +6,6 @@ import { enableProdMode, ApplicationRef, NgZone, ValueProvider } from '@angular/
|
||||
import { platformDynamicServer, PlatformState, INITIAL_CONFIG } from '@angular/platform-server';
|
||||
import { createServerRenderer, RenderResult } from 'aspnet-prerendering';
|
||||
import { AppModule } from './app/app.module.server';
|
||||
import { HttpWithStateTransfer } from 'aspnet-angular';
|
||||
|
||||
enableProdMode();
|
||||
|
||||
@@ -21,7 +20,6 @@ export default createServerRenderer(params => {
|
||||
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||
const state = moduleRef.injector.get(PlatformState);
|
||||
const zone = moduleRef.injector.get(NgZone);
|
||||
const http: HttpWithStateTransfer = moduleRef.injector.get(HttpWithStateTransfer);
|
||||
|
||||
return new Promise<RenderResult>((resolve, reject) => {
|
||||
zone.onError.subscribe((errorInfo: any) => reject(errorInfo));
|
||||
@@ -30,8 +28,7 @@ export default createServerRenderer(params => {
|
||||
// completing the request in case there's an error to report
|
||||
setImmediate(() => {
|
||||
resolve({
|
||||
html: state.renderToString(),
|
||||
globals: { ...http.stateForTransfer() }
|
||||
html: state.renderToString()
|
||||
});
|
||||
moduleRef.destroy();
|
||||
});
|
||||
|
||||
5
templates/AngularSpa/npm-shrinkwrap.json
generated
5
templates/AngularSpa/npm-shrinkwrap.json
generated
@@ -273,11 +273,6 @@
|
||||
"from": "asn1.js@>=4.0.0 <5.0.0",
|
||||
"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": {
|
||||
"version": "3.0.1",
|
||||
"from": "aspnet-prerendering@3.0.1",
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
"@ngtools/webpack": "1.5.0",
|
||||
"@types/webpack-env": "1.13.0",
|
||||
"angular2-template-loader": "0.6.2",
|
||||
"aspnet-angular": "^0.1.1",
|
||||
"aspnet-prerendering": "^3.0.1",
|
||||
"aspnet-webpack": "^2.0.1",
|
||||
"awesome-typescript-loader": "3.2.1",
|
||||
|
||||
@@ -17,7 +17,7 @@ module.exports = (env) => {
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.ts$/, include: /ClientApp/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader'] : '@ngtools/webpack' },
|
||||
{ test: /\.ts$/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader'] : '@ngtools/webpack' },
|
||||
{ test: /\.html$/, use: 'html-loader?minimize=false' },
|
||||
{ test: /\.css$/, use: [ 'to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] },
|
||||
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "generator-aspnetcore-spa",
|
||||
"version": "0.9.4",
|
||||
"version": "1.0.0",
|
||||
"description": "Single-Page App templates for ASP.NET Core",
|
||||
"author": "Microsoft",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
7
version.props
Normal file
7
version.props
Normal file
@@ -0,0 +1,7 @@
|
||||
<!-- This file may be overwritten by automation. Only values allowed here are VersionPrefix and VersionSuffix. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>2.0.0</VersionPrefix>
|
||||
<VersionSuffix>rtm</VersionSuffix>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,8 +0,0 @@
|
||||
<!-- This file may be overwritten by automation. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<KoreBuildChannel>dev</KoreBuildChannel>
|
||||
<VersionPrefix>2.1.0</VersionPrefix>
|
||||
<VersionSuffix>preview1</VersionSuffix>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user