A React Transform that enables hot reloading React classes using Hot Module Replacement API. Hot module replacement is supported natively by Webpack and available in Browserify with browserify-hmr.
First, install the Babel plugin:
npm install --save-dev babel-plugin-react-transform
Then, install the transform:
npm install --save-dev react-transform-hmr
Edit your .babelrc
to include extra.babel-plugin-react-transform
.
It must be an array of the transforms you want to use:
{
"stage": 0,
"env": {
// only enable it when process.env.NODE_ENV is 'development' or undefined
"development": {
"plugins": ["react-transform"],
"extra": {
// must be defined and be an object
"react-transform": {
"transforms": [{
"transform": "react-transform-hmr",
// if you use React Native, pass "react-native" instead:
"imports": ["react"],
// this is important for Webpack HMR:
"locals": ["module"]
}]
// note: you can put more transforms into array
// this is just one of them!
}
}
}
}
}
Make sure you process files with babel-loader
, and that you don’t use React Hot Loader (it’s not needed with this transform).
It is up to you to ensure that the transform is not enabled when you compile the app in production mode. The easiest way to do this is to put React Transform configuration inside env.development
in .babelrc
and ensure you’re calling babel
with NODE_ENV=production
. See babelrc documentation for more details about using env
option.
This transform enables hot reloading when used together with React Native Webpack Server. However note that you should not use .babelrc
to configure it with React Native. Otherwise you’ll get Uncaught SyntaxError: Unexpected reserved word
in ActivityIndicatorIOS.ios.js
.
There are two problems why .babelrc
doesn’t work well in React Native:
- Changes in it aren’t picked up by packager’s agressive caching.
- Some other problem (I don’t know what it is) causes
import
generated bybabel-plugin-react-transform
to not be compiled into arequire
call.
Until we have better .babelrc
support in React Native, you should configure React Transform together with babel-loader
:
var fs = require('fs');
var path = require('path');
var webpack = require('webpack');
var config = {
debug: true,
devtool: 'source-map',
entry: {
'index.ios': ['./src/main.js'],
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js',
},
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
stage: 0,
plugins: []
}
}]
},
plugins: []
};
// Hot mode
if (process.env.HOT) {
config.devtool = 'eval';
config.entry['index.ios'].unshift('react-native-webpack-server/hot/entry');
config.entry['index.ios'].unshift('webpack/hot/only-dev-server');
config.entry['index.ios'].unshift('webpack-dev-server/client?http://localhost:8082');
config.output.publicPath = 'http://localhost:8082/';
config.plugins.unshift(new webpack.HotModuleReplacementPlugin());
// Note: enabling React Transform and React Transform HMR:
config.module.loaders[0].query.plugins.push('react-transform');
config.module.loaders[0].query.extra = {
'react-transform': [{
target: 'react-transform-hmr',
imports: ['react-native'],
locals: ['module']
}]
};
}
if (process.env.NODE_ENV === 'production') {
config.plugins.push(new webpack.optimize.OccurrenceOrderPlugin());
config.plugins.push(new webpack.optimize.UglifyJsPlugin());
}
module.exports = config;
See React Native Webpack Server examples for details.
MIT