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

React Hot Loader 3.0 beta demo #61

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c423415
React Hot Loader 3.0 demo
gaearon Apr 17, 2016
5d5175b
Use Babel
gaearon Apr 18, 2016
afa4aee
Bump version!
gaearon Apr 18, 2016
691fe11
Bump version
gaearon Apr 18, 2016
7f8903b
Bump the version
gaearon Apr 28, 2016
b52c727
Bump to 3.0.0-beta.0
gaearon Apr 30, 2016
f134ff3
Bump version
gaearon May 2, 2016
febf956
changed the regex expression to handle .jsx files (#83)
gfantom Nov 1, 2016
dfeb37b
Use webpack middleware
bradleyboy May 20, 2016
f764530
Add express, remove webpack dev server
bradleyboy May 20, 2016
5c76efd
Formatting
bradleyboy May 20, 2016
372080f
update dependencies and add yarn.lock
calesce Nov 3, 2016
a26a653
add OccurrenceOrder and NoErrors webpack plugins
calesce Nov 20, 2016
9089b6b
use cheap-module-eval-source-map option for source maps
calesce Nov 20, 2016
9609a8e
use cheap-module-source-map
calesce Nov 21, 2016
437dc6a
Updated dependencies
petertrotman Jan 25, 2017
314c024
Updated .babelrc and webpack.config.js
petertrotman Jan 25, 2017
6811627
Updated
petertrotman Jan 25, 2017
19d3594
Resolved inconsistencies with webpack's guide setup and original boil…
petertrotman Jan 25, 2017
59281e4
Readded yarn.lock file with updated dependencies
petertrotman Jan 25, 2017
abe4763
Updated README with citation to webpack guide and removed reference t…
petertrotman Jan 25, 2017
c78530f
removed .jshintrc
calesce Jan 25, 2017
26938f2
update license and fix some formatting
calesce Jan 25, 2017
43f80ee
Readded eslint and updated yarn.lock
petertrotman Jan 26, 2017
d6891f2
Fixed missing eslint dependency and updated yarn.lock file
petertrotman Jan 26, 2017
92cb506
Merge branch 'next' into next
calesce Jan 26, 2017
8a05c0d
Merge pull request #111 from petertrotman/next
calesce Jan 26, 2017
949277a
document known WebStorm file-watching issue
calesce Jan 26, 2017
677a4d6
Ensure initial render
petertrotman Jan 26, 2017
a2d489d
Add basic build script
cookpete Feb 20, 2017
530fb8f
update yarn.lock
calesce Feb 26, 2017
8ebffda
update README
vikr01 Oct 5, 2018
4e51cf7
Merge pull request #141 from vikr01/next
theKashey Oct 5, 2018
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
9 changes: 8 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
{
"presets": ["es2015", "stage-0", "react"]
"presets": [
["es2015", {"modules": false}],

Choose a reason for hiding this comment

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

s/es2015/latest/?

Choose a reason for hiding this comment

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

why is necessary disable modules? looks like works without this option

Choose a reason for hiding this comment

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

@Kikobeats disable modules has no effect on hot loader. Webpack now can handle es 6 modules and for better tree shaking this has to be off in babel.

Choose a reason for hiding this comment

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

@tracker1 might as well use babel-present-env instead

Choose a reason for hiding this comment

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

@dlebedynskyi agreed, apparently there's a deprecation message on -latest that says as much now.

"stage-2",
"react"
],
"plugins": [
"react-hot-loader/babel"
]
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ node_modules
npm-debug.log
.DS_Store
dist
*.swp
6 changes: 0 additions & 6 deletions .jshintrc

This file was deleted.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2014 Dan Abramov
Copyright (c) 2017 Dan Abramov

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,46 @@ react-hot-boilerplate

The minimal dev environment to enable live-editing React components.

Based on the guide available at https://webpack.js.org/guides/hot-module-replacement/

### Usage

```
npm install
npm start
yarn
yarn start
open http://localhost:3000
```

Now edit `src/App.js`.
Now edit [`src/App.js`](./src/App.js).
Your changes will appear without reloading the browser like in [this video](http://vimeo.com/100010922).

### Linting

This boilerplate project includes React-friendly ESLint configuration.

```
npm run lint
yarn run lint
```

### Building

A basic production script is included that builds your app to a `dist` folder

```
yarn run build
```

### Using `0.0.0.0` as Host

You may want to change the host in `server.js` and `webpack.config.js` from `localhost` to `0.0.0.0` to allow access from same WiFi network. This is not enabled by default because it is reported to cause problems on Windows. This may also be useful if you're using a VM.
You may want to change the host in `webpack.config.js` from `localhost` to `0.0.0.0` to allow access from same WiFi network. This is not enabled by default because it is reported to cause problems on Windows. This may also be useful if you're using a VM.

### Missing Features

This boilerplate is purposefully simple to show the minimal configuration for React Hot Loader. For a real project, you'll want to add a separate config for production with hot reloading disabled and minification enabled. You'll also want to add a router, styles and maybe combine dev server with an existing server. This is out of scope of this boilerplate, but you may want to look into [other starter kits](https://github.com/gaearon/react-hot-loader/blob/master/docs/README.md#starter-kits).
This boilerplate is purposefully simple to show the minimal configuration for React Hot Loader. For a real project, you may want to add a router, styles and maybe combine dev server with an existing server. This is out of scope of this boilerplate, but you may want to look into [other starter kits](https://github.com/gaearon/react-hot-loader/blob/master/docs/README.md#starter-kits).

### WebStorm

Because the WebStorm IDE uses "safe writes" by default, Webpack's file-watcher won't recognize file changes, so hot-loading won't work. To fix this, disable "safe write" in WebStorm.

### Dependencies

Expand Down
36 changes: 21 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
"version": "1.0.0",
"description": "Boilerplate for ReactJS project with hot code reloading",
"scripts": {
"start": "node server.js",
"lint": "eslint src"
"start": "webpack-dev-server",
"lint": "eslint src",
"prebuild": "rimraf dist",
"build": "cross-env NODE_ENV=production webpack -p --config webpack.config.production.js",
"postbuild": "copyfiles index.html dist"
},
"repository": {
"type": "git",
Expand All @@ -28,20 +31,23 @@
},
"homepage": "https://github.com/gaearon/react-hot-boilerplate",
"devDependencies": {
"babel-core": "^6.0.20",
"babel-eslint": "^4.1.3",
"babel-loader": "^6.0.1",
"babel-preset-es2015": "^6.0.15",
"babel-preset-react": "^6.0.15",
"babel-preset-stage-0": "^6.0.15",
"eslint": "^1.10.3",
"eslint-plugin-react": "^3.6.2",
"react-hot-loader": "^1.3.0",
"webpack": "^1.12.2",
"webpack-dev-server": "^1.12.1"
"babel-core": "^6.22.1",
"babel-loader": "^6.2.10",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.22.0",
"babel-preset-stage-2": "^6.22.0",
"copyfiles": "^1.2.0",
"cross-env": "^3.1.4",
"react-hot-loader": "^3.0.0-beta.6",
"rimraf": "^2.6.0",
"webpack": "^2.2.0",
"webpack-dev-server": "^2.2.0"
},
"dependencies": {
"react": "^0.14.6",
"react-dom": "^0.14.6"
"babel-eslint": "^7.1.1",
"eslint": "^3.14.1",
"eslint-plugin-react": "^6.9.0",
"react": "^15.4.2",
"react-dom": "^15.4.2"
}
}
15 changes: 0 additions & 15 deletions server.js

This file was deleted.

12 changes: 11 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import React, { Component } from 'react';
import Layout from './Layout';
import Counter from './Counter';

// 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 default class App extends Component {
render() {
return (
<h1>Hello, world.</h1>
<Layout>
<Counter />
</Layout>
);
}
}
24 changes: 24 additions & 0 deletions src/Counter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React, { Component } from 'react';

export default class Counter extends Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
}

componentDidMount() {
this.interval = setInterval(this.tick.bind(this), 1000);
}

tick() {
this.setState({ counter: this.state.counter + 1 });
}

componentWillUnmount() {
clearInterval(this.interval);
}

render() {
return <h2>Counter: {this.state.counter}</h2>;
}
}
10 changes: 10 additions & 0 deletions src/Layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';

export default function Layout({ children }) {
return (
<div>
<h1>Hello, world!</h1>
{children}
</div>
);
}
13 changes: 12 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import { AppContainer } from 'react-hot-loader';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
const rootEl = document.getElementById('root');
const render = Component =>
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
rootEl
);

render(App);
if (module.hot) module.hot.accept('./App', () => render(App));
Copy link

Choose a reason for hiding this comment

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

@gaearon Do you need to re-require the App before calling render?

Copy link

@parris parris Apr 8, 2017

Choose a reason for hiding this comment

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

+1 in fact this line should be:

if (module.hot) {
    // eslint-disable-next-line global-require
    module.hot.accept('./App', () => render(require('./App').default));
}

Choose a reason for hiding this comment

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

It should not, unless you are incorrectly transforming modules before webpack sees them.

You only need to require or import() again if you required or import()ed the first time. Static imports are live and are always up-to-date (internally, webpack will re-require it before calling your callback).

Copy link

Choose a reason for hiding this comment

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

@kovensky I'm inclined to believe you're wrong due to the official 3.0 docs saying otherwise: https://github.com/gaearon/react-hot-loader/edit/master/docs/README.md#L96

Copy link

@Jessidhia Jessidhia Apr 10, 2017

Choose a reason for hiding this comment

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

Yeah, that is incorrect for webpack 2, as long as you disable the module transform in babel/typescript/etc. webpack has to see the raw import / export commands. The require is necessary if they are getting converted to require calls by your preprocessor.

See the webpack 2 section in https://github.com/gaearon/react-hot-loader/blob/master/docs/README.md#webpack-2

62 changes: 51 additions & 11 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,65 @@ var path = require('path');
var webpack = require('webpack');

module.exports = {
devtool: 'eval',
entry: [
'react-hot-loader/patch',
// activate HMR for React

'webpack-dev-server/client?http://localhost:3000',
// bundle the client for webpack-dev-server
// and connect to the provided endpoint

'webpack/hot/only-dev-server',
'./src/index'
// bundle the client for hot reloading
// only- means to only hot reload for successful updates

'./src/index.js',
// the entry point of our app
],

output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
// the output bundle

path: path.resolve(__dirname, 'dist'),

publicPath: '/static/'
// necessary for HMR to know where to load the hot update chunks
},

devtool: 'inline-source-map',

module: {
rules: [
{
test: /\.jsx?$/,
use: [
'babel-loader',
],
exclude: /node_modules/,
},
],
},

plugins: [
new webpack.HotModuleReplacementPlugin()
new webpack.HotModuleReplacementPlugin(),
// enable HMR globally

new webpack.NamedModulesPlugin(),
// prints more readable module names in the browser console on HMR updates

new webpack.NoEmitOnErrorsPlugin(),
// do not emit compiled assets that include errors
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'src')
}]
}

devServer: {
host: 'localhost',
port: 3000,

historyApiFallback: true,
// respond to 404s with index.html

hot: true,
// enable HMR on the server
},
};
33 changes: 33 additions & 0 deletions webpack.config.production.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
var path = require('path');
var webpack = require('webpack');

module.exports = {
entry: './src/index.js',

output: {
filename: 'static/bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'
},

devtool: 'source-map',

module: {
rules: [
{
test: /\.jsx?$/,
use: [
'babel-loader'
],
exclude: /node_modules/
}
]
},

plugins: [
new webpack.optimize.UglifyJsPlugin({

Choose a reason for hiding this comment

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

This is redundant since webpack -p will process output via uglify without the plugin configured.

Choose a reason for hiding this comment

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

sourceMap: true,
comments: false
})
]
};
Loading