Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

Commit 2df0feb

Browse files
Merge branch 'rel/2.0.0-templates' into dev
2 parents b434eef + e65eceb commit 2df0feb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+152
-111
lines changed

src/Microsoft.AspNetCore.SpaServices/npm/aspnet-prerendering/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aspnet-prerendering",
3-
"version": "2.0.6",
3+
"version": "3.0.1",
44
"description": "Helpers for server-side rendering of JavaScript applications in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
55
"main": "index.js",
66
"scripts": {
@@ -17,7 +17,7 @@
1717
"url": "https://github.com/aspnet/JavaScriptServices.git"
1818
},
1919
"dependencies": {
20-
"domain-task": "^2.0.2"
20+
"domain-task": "^3.0.0"
2121
},
2222
"devDependencies": {
2323
"@types/node": "^6.0.42",

src/Microsoft.AspNetCore.SpaServices/npm/aspnet-prerendering/src/Prerendering.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export function createServerRenderer(bootFunc: BootFunc): RenderToStringFunc {
2626
domainTasks: domainTaskCompletionPromise,
2727
data: customDataParameter
2828
};
29+
const absoluteBaseUrl = params.origin + params.baseUrl; // Should be same value as page's <base href>
2930

3031
// Open a new domain that can track all the async tasks involved in the app's execution
3132
domainTaskRun(/* code to run */ () => {
@@ -35,7 +36,7 @@ export function createServerRenderer(bootFunc: BootFunc): RenderToStringFunc {
3536
bindPromiseContinuationsToDomain(domainTaskCompletionPromise, domain['active']);
3637

3738
// Make the base URL available to the 'domain-tasks/fetch' helper within this execution context
38-
domainTaskBaseUrl(absoluteRequestUrl);
39+
domainTaskBaseUrl(absoluteBaseUrl);
3940

4041
// Begin rendering, and apply a timeout
4142
const bootFuncPromise = bootFunc(params);

src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack-react/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aspnet-webpack-react",
3-
"version": "3.0.0-beta.1",
3+
"version": "3.0.0",
44
"description": "Helpers for using Webpack with React in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
55
"main": "index.js",
66
"scripts": {

src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aspnet-webpack",
3-
"version": "1.0.29",
3+
"version": "2.0.0",
44
"description": "Helpers for using Webpack in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
55
"main": "index.js",
66
"scripts": {

src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/WebpackDevMiddleware.ts

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ function attachWebpackDevMiddleware(app: any, webpackConfig: webpack.Configurati
108108
const compiler = webpack(webpackConfig);
109109
app.use(require('webpack-dev-middleware')(compiler, {
110110
noInfo: true,
111-
publicPath: webpackConfig.output.publicPath,
111+
publicPath: ensureLeadingSlash(webpackConfig.output.publicPath),
112112
watchOptions: webpackConfig.watchOptions
113113
}));
114114

@@ -195,6 +195,14 @@ function copyRecursiveToRealFsSync(from: typeof fs, rootDir: string, exclude: Re
195195
});
196196
}
197197

198+
function ensureLeadingSlash(value: string) {
199+
if (value !== null && value.substring(0, 1) !== '/') {
200+
value = '/' + value;
201+
}
202+
203+
return value;
204+
}
205+
198206
function pathJoinSafe(rootPath: string, filePath: string) {
199207
// On Windows, MemoryFileSystem's readdirSync output produces directory entries like 'C:'
200208
// which then trigger errors if you call statSync for them. Avoid this by detecting drive
@@ -257,22 +265,32 @@ export function createWebpackDevServer(callback: CreateDevServerCallback, option
257265
if (!publicPath) {
258266
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)');
259267
}
260-
normalizedPublicPaths.push(removeTrailingSlash(publicPath));
261-
262-
// Newer versions of Microsoft.AspNetCore.SpaServices will explicitly pass an HMR endpoint URL
263-
// (because it's relative to the app's URL space root, which the client doesn't otherwise know).
264-
// For back-compatibility, fall back on connecting directly to the underlying HMR server (though
265-
// that won't work if the app is hosted on HTTPS because of the mixed-content rule, and we can't
266-
// run the HMR server itself on HTTPS because in general it has no valid cert).
267-
const hmrClientEndpoint = options.hotModuleReplacementEndpointUrl // The URL that we'll proxy (e.g., /__asp_webpack_hmr)
268-
|| `http://localhost:${listener.address().port}/__webpack_hmr`; // Fall back on absolute URL to bypass proxying
269-
const hmrServerEndpoint = options.hotModuleReplacementEndpointUrl
270-
|| '/__webpack_hmr'; // URL is relative to webpack dev server root
268+
const publicPathNoTrailingSlash = removeTrailingSlash(publicPath);
269+
normalizedPublicPaths.push(publicPathNoTrailingSlash);
270+
271+
// This is the URL the client will connect to, except that since it's a relative URL
272+
// (no leading slash), Webpack will resolve it against the runtime <base href> URL
273+
// plus it also adds the publicPath
274+
const hmrClientEndpoint = removeLeadingSlash(options.hotModuleReplacementEndpointUrl);
275+
276+
// This is the URL inside the Webpack middleware Node server that we'll proxy to.
277+
// We have to prefix with the public path because Webpack will add the publicPath
278+
// when it resolves hmrClientEndpoint as a relative URL.
279+
const hmrServerEndpoint = ensureLeadingSlash(publicPathNoTrailingSlash + options.hotModuleReplacementEndpointUrl);
271280

272281
// We always overwrite the 'path' option as it needs to match what the .NET side is expecting
273282
const hmrClientOptions = options.suppliedOptions.HotModuleReplacementClientOptions || <StringMap<string>>{};
274283
hmrClientOptions['path'] = hmrClientEndpoint;
275284

285+
const dynamicPublicPathKey = 'dynamicPublicPath';
286+
if (!(dynamicPublicPathKey in hmrClientOptions)) {
287+
// dynamicPublicPath default to true, so we can work with nonempty pathbases (virtual directories)
288+
hmrClientOptions[dynamicPublicPathKey] = true;
289+
} else {
290+
// ... but you can set it to any other value explicitly if you want (e.g., false)
291+
hmrClientOptions[dynamicPublicPathKey] = JSON.parse(hmrClientOptions[dynamicPublicPathKey]);
292+
}
293+
276294
attachWebpackDevMiddleware(app, webpackConfig, enableHotModuleReplacement, enableReactHotModuleReplacement, hmrClientOptions, hmrServerEndpoint);
277295
}
278296
});
@@ -292,6 +310,14 @@ export function createWebpackDevServer(callback: CreateDevServerCallback, option
292310
});
293311
}
294312

313+
function removeLeadingSlash(str: string) {
314+
if (str.indexOf('/') === 0) {
315+
str = str.substring(1);
316+
}
317+
318+
return str;
319+
}
320+
295321
function removeTrailingSlash(str: string) {
296322
if (str.lastIndexOf('/') === str.length - 1) {
297323
str = str.substring(0, str.length - 1);

templates/AngularSpa/ClientApp/app/app.module.browser.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import { AppComponent } from './components/app/app.component';
1010
AppModuleShared
1111
],
1212
providers: [
13-
{ provide: 'ORIGIN_URL', useFactory: getOriginUrl }
13+
{ provide: 'BASE_URL', useFactory: getBaseUrl }
1414
]
1515
})
1616
export class AppModule {
1717
}
1818

19-
export function getOriginUrl() {
20-
return location.origin;
19+
export function getBaseUrl() {
20+
return document.getElementsByTagName('base')[0].href;
2121
}

templates/AngularSpa/ClientApp/app/components/fetchdata/fetchdata.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { Http } from '@angular/http';
88
export class FetchDataComponent {
99
public forecasts: WeatherForecast[];
1010

11-
constructor(http: Http, @Inject('ORIGIN_URL') originUrl: string) {
12-
http.get(originUrl + '/api/SampleData/WeatherForecasts').subscribe(result => {
11+
constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
12+
http.get(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
1313
this.forecasts = result.json() as WeatherForecast[];
1414
}, error => console.error(error));
1515
}

templates/AngularSpa/ClientApp/boot.server.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'reflect-metadata';
22
import 'zone.js';
33
import 'rxjs/add/operator/first';
4+
import { APP_BASE_HREF } from '@angular/common';
45
import { enableProdMode, ApplicationRef, NgZone, ValueProvider } from '@angular/core';
56
import { platformDynamicServer, PlatformState, INITIAL_CONFIG } from '@angular/platform-server';
67
import { createServerRenderer, RenderResult } from 'aspnet-prerendering';
@@ -11,7 +12,8 @@ enableProdMode();
1112
export default createServerRenderer(params => {
1213
const providers = [
1314
{ provide: INITIAL_CONFIG, useValue: { document: '<app></app>', url: params.url } },
14-
{ provide: 'ORIGIN_URL', useValue: params.origin }
15+
{ provide: APP_BASE_HREF, useValue: params.baseUrl },
16+
{ provide: 'BASE_URL', useValue: params.origin + params.baseUrl },
1517
];
1618

1719
return platformDynamicServer(providers).bootstrapModule(AppModule).then(moduleRef => {

templates/AngularSpa/npm-shrinkwrap.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

templates/AngularSpa/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
"@ngtools/webpack": "1.5.0",
2121
"@types/node": "8.0.8",
2222
"angular2-template-loader": "0.6.2",
23-
"aspnet-prerendering": "^2.0.5",
24-
"aspnet-webpack": "^1.0.29",
23+
"aspnet-prerendering": "^3.0.1",
24+
"aspnet-webpack": "^2.0.0",
2525
"awesome-typescript-loader": "3.2.1",
2626
"bootstrap": "3.3.7",
2727
"css": "2.2.1",

templates/AngularSpa/webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module.exports = (env) => {
1313
resolve: { extensions: [ '.js', '.ts' ] },
1414
output: {
1515
filename: '[name].js',
16-
publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
16+
publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
1717
},
1818
module: {
1919
rules: [

templates/AngularSpa/webpack.config.vendor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ module.exports = (env) => {
3636
]
3737
},
3838
output: {
39-
publicPath: '/dist/',
39+
publicPath: 'dist/',
4040
filename: '[name].js',
4141
library: '[name]_[hash]'
4242
},

templates/AureliaSpa/ClientApp/app/components/fetchdata/fetchdata.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export class Fetchdata {
66
public forecasts: WeatherForecast[];
77

88
constructor(http: HttpClient) {
9-
http.fetch('/api/SampleData/WeatherForecasts')
9+
http.fetch('api/SampleData/WeatherForecasts')
1010
.then(result => result.json() as Promise<WeatherForecast[]>)
1111
.then(data => {
1212
this.forecasts = data;

templates/AureliaSpa/ClientApp/boot.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'isomorphic-fetch';
22
import { Aurelia, PLATFORM } from 'aurelia-framework';
3+
import { HttpClient } from 'aurelia-fetch-client';
34
import 'bootstrap/dist/css/bootstrap.css';
45
import 'bootstrap';
56
declare const IS_DEV_BUILD: boolean; // The value is supplied by Webpack during the build
@@ -11,5 +12,10 @@ export function configure(aurelia: Aurelia) {
1112
aurelia.use.developmentLogging();
1213
}
1314

15+
new HttpClient().configure(config => {
16+
const baseUrl = document.getElementsByTagName('base')[0].href;
17+
config.withBaseUrl(baseUrl);
18+
});
19+
1420
aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app/components/app/app')));
1521
}

templates/AureliaSpa/npm-shrinkwrap.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

templates/AureliaSpa/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
},
1616
"devDependencies": {
1717
"@types/node": "^7.0.12",
18-
"aspnet-webpack": "^1.0.28",
18+
"aspnet-webpack": "^2.0.0",
1919
"aurelia-webpack-plugin": "^2.0.0-rc.2",
2020
"css-loader": "^0.28.0",
2121
"extract-text-webpack-plugin": "^2.1.0",

templates/AureliaSpa/webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module.exports = (env) => {
1414
},
1515
output: {
1616
path: path.resolve(bundleOutputDir),
17-
publicPath: '/dist/',
17+
publicPath: 'dist/',
1818
filename: '[name].js'
1919
},
2020
module: {

templates/AureliaSpa/webpack.config.vendor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ module.exports = ({ prod } = {}) => {
3838
},
3939
output: {
4040
path: path.join(__dirname, 'wwwroot', 'dist'),
41-
publicPath: '/dist/',
41+
publicPath: 'dist/',
4242
filename: '[name].js',
4343
library: '[name]_[hash]',
4444
},

templates/KnockoutSpa/ClientApp/boot.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import * as ko from 'knockout';
44
import './webpack-component-loader';
55
import AppRootComponent from './components/app-root/app-root';
66
const createHistory = require('history').createBrowserHistory;
7+
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href');
8+
const basename = baseUrl.substring(0, baseUrl.length - 1); // History component needs no trailing slash
79

810
// Load and register the <app-root> component
911
ko.components.register('app-root', AppRootComponent);
1012

1113
// Tell Knockout to start up an instance of your application
12-
ko.applyBindings({ history: createHistory() });
14+
ko.applyBindings({ history: createHistory({ basename }), basename });
1315

1416
// Basic hot reloading support. Automatically reloads and restarts the Knockout app each time
1517
// you modify source files. This will not preserve any application state other than the URL.

templates/KnockoutSpa/ClientApp/components/app-root/app-root.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div class='container-fluid'>
22
<div class='row'>
33
<div class='col-sm-3'>
4-
<nav-menu params='route: route'></nav-menu>
4+
<nav-menu params='router: router'></nav-menu>
55
</div>
66
<div class='col-sm-9' data-bind='component: { name: route().page, params: route }'></div>
77
</div>

templates/KnockoutSpa/ClientApp/components/app-root/app-root.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ const routes: Route[] = [
1212

1313
class AppRootViewModel {
1414
public route: KnockoutObservable<Route>;
15-
private _router: Router;
15+
public router: Router;
1616

17-
constructor(params: { history: History.History }) {
17+
constructor(params: { history: History.History, basename: string }) {
1818
// Activate the client-side router
19-
this._router = new Router(params.history, routes)
20-
this.route = this._router.currentRoute;
19+
this.router = new Router(params.history, routes, params.basename);
20+
this.route = this.router.currentRoute;
2121

2222
// Load and register all the KO components needed to handle the routes
2323
// The optional 'bundle-loader?lazy!' prefix is a Webpack feature that causes the referenced modules
@@ -32,7 +32,7 @@ class AppRootViewModel {
3232
// To support hot module replacement, this method unregisters the router and KO components.
3333
// In production scenarios where hot module replacement is disabled, this would not be invoked.
3434
public dispose() {
35-
this._router.dispose();
35+
this.router.dispose();
3636

3737
// TODO: Need a better API for this
3838
Object.getOwnPropertyNames((<any>ko).components._allRegisteredComponents).forEach(componentName => {

templates/KnockoutSpa/ClientApp/components/fetch-data/fetch-data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class FetchDataViewModel {
1212
public forecasts = ko.observableArray<WeatherForecast>();
1313

1414
constructor() {
15-
fetch('/api/SampleData/WeatherForecasts')
15+
fetch('api/SampleData/WeatherForecasts')
1616
.then(response => response.json() as Promise<WeatherForecast[]>)
1717
.then(data => {
1818
this.forecasts(data);

templates/KnockoutSpa/ClientApp/components/nav-menu/nav-menu.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@
1313
<div class='navbar-collapse collapse'>
1414
<ul class='nav navbar-nav'>
1515
<li>
16-
<a href='/' data-bind='css: { active: route().page === "home-page" }'>
16+
<a data-bind='attr: { href: router.link("/") }, css: { active: route().page === "home-page" }'>
1717
<span class='glyphicon glyphicon-home'></span> Home
1818
</a>
1919
</li>
2020
<li>
21-
<a href='/counter' data-bind='css: { active: route().page === "counter-example" }'>
21+
<a data-bind='attr: { href: router.link("/counter") }, css: { active: route().page === "counter-example" }'>
2222
<span class='glyphicon glyphicon-education'></span> Counter
2323
</a>
2424
</li>
2525
<li>
26-
<a href='/fetch-data' data-bind='css: { active: route().page === "fetch-data" }'>
26+
<a data-bind='attr: { href: router.link("/fetch-data") }, css: { active: route().page === "fetch-data" }'>
2727
<span class='glyphicon glyphicon-th-list'></span> Fetch data
2828
</a>
2929
</li>

0 commit comments

Comments
 (0)