Skip to content
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

18 react hot loader implementation #69

Merged
Merged
Show file tree
Hide file tree
Changes from 14 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
3 changes: 3 additions & 0 deletions 18 ReactHotLoader/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["es2015", "stage-0", "react"]
}
16 changes: 16 additions & 0 deletions 18 ReactHotLoader/devServer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');

new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
noInfo: true,
historyApiFallback: true
}).listen(8080, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}

console.log('Listening at http://localhost:8080/');
});
18 changes: 14 additions & 4 deletions 18 ReactHotLoader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
"version": "1.0.0",
"description": "",
"scripts": {
"clean": "rimraf dist",
"postinstall": "tsd reinstall --overwrite --save",
"start": "webpack-dev-server",
"start": "node devserver.js",
"test": "karma start"
},
"author": "Braulio Diez",
Expand All @@ -15,19 +16,26 @@
"lodash": "^4.5.1",
"object-assign": "^4.0.1",
"q": "^1.4.1",
"react": "^15.2.1",
"react": "^15.3.0",
"react-dom": "^15.2.1",
"react-redux": "^4.4.5",
"react-router": "^2.5.2",
"redux": "^3.5.2",
"redux-thunk": "^2.1.0",
"toastr": "^2.1.2"
"toastr": "^2.1.2",
"webpack-dev-server": "^1.14.1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move webpack-dev-server to devDependencies

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, pending commit / push

},
"devDependencies": {
"babel-core": "^6.13.2",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After testing to run app without babel-loader see this comment, I think we can remove all dependencies with babel

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be great going to.give a try

"babel-loader": "^6.2.5",
"babel-preset-es2015": "^6.13.2",
"babel-preset-react": "^6.11.1",
"babel-preset-stage-0": "^6.5.0",
"chai": "^3.5.0",
"css-loader": "^0.23.1",
"deep-freeze": "0.0.1",
"enzyme": "^2.4.1",
"express": "^4.14.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove dependency

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right, done

"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
"html-webpack-plugin": "^2.9.0",
Expand All @@ -41,14 +49,16 @@
"karma-webpack": "^1.7.0",
"mocha": "^2.4.5",
"react-addons-test-utils": "^15.2.1",
"react-hot-loader": "^1.3.0",
"redux-mock-store": "^1.1.2",
"rimraf": "^2.5.4",
"sinon": "^1.17.3",
"style-loader": "^0.13.0",
"ts-loader": "^0.8.1",
"tsd": "^0.6.5",
"typescript": "^1.8.9",
"url-loader": "^0.5.7",
"webpack": "^1.12.13",
"webpack-dev-server": "~1.10.1"
"webpack-hot-middleware": "^2.12.2"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dependency can be removed too, isn't it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

webpack-hot-middleware is used when we are not using webpack-dev-server

}
}
120 changes: 120 additions & 0 deletions 18 ReactHotLoader/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# React Hot Loader + Redux dev tool support
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were writing this info in AboutPage, isn't it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the about page we can have a summary, but is a good idea to have detailed readme.md when a given user navigates to this sample in Github the readme.md will be automatically displayed


React Hot loader allows us to introduce changes in the application
source code meanwhile we are running our web server and get the changes into our page without having to reload the browser and not loosing the application
state.

Redux dev tool is a chrome add-on that allows us to browse the state, replay actions, inject actions, export / import state...

# Steps to configure hot Loader

You don't need to update the source code of the app, all we have to do is install a list of npm packages, add some babel configuration, and then set a web server + updates on the webpack.config.

Packages to install (dev dependencies):

- babel-core
- babel-loader
- babel-preset-es2015
- babel-preset-react
- babel-preset-stage-0
- react-hot-loader
- webpack-hot-middleware

```
npm install babel-core babel-loader
babel-preset-es2015 babel-preset-react
babel-preset-stage-0
react-hot-loader
webpack-hot-middleware --save-dev
```

.babelrc file content to be added:

```json
{
"presets": ["es2015", "stage-0", "react"]
}
```

webpack config updates:

```javascript
//(...)
module.exports = {

// TODO: remove hot loading entry points in production
entry: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
'./index.tsx',
'./css/site.css',
'../node_modules/toastr/build/toastr.css',
'../node_modules/bootstrap/dist/css/bootstrap.css'
],

// (...)

module: {
loaders: [
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
loaders: ['react-hot', 'babel','ts-loader']
},
// (..)
},

plugins:[
new webpack.HotModuleReplacementPlugin(),
// (...)
]
}
```

We ned to add a new devServer.js file (we could try to setup a call to webpack-dev-server directly).

```javascript
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');

new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
noInfo: true,
historyApiFallback: true
}).listen(8080, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}

console.log('Listening at http://localhost:8080/');
});
````

Then update the "start" script on the package.json file:

```json
"scripts": {
// (...)
"start": "node devserver.js",
//(...)
},
```

# Steps to configure Redux dev tool

First we have to download the app from the chrome store.

Then we have to add a line of code to the create store to check
wether is enabled the dev tool (app.tsx).

````javascript
let store = createStore(
reducers,
compose(
applyMiddleware(ReduxThunk)
,nonTypedWindow.devToolsExtension ? nonTypedWindow.devToolsExtension() : f => f
)
);
````
11 changes: 8 additions & 3 deletions 18 ReactHotLoader/src/components/app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { createStore, applyMiddleware } from 'redux';
import { createStore, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import Header from './common/header';
import reducers from '../reducers';
Expand All @@ -9,9 +9,14 @@ import SpinnerContainer from './common/spinner.container';
interface Props extends React.Props<App> {
}

const nonTypedWindow : any = window;

let store = createStore(
reducers
,applyMiddleware(ReduxThunk)
reducers,
compose(
applyMiddleware(ReduxThunk)
,nonTypedWindow.devToolsExtension ? nonTypedWindow.devToolsExtension() : f => f
)
);

export default class App extends React.Component<Props, {}> {
Expand Down
18 changes: 9 additions & 9 deletions 18 ReactHotLoader/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var ExtractTextPlugin = require('extract-text-webpack-plugin');
var basePath = __dirname;

module.exports = {
debug: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this flag set to true?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's check what is for and later on remove.it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove, pending commit / push

context: path.join(basePath, "src"),
resolve: {
// .js is required for react imports.
Expand All @@ -14,35 +15,32 @@ module.exports = {
extensions: ['', '.js', '.ts', '.tsx']
},

// Toake into account: remove hot loading entry points in production
entry: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
'./index.tsx',
'./css/site.css',
'../node_modules/toastr/build/toastr.css',
'../node_modules/bootstrap/dist/css/bootstrap.css'
],

output: {
publicPath: 'http://localhost:8080/',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are using:

entry: [
 +    'webpack-dev-server/client?http://localhost:8080',

I think this line is not necessary

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I Will check, why is on the basic samples?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done pending commit / push

path: path.join(basePath, "dist"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can still using this configuration instead of create devServer.js and more dependencies like express.

Configuration:

devServer: {
    contentBase: './dist', //Content base
    inline: true, //Enable watch and live reload
    host: 'localhost',
    port: 8080,
    hot: true
  },

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I Will.give a try

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

filename: 'bundle.js'
},

//https://webpack.github.io/docs/webpack-dev-server.html#webpack-dev-server-cli
devServer: {
contentBase: './dist', //Content base
inline: true, //Enable watch and live reload
host: 'localhost',
port: 8080
},

// http://webpack.github.io/docs/configuration.html#devtool
devtool: 'inline-source-map',
devtool: 'source-map',

module: {
loaders: [
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
loader: 'ts-loader'
loaders: ['react-hot', 'babel','ts-loader']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I test to execute the app without babel-loader and it's working. So we only need:

loaders: ['react-hot', 'ts-loader']

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think webpack works if we configure this line like:

loaders: ['react-hot-loader', 'ts-loader']

or

loaders: ['react-hot', 'ts']

It's the same for it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good points!!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

},
//Note: Doesn't exclude node_modules to load bootstrap
{
Expand All @@ -64,6 +62,8 @@ module.exports = {
},

plugins:[
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why we need this plugin. It's to avoid show erros while webpack is compiling

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove it and.checi

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html', //Name of file in ./dist/
Expand Down