Ok, after some noodling around a good approach looks to be to use the old customMiddleware
option of sails's http
middleware configuration, but only for the development environment kept in config/env/development.js
.
1) Install react and react-dom (if you haven't already):
$ npm install react react-dom --save
2) Install webpack, hot module reloading (& ES6) support for sails:
$ npm install sails-webpack babel-core babel-loader \
babel-plugin-syntax-class-properties babel-plugin-syntax-decorators \
babel-plugin-syntax-object-rest-spread \
babel-plugin-transform-class-properties \
babel-plugin-transform-decorators-legacy \
babel-plugin-transform-object-rest-spread \
babel-preset-es2015 babel-preset-react \
copy-webpack-plugin file-loader --save
3) Install react transforms and middleware for hot module reloading:
$ npm install babel-plugin-react-transform
react-transform-catch-errors react-transform-hmr \
webpack-dev-middleware webpack-hot-middleware --save-dev
4) Disable the built-in grunt hook that would normally link your application:
// .sailsrc
{
"hooks": {
"grunt": false
}
}
5) Configure sails webpack configuration:
// config/webpack.js
var webpack = require('webpack');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var path = require('path');
// compile js assets into a single bundle file
module.exports.webpack = {
options: {
context: path.join(__dirname, '..'),
devtool: 'eval',
entry: [
'./assets/js',
'webpack-hot-middleware/client'
],
output: {
path: path.resolve(__dirname, '../.tmp/public'),
publicPath: "/",
filename: 'bundle.js'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
/* Copy sails.io.js unmolested: */
new CopyWebpackPlugin([
{
from: 'assets/js/dependencies',
to: 'dependencies',
force: true
}
]),
],
resolve: {
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(bower_components|node_modules)/,
loader: 'babel',
},
{ test: /\.css$/, loader: 'style!css' },
{
test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$|\.wav$|\.mp3$/,
loader: "file" }
]
}
},
// docs: https://webpack.github.io/docs/node.js-api.html#compiler
watchOptions: {
aggregateTimeout: 300
}
};
6) Configure project-wide .babelrc
to use hot module reload in development mode:
{
"presets": [
"es2015",
"react",
],
"plugins": [
"syntax-class-properties",
"syntax-decorators",
"syntax-object-rest-spread",
"transform-class-properties",
"transform-decorators-legacy",
"transform-object-rest-spread"
],
"env": {
"development": {
"plugins": [["react-transform", {
"transforms": [{
"transform": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}]
}]]
}
}
}
7) Lastly, add http.customMiddleware
configuration to sails's config/env/development.js
:
module.exports = {
/* ... */
/*
* Enable webpack hotloading while in development mode:
*/
http: {
customMiddleware: function (app) {
var webpack = require('webpack');
var webpackConfig = require('../webpack').webpack.options;
var compiler = webpack(webpackConfig);
app.use(require("webpack-dev-middleware")(compiler,
{
noInfo: true,
publicPath: webpackConfig.output.publicPath
}
));
app.use(require("webpack-hot-middleware")(compiler,
{ reload: true }
));
},
}
/* ... */
};
Presuming you've got a react application in assets/js/index.jsx
(or similar) and a view which includes your bundle.js
file you should be able to simply $ sails lift
and see the following on your brower's development console:
|> Now connected to Sails.
\___/ For help, see: http://bit.ly/1DmTvgK
(using browser SDK @v0.11.0)
client.js:51 [HMR] connected
And boom you should be in business!