The title of this post may not be very clear, but I appreciate your patience.
I am currently in the process of setting up React for an older Rails application that uses static ERBs. Due to the size of the project, I am gradually transitioning towards a Single Page Application (SPA) architecture by replacing components on different pages.
My current setup involves using webpack to compile a bundle file and output it to the assets directory. I then load this bundle file on the page, relying on the assets pipeline for caching (not the most ideal setup, but sufficient for now). For pages containing React components, I have <div>
elements where specific components will be appended. For example:
<body>
<div>some other ERB, HTML stuff</div>
<div>more other ERB, HTML stuff</div>
<div id='react-component-1'></div>
<div id='react-component-2'></div>
</body>
This setup works as a basic foundation. However, to speed up development, I would like to implement hot module reloading (HMR). But since I am not serving the entire page, I need to write the bundle file to disk so Rails can access it. This also means I cannot use webpack-dev-server.
Is there a way to set up HMR in this kind of configuration?
Potential options include:
- Reloading the bundle file periodically (I've tried appending a new script tag and removing the old one, but while the script file is downloaded with a status code of 200, the updated scripts are not being loaded)
- Programmatically refreshing the page and storing serialized state in session storage (less than ideal, as it refreshes other parts of the static page as well)
- Exploring a method to only serve the bundle file through webpack-dev-server
Edit
After following @SamHH's answer, it seems the bundle file is unable to load (404 error). There might be an issue with my path configuration.
In my webpack configuration, the output path is set to:
'../../app/assets/webpack/admin'
The publicPath is set to:
/admin/
Although I attempted to match these paths in the proxy
option, it didn't work as expected. From the network tab, it appears that the file was being loaded from /javascripts/...
Here is a snippet of my webpack config:
const config = {
entry: {
bundle: './apps/appsRegistration',
vendor: VENDOR_LIBS
},
output: {
filename: '[name].js',
path: pathLib.resolve(__dirname, '../../app/assets/webpack/admin'),
publicPath: '/admin/'
},
resolve: {
extensions: ['.js', '.jsx'],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.EnvironmentPlugin({ NODE_ENV: 'development' }),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor'
}),
],
module: {
rules: [
{
test: /\.jsx?$/,
use: 'babel-loader',
exclude: /node_modules/,
},
],
},
externals: {
react: 'React',
'react-dom': 'ReactDOM',
redux: 'Redux',
'react-redux': 'ReactRedux',
'redux-thunk': 'ReduxThunk'
},
devServer: {
port: 9000,
disableHostCheck: true,
proxy: {
'!/admin/**': {
target: 'http://localhost:3000',
secure: false
}
},
hot: true
}
};