Pretty simple:
- Follow the steps to migrate to version 9 (except installing 10.x instead of 9.x)
- If you have
react_component
returning hashes, then switch toreact_component_hash
instead
- Bump your ReactOnRails versions in
Gemfile
&package.json
- In
/config/initializers/react_on_rails.rb
, rename:- config.npm_build_test_command ==> config.build_test_command
- config.npm_build_production_command ==> config.build_production_command
- Also create
config.node_modules_location
and set it to"client"
...and you're done.
Reason for doing this: This enables your webpack bundles to bypass the Rails asset pipeline and it's extra minification, enabling you to use source-maps in production, while still maintaining total control over everything in the client directory
For an example of upgrading, see react-webpack-rails-tutorial/pull/416.
-
Breaking Configuration Changes
- Added
config.node_modules_location
which defaults to""
if Webpacker is installed. You may want to set this to 'client'to
config/initializers/react_on_rails.rbto keep your node_modules inside of
/client` - Renamed
- config.npm_build_test_command ==> config.build_test_command
- config.npm_build_production_command ==> config.build_production_command
- Added
-
Update the gemfile. Switch over to using the webpacker gem.
gem "webpacker"
-
Update for the renaming in the
WebpackConfigLoader
in your webpack configuration. You will need to rename the following object properties:- webpackOutputPath ==> output.path
- webpackPublicOutputDir ==> output.publicPath
- hotReloadingUrl ==> output.publicPathWithHost
- hotReloadingHostname ==> settings.dev_server.host
- hotReloadingPort ==> settings.dev_server.port
- hmr ==> settings.dev_server.hmr
- manifest ==> Remove this one. We use the default for Webpack of manifest.json
- env ==> Use
const { env } = require('process');
- devBuild ==> Use
const devBuild = process.env.NODE_ENV !== 'production';
-
Edit your Webpack.config files:
- Change your Webpack output to be like this. Be sure to have the hash or chunkhash in the filename, unless the bundle is server side.:
const webpackConfigLoader = require('react-on-rails/webpackConfigLoader'); const configPath = resolve('..', 'config'); const { output, settings } = webpackConfigLoader(configPath); const hmr = settings.dev_server.hmr; const devBuild = process.env.NODE_ENV !== 'production'; output: { filename: isHMR ? '[name]-[hash].js' : '[name]-[chunkhash].js', chunkFilename: '[name]-[chunkhash].chunk.js', publicPath: output.publicPath, path: output.path, },
- Change your ManifestPlugin definition to something like the following
new ManifestPlugin({ publicPath: output.publicPath, writeToFileEmit: true }),
- Change your Webpack output to be like this. Be sure to have the hash or chunkhash in the filename, unless the bundle is server side.:
-
Find your
webpacker_lite.yml
and rename it towebpacker.yml
- Consider copying a default webpacker.yml setup such as https://github.com/shakacode/react-on-rails-v9-rc-generator/blob/master/config/webpacker.yml
- If you are not using the webpacker webpacker setup, be sure to put in
compile: false
in thedefault
section. - Alternately, if you are updating from webpacker_lite, you can manually change these:
- Add a default setting
cache_manifest: false
- For production, set:
cache_manifest: true
- Add a section like this under your development env:
Set hmr to your preference.
dev_server: host: localhost port: 3035 hmr: false
- See the example
spec/dummy/config/webpacker.yml
. - Remove keys
hot_reloading_host
andhot_reloading_enabled_by_default
. These are replaced by thedev_server
key. - Rename
webpack_public_output_dir
topublic_output_path
.
-
Edit your Procfile.dev
- Remove the env value WEBPACKER_DEV_SERVER as it's not used
- For hot loading:
- Set the
hmr
key in yourwebpacker.yml
totrue
.
- Set the
Unfortunately, this requires quite a few steps:
.gitignore
: add/public/webpack/*
Gemfile
: bumpreact_on_rails
and addwebpacker
- layout views: anything bundled by webpack will need to be requested by a
javascript_pack_tag
orstylesheet_pack_tag
config/initializers/assets.rb
: we no longer need to modifyRails.application.config.assets.paths
or append anything toRails.application.config.assets.precompile
.config/initializers/react_on_rails.rb
:- Delete
config.generated_assets_dir
. Webpacker's config now supplies this information - Replace
config.npm_build_(test|production)_command
withconfig.build_(test|production)_command
- Delete
config/webpacker.yml
: start with our example config (feel free to modify it as needed). I recommend setting dev_server.hmr to false however since HMR is currently broken.client/package.json
: bumpreact_on_rails
(I recommend bumpingwebpack
as well). You'll also needjs-yaml
if you're not already usingeslint
andwebpack-manifest-plugin
regardless.
- You'll need the following code to read data from the webpacker config:
const path = require('path');
const ManifestPlugin = require('webpack-manifest-plugin'); // we'll use this later
const webpackConfigLoader = require('react-on-rails/webpackConfigLoader');
const configPath = path.resolve('..', 'config');
const { output } = webpackConfigLoader(configPath);
- That output variable will be used for webpack's
output
rules:
output: {
filename: '[name]-[chunkhash].js', // [chunkhash] because we've got to do our own cache-busting now
path: output.path,
publicPath: output.publicPath,
},
- ...as well as for the output of plugins like
webpack-manifest-plugin
:
new ManifestPlugin({
publicPath: output.publicPath,
writeToFileEmit: true
}),
- If you're using referencing files or images with
url-loader
&file-loader
, their publicpaths will have to change as well:publicPath: '/webpack/',
- If you're using
css-loader
,webpack.optimize.CommonsChunkPlugin
, orextract-text-webpack-plugin
, they will also need cache-busting!
...and you're finally done!
- Make the same changes to
config/initializers/react_on_rails.rb as described above
- Upgrade RoR & add Webpacker in the Gemfile
- Upgrade RoR in the
client/package.json
- Run
bundle
- Run
rails webpacker:install
- Run
rails webpacker:install:react
- Run
rails g react_on_rails:install
- Move your entry point files to
app/javascript/packs
- Either:
- Move all your source code to
app/javascript/bundles
, move your linter configs to the root directory, and then delete theclient
directory - or just delete the webpack config and remove webpack, its loaders, and plugins from your
client/package.json
.
- Move all your source code to
...and you're done.