Skip to content

Commit 1b4dd93

Browse files
Update React MusicStore sample to use current technologies (TypeScript 2, .NET Core 1.0.1, etc.). Fixes aspnet#417
1 parent 7ee8a7b commit 1b4dd93

File tree

21 files changed

+140
-4685
lines changed

21 files changed

+140
-4685
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
music-db.sqlite
22
/wwwroot/dist/
33
/node_modules/
4+
yarn.lock

samples/react/MusicStore/ReactApp/boot-server.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,29 @@ import { match, RouterContext } from 'react-router';
55
import createMemoryHistory from 'history/lib/createMemoryHistory';
66
import { routes } from './routes';
77
import configureStore from './configureStore';
8-
React;
8+
type BootResult = { html?: string, globals?: { [key: string]: any }, redirectUrl?: string};
99

1010
export default function (params: any): Promise<{ html: string }> {
11-
return new Promise<{ html: string, globals: { [key: string]: any } }>((resolve, reject) => {
11+
return new Promise<BootResult>((resolve, reject) => {
1212
// Match the incoming request against the list of client-side routes
1313
match({ routes, location: params.location }, (error, redirectLocation, renderProps: any) => {
1414
if (error) {
1515
throw error;
1616
}
1717

18+
// If there's a redirection, just send this information back to the host application
19+
if (redirectLocation) {
20+
resolve({ redirectUrl: redirectLocation.pathname });
21+
return;
22+
}
23+
24+
// If it didn't match any route, renderProps will be undefined
25+
if (!renderProps) {
26+
throw new Error(`The location '${ params.url }' doesn't match any route configured in react-router.`);
27+
}
28+
1829
// Build an instance of the application
19-
const history = createMemoryHistory(params.url);
20-
const store = configureStore(history);
30+
const store = configureStore();
2131
const app = (
2232
<Provider store={ store }>
2333
<RouterContext {...renderProps} />
Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
1+
import './styles/styles.css';
2+
import 'bootstrap/dist/css/bootstrap.css';
3+
14
import * as React from 'react';
25
import * as ReactDOM from 'react-dom';
36
import { browserHistory, Router } from 'react-router';
47
import { Provider } from 'react-redux';
5-
React; // Need this reference otherwise TypeScript doesn't think we're using it and ignores the import
6-
7-
import './styles/styles.css';
8-
import 'bootstrap/dist/css/bootstrap.css';
9-
import configureStore from './configureStore';
8+
import { syncHistoryWithStore } from 'react-router-redux';
109
import { routes } from './routes';
10+
import configureStore from './configureStore';
1111
import { ApplicationState } from './store';
1212

13+
// Get the application-wide store instance, prepopulating with state from the server where available.
1314
const initialState = (window as any).initialReduxState as ApplicationState;
14-
const store = configureStore(browserHistory, initialState);
15+
const store = configureStore(initialState);
16+
const history = syncHistoryWithStore(browserHistory, store);
1517

18+
// This code starts up the React app when it runs in a browser. It sets up the routing configuration
19+
// and injects the app into a DOM element.
1620
ReactDOM.render(
1721
<Provider store={ store }>
18-
<Router history={ browserHistory } children={ routes } />
22+
<Router history={ history } children={ routes } />
1923
</Provider>,
2024
document.getElementById('react-app')
2125
);
Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,22 @@
1-
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
2-
import * as thunkModule from 'redux-thunk';
3-
import { syncHistory, routeReducer } from 'react-router-redux';
1+
import { createStore, applyMiddleware, compose, combineReducers, GenericStoreEnhancer } from 'redux';
2+
import thunk from 'redux-thunk';
3+
import { routerReducer } from 'react-router-redux';
44
import * as Store from './store';
55
import { typedToPlain } from 'redux-typed';
66

7-
export default function configureStore(history: HistoryModule.History, initialState?: Store.ApplicationState) {
8-
// Build middleware
9-
const thunk = (thunkModule as any).default; // Workaround for TypeScript not importing thunk module as expected
10-
const reduxRouterMiddleware = syncHistory(history);
11-
const middlewares = [thunk, reduxRouterMiddleware, typedToPlain];
12-
const devToolsExtension = null;//(window as any).devToolsExtension; // If devTools is installed, connect to it
13-
14-
const finalCreateStore = compose(
15-
applyMiddleware(...middlewares),
7+
export default function configureStore(initialState?: Store.ApplicationState) {
8+
// Build middleware. These are functions that can process the actions before they reach the store.
9+
const windowIfDefined = typeof window === 'undefined' ? null : window as any;
10+
// If devTools is installed, connect to it
11+
const devToolsExtension = windowIfDefined && windowIfDefined.devToolsExtension as () => GenericStoreEnhancer;
12+
const createStoreWithMiddleware = compose(
13+
applyMiddleware(thunk, typedToPlain),
1614
devToolsExtension ? devToolsExtension() : f => f
17-
)(createStore)
15+
)(createStore);
1816

19-
// Combine all reducers
17+
// Combine all reducers and instantiate the app-wide store instance
2018
const allReducers = buildRootReducer(Store.reducers);
21-
22-
const store = finalCreateStore(allReducers, initialState) as Redux.Store;
23-
24-
// Required for replaying actions from devtools to work
25-
reduxRouterMiddleware.listenForReplays(store);
19+
const store = createStoreWithMiddleware(allReducers, initialState) as Redux.Store<Store.ApplicationState>;
2620

2721
// Enable Webpack hot module replacement for reducers
2822
if (module.hot) {
@@ -36,5 +30,5 @@ export default function configureStore(history: HistoryModule.History, initialSt
3630
}
3731

3832
function buildRootReducer(allReducers) {
39-
return combineReducers(Object.assign({}, allReducers, { routing: routeReducer })) as Redux.Reducer;
33+
return combineReducers<Store.ApplicationState>(Object.assign({}, allReducers, { routing: routerReducer }));
4034
}
Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,52 @@
11
{
2-
"name": "MusicStore",
2+
"name": "music-store",
33
"version": "0.0.0",
4-
"devDependencies": {
5-
"babel-loader": "^6.2.1",
6-
"babel-plugin-react-transform": "^2.0.0",
7-
"babel-preset-es2015": "^6.3.13",
8-
"babel-preset-react": "^6.3.13",
4+
"dependencies": {
5+
"@types/react": "^0.14.29",
6+
"@types/react-bootstrap": "^0.0.35",
7+
"@types/react-dom": "^0.14.14",
8+
"@types/react-redux": "^4.4.29",
9+
"@types/react-router": "^2.0.30",
10+
"@types/react-router-bootstrap": "^0.0.27",
11+
"@types/react-router-redux": "^4.0.30",
12+
"@types/redux": "3.5.27",
13+
"@types/redux-thunk": "^2.1.28",
14+
"@types/source-map": "^0.1.28",
15+
"@types/uglify-js": "^2.0.27",
16+
"@types/webpack": "^1.12.35",
17+
"@types/webpack-env": "^1.12.1",
18+
"@types/whatwg-fetch": "0.0.28",
19+
"aspnet-prerendering": "^1.0.7",
20+
"aspnet-webpack": "^1.0.17",
21+
"aspnet-webpack-react": "^1.0.2",
22+
"babel-core": "^6.5.2",
23+
"babel-loader": "^6.2.3",
24+
"babel-preset-es2015": "^6.5.0",
25+
"babel-preset-react": "^6.5.0",
26+
"bootstrap": "^3.3.6",
927
"css-loader": "^0.23.1",
10-
"express": "^4.13.4",
28+
"domain-task": "^2.0.1",
29+
"event-source-polyfill": "^0.0.7",
1130
"extract-text-webpack-plugin": "^1.0.1",
1231
"file-loader": "^0.8.5",
13-
"react-transform-hmr": "^1.0.2",
32+
"jquery": "^2.2.1",
33+
"react": "^15.3.2",
34+
"react-bootstrap": "^0.30.6",
35+
"react-dom": "^15.3.2",
36+
"react-redux": "^4.4.5",
37+
"react-router": "^2.8.1",
38+
"react-router-bootstrap": "^0.23.1",
39+
"react-router-redux": "^4.0.6",
40+
"redux": "^3.6.0",
41+
"redux-thunk": "^2.1.0",
42+
"redux-typed": "^2.0.0",
1443
"style-loader": "^0.13.0",
15-
"ts-loader": "^0.8.0",
16-
"typescript": "^1.7.5",
44+
"ts-loader": "^0.8.1",
45+
"typescript": "2.0.3",
1746
"url-loader": "^0.5.7",
18-
"webpack": "^1.12.12",
19-
"webpack-dev-middleware": "^1.5.1",
20-
"webpack-hot-middleware": "^2.6.4"
21-
},
22-
"dependencies": {
23-
"aspnet-prerendering": "^1.0.0",
24-
"aspnet-webpack": "^1.0.3",
25-
"aspnet-webpack-react": "^1.0.1",
26-
"bootstrap": "^3.3.6",
27-
"domain-context": "^0.5.1",
28-
"domain-task": "^2.0.0",
29-
"history": "^2.0.0",
30-
"isomorphic-fetch": "^2.2.1",
31-
"memory-fs": "^0.3.0",
32-
"react": "^0.14.7",
33-
"react-bootstrap": "^0.28.2",
34-
"react-dom": "^0.14.7",
35-
"react-redux": "^4.2.1",
36-
"react-router": "^2.0.0-rc5",
37-
"react-router-bootstrap": "^0.20.1",
38-
"react-router-redux": "^2.1.0",
39-
"redux": "^3.2.1",
40-
"redux-thunk": "^1.0.3",
41-
"redux-typed": "^1.0.0",
42-
"require-from-string": "^1.1.0",
43-
"webpack-externals-plugin": "^1.0.0"
47+
"webpack": "^1.13.2",
48+
"webpack-hot-middleware": "^2.12.2",
49+
"webpack-merge": "^0.14.1",
50+
"webpack-node-externals": "^1.4.3"
4451
}
4552
}
Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,83 @@
11
{
2-
"version": "1.0.0-*",
3-
"buildOptions": {
4-
"emitEntryPoint": true,
5-
"preserveCompilationContext": true
6-
},
7-
"runtimeOptions": {
8-
"gcServer": true
9-
},
10-
"tooling": {
11-
"defaultNamespace": "MusicStore"
12-
},
13-
14-
"dependencies": {
2+
"dependencies": {
153
"Microsoft.NETCore.App": {
16-
"version": "1.0.0",
4+
"version": "1.0.1",
175
"type": "platform"
186
},
7+
"Microsoft.AspNetCore.ReactServices": "1.0.0-*",
198
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
209
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
10+
"Microsoft.AspNetCore.Mvc": "1.0.1",
11+
"Microsoft.AspNetCore.Razor.Tools": {
12+
"version": "1.0.0-preview2-final",
13+
"type": "build"
14+
},
2115
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
22-
"Microsoft.AspNetCore.Mvc": "1.0.0",
23-
"Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0",
24-
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
16+
"Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
2517
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
18+
"Microsoft.EntityFrameworkCore.SQLite": "1.0.0",
19+
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
2620
"Microsoft.Extensions.Configuration.Json": "1.0.0",
21+
"Microsoft.Extensions.Configuration.CommandLine": "1.0.0",
22+
"Microsoft.Extensions.Logging": "1.0.0",
2723
"Microsoft.Extensions.Logging.Console": "1.0.0",
28-
"Microsoft.NETCore.Platforms": "1.0.1",
2924
"Microsoft.Extensions.Logging.Debug": "1.0.0",
30-
"Microsoft.EntityFrameworkCore.SQLite": "1.0.0",
31-
"Microsoft.AspNetCore.ReactServices": "1.0.0-*",
32-
"AutoMapper": "5.0.2"
25+
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
26+
"AutoMapper": "5.0.2"
27+
},
28+
29+
"tools": {
30+
"Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final",
31+
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final",
32+
"Microsoft.DotNet.Watcher.Tools": "1.0.0-preview2-final"
3333
},
34+
3435
"frameworks": {
3536
"netcoreapp1.0": {
3637
"imports": [
3738
"dotnet5.6",
38-
"dnxcore50",
3939
"portable-net45+win8"
4040
]
4141
}
4242
},
43+
44+
"buildOptions": {
45+
"emitEntryPoint": true,
46+
"preserveCompilationContext": true,
47+
"compile": {
48+
"exclude": ["node_modules"]
49+
}
50+
},
51+
52+
"runtimeOptions": {
53+
"configProperties": {
54+
"System.GC.Server": true
55+
}
56+
},
57+
4358
"publishOptions": {
44-
"exclude": [
59+
"include": [
60+
"appsettings.json",
61+
"ClientApp/dist",
4562
"node_modules",
46-
"bower_components",
47-
"**.xproj",
48-
"**.user",
49-
"**.vspscc"
63+
"Views",
64+
"web.config",
65+
"wwwroot"
66+
],
67+
"exclude": [
68+
"wwwroot/dist/*.map"
5069
]
5170
},
71+
5272
"scripts": {
53-
"prepublish": [ "npm install" ],
73+
"prepublish": [
74+
"npm install",
75+
"node node_modules/webpack/bin/webpack.js"
76+
],
5477
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
78+
},
79+
80+
"tooling": {
81+
"defaultNamespace": "MusicStore"
5582
}
5683
}

samples/react/MusicStore/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"target": "es6",
55
"jsx": "preserve",
66
"sourceMap": true,
7-
"experimentalDecorators": true
7+
"experimentalDecorators": true,
8+
"types": [ "webpack-env", "whatwg-fetch" ]
89
},
910
"exclude": [
1011
"node_modules"

samples/react/MusicStore/tsd.json

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)