HenrikJoreteg / hjs-webpack

Helpers/presets for setting up webpack with hotloading react and ES6(2015) using Babel.
1.79k stars 129 forks source link

Transition from babel-plugin-react-transform to React Hot Loader 3 #213

Open standayweb opened 8 years ago

standayweb commented 8 years ago

TL;DR: https://github.com/gaearon/react-hot-boilerplate/pull/61

babel-plugin-react-transform is now deprecated, React Hot Loader 3 is on the horizon. The biggest advantage for me right now is that I want to write more components as stateless functions but if I do, hot reloading breaks.

batusai513 commented 8 years ago

@standayweb i don't think that adding react-hot-loader to hjs-webpack based on what have been done since version 8.0.0, i think that is better to do something on how to add extra code to the configuration, is a bit cumbersome.

anyways, here is what i did to implement react-hot-loader@3

var path = require('path');
var getConfig = require('hjs-webpack');
var webpack = require('webpack');

var config = getConfig({
  in: 'app/main.js',
  out: 'dist',
  clearBeforeBuild: '!(images|favicon.ico)'
});

if(process.env.NODE_ENV === 'production'){
  config.plugins[4] = new webpack.optimize.UglifyJsPlugin({
    mangle: {
      except: ['$inject', 'elementRegistry', 'modeling']
    },
    compress: {
      warnings: false
    },
    output: {
      comments: false
    },
    sourceMap: false
  });
}

if(env == 'development'){
  config.entry[0] = config.entry[0] + '?reload=true';
  config.entry.unshift('react-hot-loader/patch');
}

config.resolve.root = path.resolve('.');

config.module.loaders.push({
  test: /\.(js|jsx|babel)$/,
  loaders: ['babel', 'eslint'],
  exclude: /node_modules/
});

module.exports = config;

look above, i have to know to know much about where to add the 'react-hot-loader/patch', also, but not related, how i need to know the exact place to modify a plugin.

.babelrc

{
  "presets": ["es2015", "stage-0", "react"],
  "env": {
    "development": {
      "plugins": ["react-hot-loader/babel"]
    }
  }
}

i had to create an app.js file

import React from 'react';
import { Provider } from 'react-redux';
import getRoutes from './routes';
import {authService} from './helpers/api/auth';

function checkAuth(nextState, replace){
  var nextPathName = nextState.location.pathname;
  if(nextPathName == "/login"){
    if(authService.loggedIn()){
      replace({
        pathname: '/',
        state: { nextPathName: nextPathName }
      });
    }
  }else{
    if(!authService.loggedIn()){
      replace({
        pathname: '/login',
        state: { nextPathName: nextPathName }
      });
    }
  }
}

export default function App({store, history}){
  return (
    <Provider store={store}>
      {getRoutes(history, checkAuth)}
    </Provider>
  );
}

and in my main.js file:

import 'babel-polyfill';
import React from 'react';
import ReactDOM, {render} from 'react-dom';
import {browserHistory} from 'react-router';
import { AppContainer } from 'react-hot-loader';
import createStore from './create-store';
import App from './app';
import './styles/main.scss';
import startInitializers from './initializers';

const {store, history} = createStore(browserHistory, {});
startInitializers(store.dispatch, store.getState);

var rootEl = document.getElementById('root');

export default render(
  <AppContainer>
    <App store={store} history={history} />
  </AppContainer>,
  rootEl
);

if (module.hot) {
  module.hot.accept('./app', () => {
    const NextApp = require('./app').default;
    render(
      <AppContainer>
         <NextApp store={store} history={history} />
      </AppContainer>,
      rootEl
    );
  });
}

hopefully this will help you.