Skip to content

Try using react-router with HMR #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion kill-node.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

echo "Killing all previously lauched Node.js instances"
AMOUNT=$(taskkill /f /im node.exe 2>/dev/null | grep node.exe | wc -l)
echo "Killed instances: $AMOUNT"
echo "Killed instances: $AMOUNT"

sleep 20
2,680 changes: 2,680 additions & 0 deletions npm-shrinkwrap.json

Large diffs are not rendered by default.

22 changes: 12 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,29 @@
},
"license": "MIT",
"dependencies": {
"react": "^15.1.0",
"react-dom": "^15.1.0",
"react": "^15.2.1",
"react-dom": "^15.2.1",
"react-redux": "^4.4.5",
"react-router": "^2.4.1",
"react-router": "^2.6.0",
"react-router-redux": "^4.0.5",
"redux": "^3.5.2"
},
"devDependencies": {
"awesome-typescript-loader": "^2.0.0-rc.17",
"babel-core": "^6.9.1",
"awesome-typescript-loader": "^2.1.1",
"babel-core": "^6.11.4",
"babel-loader": "^6.2.4",
"babel-polyfill": "^6.9.1",
"babel-preset-es2015-webpack": "^6.4.1",
"babel-preset-react": "^6.5.0",
"babel-preset-es2015-webpack": "^6.4.2",
"babel-preset-react": "^6.11.1",
"babel-preset-stage-0": "^6.5.0",
"colog": "^1.0.4",
"keypress": "^0.2.1",
"react-hot-loader": "^3.0.0-beta.2",
"single-line-log": "^1.1.1",
"typescript": "^1.9.0-dev.20160622-1.0",
"typings": "^1.3.0",
"webpack": "^2.1.0-beta.13",
"typescript": "^2.1.0-dev.20160728",
"typings": "^1.3.2",
"typings-for-css-modules-plugin": "0.0.7",
"webpack": "^2.1.0-beta.20",
"webpack-dev-server": "^2.1.0-beta.0"
}
}
20 changes: 0 additions & 20 deletions src/main/App.tsx

This file was deleted.

18 changes: 18 additions & 0 deletions src/main/container/Home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React, { Component } from 'react'
import { Link } from 'react-router'

export class Home extends Component<{}, {}> {
render() {
return (
<div>
<p>Layout container</p>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/test1">test1</Link></li>
<li><Link to="/test2">test2</Link></li>
</ul>
{this.props.children}
</div>
)
}
}
57 changes: 57 additions & 0 deletions src/main/container/Root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { Component } from 'react'
import { Provider } from 'react-redux'
import { Router } from 'react-router'
import { Store } from 'redux'
import { ApplicationState } from 'model/ApplicationState'

// If you use React Router, make this component
// render <Router> with your routes. Currently,
// only synchronous routes are hot reloaded, and
// you will see a warning from <Router> on every reload.
// You can ignore this warning. For details, see:
// https://github.com/reactjs/react-router/issues/2182

export class App extends Component<{}, {}> {
render() {
return (
<div>
<h1>Test App</h1>
</div>
)
}
}

export interface RootProps {
store: Store<ApplicationState>,
history: HistoryModule.History,
routes: ReactRouter.RouteConfig
}

Router.prototype.componentWillReceiveProps = function(nextProps) {
let components = [];
function grabComponents(element) {
// This only works for JSX routes, adjust accordingly for plain JS config
if (element.props && element.props.component) {
components.push(element.props.component);
}
if (element.props && element.props.children) {
React.Children.forEach(element.props.children, grabComponents);
}
}
grabComponents(nextProps.routes || nextProps.children);
components.forEach(React.createElement); // force patching
}

export class RootComponent extends Component<RootProps, {}> {
render() {
const { store, history, routes } = this.props

return (
<Provider store={store}>
<Router history={history} routes={routes} key={Math.random()} />
</Provider>
)
}
}

export const Root = RootComponent
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React, { Component } from 'react'
import { Test2 } from 'some/other/ns/Test2'
import { Test2 } from 'container/some/other/ns/Test2'
import * as style from './Style.css'

export class Test1 extends Component<{}, {}> {
render() {
console.log("test1:", style.test1)
return (
<div>
<p>I'm Test1</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { Component } from 'react'
export class Test2 extends Component<{}, {}> {
render() {
return (
<p>I'm Tets2</p>
<p>I'm Test2</p>
)
}
}
16 changes: 11 additions & 5 deletions src/main/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import 'babel-polyfill'
import React, { Component } from 'react'
import { render } from 'react-dom'
import { App } from './App'
import { Root, RootProps } from 'container/Root'
import { AppContainer } from 'react-hot-loader'
import { configureHistory } from 'router/history'
import { configureStore } from 'store/configureStore'
import { routes } from 'router/routes'

const store = configureStore()
export const history = configureHistory(store)

const domElement = document.getElementById('root')
const renderApp = (RootComponent: new () => Component<any, any>) => {
const renderApp = (RootComponent: new () => Component<RootProps, any>) => {
render(
<AppContainer>
<RootComponent />
<RootComponent store={store} history={history} routes={routes()} />
</AppContainer>,
domElement
)
}

if (module.hot) {
module.hot.accept('./App', () => renderApp(App))
module.hot.accept('container/Root', () => renderApp(Root))
}

renderApp(App)
renderApp(Root)

3 changes: 3 additions & 0 deletions src/main/model/ApplicationState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface ApplicationState {
routing: any
}
6 changes: 6 additions & 0 deletions src/main/reducer/root.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { combineReducers } from 'redux'
import { routerReducer } from 'react-router-redux'

export const rootReducer = combineReducers({
routing: routerReducer, /* name "routing" is fixed */
})
7 changes: 7 additions & 0 deletions src/main/router/history.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { browserHistory } from 'react-router'
import { IStore } from 'redux'
import { syncHistoryWithStore } from 'react-router-redux'
import { ApplicationState } from 'model/ApplicationState';

// Create an enhanced history that syncs navigation events with the store
export const configureHistory = (store: IStore<ApplicationState>) => syncHistoryWithStore(browserHistory, store)
12 changes: 12 additions & 0 deletions src/main/router/routes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react'
import { Home } from 'container/Home'
import { Route } from 'react-router'
import { Test1 } from 'container/some/name/space/Test1'
import { Test2 } from 'container/some/other/ns/Test2'

export const routes = () => (
<Route path="/" component={Home}>
<Route path="/test1" component={Test1} />
<Route path="/test2" component={Test2} />
</Route>
)
6 changes: 6 additions & 0 deletions src/main/store/configureStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createStore } from 'redux'
import { rootReducer } from 'reducer/root'

export const configureStore = (initialState?: Object) => {
return createStore(rootReducer, initialState)
}
2 changes: 0 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
"module": "es6",
"moduleResolution": "node",
"noImplicitAny": false,
"outDir": "target/typescript",
"pretty": true,
"removeComments": false,
"rootDir": "src/main",
"target": "es6"
},
"exclude": [
Expand Down
10 changes: 6 additions & 4 deletions typings.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{
"globalDependencies": {
"node": "registry:dt/node#6.0.0+20160621231320",
"react": "registry:dt/react#0.14.0+20160621225615",
"react-dom": "registry:dt/react-dom#0.14.0+20160412154040"
"node": "registry:dt/node#6.0.0+20160728152422",
"react": "registry:dt/react#0.14.0+20160720060442",
"react-dom": "registry:dt/react-dom#0.14.0+20160412154040",
"redux": "registry:dt/redux#3.5.2+20160703092728"
},
"dependencies": {
"react-redux": "registry:npm/react-redux#4.4.0+20160614222153",
"react-router": "registry:npm/react-router#2.4.0+20160616150328"
"react-router": "registry:npm/react-router#2.4.0+20160723033700",
"react-router-redux": "registry:npm/react-router-redux#4.0.0+20160602212457"
}
}
6 changes: 5 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const path = require('path')
const webpack = require('webpack')
const awesome = require('awesome-typescript-loader')
const TsConfigPathsPlugin = require('awesome-typescript-loader').TsConfigPathsPlugin;

const mainDir = 'src/main'
const resolve = rpath => path.join(__dirname, rpath)
Expand Down Expand Up @@ -43,6 +44,9 @@ module.exports = {
resolve(mainDir),
resolve('node_modules'),
],
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json', '.css']
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json', '.css'],
plugins: [
new TsConfigPathsPlugin(/* { tsconfig, compiler } */)
]
},
}