Wednesday, July 4, 2018

react-hot-loader and webpack-dev-server don't reload changes

Leave a Comment

I tried to follow react-hot-loader/getstarted to get up and running react-hot-loader in my webpack config. When I make some changes in my components, react-hot-loader doesn't reload changes. I updated npm script, added react-hot-loader into babel and webpack config and added module.hot.accept into index.jsx.

package.json

"scripts": {     "dev": "webpack-dev-server -d --progress --colors --port 8090 --hot --inline",   },     "dependencies": {         "aphrodite": "^2.2.1",         "bootstrap": "^4.1.1",         "bootstrap-select": "^1.13.1",         "classnames": "^2.2.5",         "d3": "^3.5.17",         "fixed-data-table-2": "^0.8.13",         "font-awesome": "^4.7.0",         "jquery": "^3.3.1",         "js-cookie": "^2.2.0",         "lodash": "^4.17.10",         "moment": "^2.22.1",         "popper.js": "^1.14.3",         "react": "^16.3.2",         "react-bootstrap-typeahead": "^3.1.3",         "react-datetime": "^2.14.0",         "react-dom": "^16.3.2",         "react-hot-loader": "^4.3.3",         "react-loadable": "^5.4.0",         "react-modal": "^3.4.4",         "react-redux": "^5.0.7",         "react-router": "^4.2.0",         "react-router-dom": "^4.2.2",         "react-router-redux": "^5.0.0-alpha.9",         "react-slidedown": "^1.3.0",         "react-tippy": "^1.2.2",         "react-toastify": "^4.0.1",         "react-transition-group": "^2.3.1",         "redux": "^4.0.0",         "redux-saga": "^0.16.0"       },       "devDependencies": {         "autoprefixer": "^8.4.1",         "babel": "^6.23.0",         "babel-core": "^6.26.3",         "babel-eslint": "^8.2.3",         "babel-loader": "^7.1.4",         "babel-plugin-syntax-dynamic-import": "^6.18.0",         "babel-plugin-transform-async-to-generator": "^6.24.1",         "babel-plugin-transform-class-properties": "^6.24.1",         "babel-plugin-transform-object-rest-spread": "^6.26.0",         "babel-polyfill": "^6.26.0",         "babel-preset-env": "^1.6.1",         "babel-preset-latest": "^6.24.1",         "babel-preset-react": "^6.24.1",         "css-loader": "^0.28.11",         "eslint": "^4.19.1",         "eslint-config-airbnb": "^16.1.0",         "eslint-plugin-import": "^2.11.0",         "eslint-plugin-jsx-a11y": "^6.0.3",         "eslint-plugin-react": "^7.7.0",         "file-loader": "^1.1.11",         "http-server": "^0.11.1",         "less": "^3.0.2",         "less-loader": "^4.1.0",         "node-sass": "^4.9.0",         "npm-install-webpack-plugin": "^4.0.5",         "postcss": "^6.0.22",         "postcss-loader": "^2.1.4",         "redux-devtools-extension": "^2.13.2",         "sass-loader": "^7.0.1",         "sass-resources-loader": "^1.3.3",         "style-loader": "^0.21.0",         "url-loader": "^1.0.1",         "webpack": "^4.6.0",         "webpack-cli": "^2.1.2",         "webpack-dev-server": "^3.1.4",         "webpack-merge": "^4.1.2",         "webpack-notifier": "^1.6.0"       } 

.babelrc

{   "presets": [     [       "latest", {         "es2015": {           "modules": false         }       }     ],     "react"   ],   "plugins": [     "transform-object-rest-spread",     "transform-class-properties",     "syntax-dynamic-import",     "transform-async-to-generator",     "react-hot-loader/babel"   ] } 

webpack.config.js

const webpack = require('webpack'); const webpackMerge = require('webpack-merge'); const path = require('path'); const WebpackNotifierPlugin = require('webpack-notifier');  const TARGET = process.env.npm_lifecycle_event; console.log(`target event is ${TARGET}`);  let outputFileName = 'app'; outputFileName += TARGET === 'prod' ? '.min.js' : '.js';  const common = {   entry: ['babel-polyfill', 'react-hot-loader/patch', './index.jsx'],   output: {     publicPath: '/',   },   module: {     rules: [       {         test: /\.js[x]?$/,         exclude: /(node_modules)/,         use: {           loader: 'babel-loader',         },       },     ],   },   plugins: [     new webpack.ProvidePlugin({       jQuery: 'jquery',       $: 'jquery',       jquery: 'jquery',       'window.jQuery': 'jquery',     }),     new WebpackNotifierPlugin(),   ],   resolve: {     modules: [       path.resolve('.'),       path.resolve('script'),       path.resolve('script', 'views'),       'node_modules',     ],     extensions: ['.js', '.jsx', '.json'],   }, };  if (TARGET === 'dev' || !TARGET) {   module.exports = webpackMerge(common, {     devtool: 'eval-source-map',     output: {       filename: 'bundle.js',       sourceMapFilename: '[file].map',     },     module: {       rules: [         {           test: /\.scss$/,           loaders: [             'style-loader',             'css-loader',             {               loader: 'postcss-loader',               options: {                 config: {                   path: 'postcss.config.js',                 },               },             },             'sass-loader',           ],         },         {           test: /\.less$/,           loaders: ['style-loader', 'css-loader', 'less-loader'],         },         {           test: /\.css$/,           use: ['style-loader', 'css-loader'],         },         {           test: /\.(eot|ttf|svg|gif|png|jpg|otf|woff|woff2)$/,           loader: 'url-loader',         },       ],     },     devServer: {       contentBase: path.resolve(__dirname), // New       historyApiFallback: true,     },     plugins: [       new webpack.DefinePlugin({         'process.env.NODE_ENV': JSON.stringify('development'),       }),       new webpack.HotModuleReplacementPlugin(),     ],   }); } 

index.jsx

import React from 'react'; import ReactDOM from 'react-dom'; import createHistory from 'history/createBrowserHistory'; import { createStore, combineReducers, applyMiddleware } from 'redux'; import { ConnectedRouter, routerReducer, routerMiddleware } from 'react-router-redux'; import { Provider } from 'react-redux'; import { AppContainer } from 'react-hot-loader'; import createSagaMiddleware from 'redux-saga'; import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';  import 'bootstrap'; import 'styles/custom.scss';  import App from 'App'; import reducers from 'state'; import sagas from 'sagas';  const history = createHistory(); const sagaMiddleware = createSagaMiddleware();  const store = createStore(   combineReducers({     ...reducers,     router: routerReducer,   }),   composeWithDevTools(applyMiddleware(routerMiddleware(history), sagaMiddleware)), );  if (module.hot) {   module.hot.accept('state', () => {     store.replaceReducer(require('state').default);   }); }  sagaMiddleware.run(sagas);  const render = (Component) => {   ReactDOM.render(     <AppContainer>       <Provider store={store}>         <ConnectedRouter history={history}>           <Component />         </ConnectedRouter>       </Provider>     </AppContainer>,     document.getElementById('app'),   ); };  render(App);  if (module.hot) {   module.hot.accept('App', () => { render(App); }); } 

index.html

<!DOCTYPE html>  <html lang="en"> <head>     <meta charset="utf-8">      <title>Test</title>      <meta name="description" content="">      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">  </head> <body>      <div id="app">      </div>    <script type="text/javascript" src="/bundle.js"></script>  </body> </html> 

2 Answers

Answers 1

  1. You can use react-script and react-app-rewire-hot-loader
  2. You maybe don't use react-hot-loader/babel

    { test: /\.(js|jsx)$/, include: paths.appSrc, loader: require.resolve("babel-loader"), options: {   // This is a feature of babel-loader for webpack (not Babel itself).   // It enables caching results in ./node_modules/.cache/babel-loader/   // directory for faster rebuilds.   cacheDirectory: true,   plugins: ["react-hot-loader/babel"]   }, } 

Answers 2

Have you tried exporting your root component as a hot:

import { hot } from "react-hot-loader" const App = () => <h3>Hello World</h3> export default hot(module)(App) 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment