diff --git a/Gemfile b/Gemfile
index 77b86575..a4879f2e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,7 +6,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "3.3.4"
gem "react_on_rails", "16.1.1"
-gem "shakapacker", "8.2.0"
+gem "shakapacker", "8.4.0"
# Bundle edge Rails instead: gem "rails", github: "rails/rails"
gem "listen"
diff --git a/Gemfile.lock b/Gemfile.lock
index b0cddd1d..a55f29f3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -390,7 +390,7 @@ GEM
websocket (~> 1.0)
semantic_range (3.1.0)
sexp_processor (4.17.1)
- shakapacker (8.2.0)
+ shakapacker (8.4.0)
activesupport (>= 5.2)
package_json
rack-proxy (>= 0.6.1)
@@ -499,7 +499,7 @@ DEPENDENCIES
scss_lint
sdoc
selenium-webdriver (~> 4)
- shakapacker (= 8.2.0)
+ shakapacker (= 8.4.0)
spring
spring-commands-rspec
stimulus-rails (~> 1.3)
diff --git a/Procfile.dev b/Procfile.dev
index 20453bbe..650af5e4 100644
--- a/Procfile.dev
+++ b/Procfile.dev
@@ -1,7 +1,5 @@
# Procfile for development using HMR
# You can run these commands in separate shells
-rescript: yarn res:dev
-redis: redis-server
rails: bundle exec rails s -p 3000
-wp-client: HMR=true RAILS_ENV=development NODE_ENV=development bin/shakapacker-dev-server
-wp-server: bundle exec rake react_on_rails:locale && HMR=true SERVER_BUNDLE_ONLY=yes bin/shakapacker --watch
+wp-client: WEBPACK_SERVE=true bin/shakapacker-dev-server
+wp-server: SERVER_BUNDLE_ONLY=yes bin/shakapacker --watch
diff --git a/Procfile.dev-prod-assets b/Procfile.dev-prod-assets
index 096efc60..5e970472 100644
--- a/Procfile.dev-prod-assets
+++ b/Procfile.dev-prod-assets
@@ -1,10 +1,8 @@
-# You can run these commands in separate shells
-web: bin/rails s -p 3001
-redis: redis-server
+# Procfile for development with production assets
+# Uses production-optimized, precompiled assets with development environment
+# Uncomment additional processes as needed for your app
-# Next line runs a watch process with webpack to compile the changed files.
-# When making frequent changes to client side assets, you will prefer building webpack assets
-# upon saving rather than when you refresh your browser page.
-# Note, if using React on Rails localization you will need to run
-# `bundle exec rake react_on_rails:locale` before you run bin/shakapacker
-webpack: sh -c 'bundle exec rake react_on_rails:locale && rm -rf public/packs/* || true && bin/shakapacker -w'
+rails: bundle exec rails s -p 3001
+# sidekiq: bundle exec sidekiq -C config/sidekiq.yml
+# redis: redis-server
+# mailcatcher: mailcatcher --foreground
diff --git a/Procfile.dev-static-assets b/Procfile.dev-static-assets
index 4561761a..75152f0e 100644
--- a/Procfile.dev-static-assets
+++ b/Procfile.dev-static-assets
@@ -1,10 +1,2 @@
-# You can run these commands in separate shells
-web: bin/rails s -p 3000
-redis: redis-server
-
-# Next line runs a watch process with webpack to compile the changed files.
-# When making frequent changes to client side assets, you will prefer building webpack assets
-# upon saving rather than when you refresh your browser page.
-# Note, if using React on Rails localization you will need to run
-# `bundle exec rake react_on_rails:locale` before you run bin/shakapacker
-webpack: sh -c 'bundle exec rake react_on_rails:locale && rm -rf public/packs/* || true && bin/shakapacker -w'
+web: bin/rails server -p 3000
+js: bin/shakapacker --watch
diff --git a/app/controllers/hello_world_controller.rb b/app/controllers/hello_world_controller.rb
new file mode 100644
index 00000000..ad09c5ef
--- /dev/null
+++ b/app/controllers/hello_world_controller.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class HelloWorldController < ApplicationController
+ layout "hello_world"
+
+ def index
+ @hello_world_props = { name: "Stranger" }
+ end
+end
diff --git a/app/javascript/generated b/app/javascript/generated
new file mode 120000
index 00000000..ec645461
--- /dev/null
+++ b/app/javascript/generated
@@ -0,0 +1 @@
+../../client/app/generated
\ No newline at end of file
diff --git a/app/javascript/packs/generated b/app/javascript/packs/generated
new file mode 120000
index 00000000..64ef33c0
--- /dev/null
+++ b/app/javascript/packs/generated
@@ -0,0 +1 @@
+../../../client/app/packs/generated
\ No newline at end of file
diff --git a/app/javascript/packs/server-bundle.js b/app/javascript/packs/server-bundle.js
new file mode 100644
index 00000000..28a58fd4
--- /dev/null
+++ b/app/javascript/packs/server-bundle.js
@@ -0,0 +1,3 @@
+// import statement added by react_on_rails:generate_packs rake task
+import "./../generated/server-bundle-generated.js"
+// Placeholder comment - auto-generated imports will be prepended here by react_on_rails:generate_packs
diff --git a/app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css b/app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css
new file mode 100644
index 00000000..1983caaa
--- /dev/null
+++ b/app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css
@@ -0,0 +1,4 @@
+.bright {
+ color: green;
+ font-weight: bold;
+}
diff --git a/app/views/layouts/hello_world.html.erb b/app/views/layouts/hello_world.html.erb
new file mode 100644
index 00000000..59a52bad
--- /dev/null
+++ b/app/views/layouts/hello_world.html.erb
@@ -0,0 +1,15 @@
+
+
+
+ ReactOnRailsWithShakapacker
+ <%= csrf_meta_tags %>
+
+
+ <%= stylesheet_pack_tag %>
+ <%= javascript_pack_tag %>
+
+
+
+ <%= yield %>
+
+
diff --git a/babel.config.js b/babel.config.js
index 6e2c3800..9953e2a5 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,32 +1,36 @@
+// The source code including full typescript support is available at:
+// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/babel.config.js
+
module.exports = function (api) {
- const defaultConfigFunc = require('shakapacker/package/babel/preset.js');
- const resultConfig = defaultConfigFunc(api);
- const isProductionEnv = api.env('production');
+ const defaultConfigFunc = require('shakapacker/package/babel/preset.js')
+ const resultConfig = defaultConfigFunc(api)
+ const isProductionEnv = api.env('production')
const changesOnDefault = {
presets: [
[
'@babel/preset-react',
{
- runtime: 'automatic',
development: !isProductionEnv,
useBuiltIns: true,
- },
- ],
+ runtime: 'automatic'
+ }
+ ]
].filter(Boolean),
plugins: [
- process.env.WEBPACK_SERVE && 'react-refresh/babel',
- isProductionEnv && [
- 'babel-plugin-transform-react-remove-prop-types',
+ // Enable React Refresh (Fast Refresh) only when webpack-dev-server is running (HMR mode)
+ // This prevents React Refresh from trying to connect when using static compilation
+ !isProductionEnv && process.env.WEBPACK_SERVE && 'react-refresh/babel',
+ isProductionEnv && ['babel-plugin-transform-react-remove-prop-types',
{
- removeImport: true,
- },
- ],
+ removeImport: true
+ }
+ ]
].filter(Boolean),
- };
+ }
- resultConfig.presets = [...resultConfig.presets, ...changesOnDefault.presets];
- resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins];
+ resultConfig.presets = [...resultConfig.presets, ...changesOnDefault.presets]
+ resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins ]
- return resultConfig;
-};
+ return resultConfig
+}
diff --git a/config/initializers/react_on_rails.rb b/config/initializers/react_on_rails.rb
index 2a1faceb..f1b1a866 100644
--- a/config/initializers/react_on_rails.rb
+++ b/config/initializers/react_on_rails.rb
@@ -1,90 +1,67 @@
# frozen_string_literal: true
-# Shown below are the defaults for configuration
-ReactOnRails.configure do |config|
- # Auto-registration configuration for v16
- config.components_subdirectory = "ror_components"
- config.auto_load_bundle = true
-
- config.build_test_command = "RAILS_ENV=test bin/shakapacker"
- config.build_production_command = "RAILS_ENV=production NODE_ENV=production bin/shakapacker"
+# See https://github.com/shakacode/react_on_rails/blob/master/docs/guides/configuration.md
+# for many more options.
- # This is the file used for server rendering of React when using `(prerender: true)`
- # If you are never using server rendering, you may set this to "".
- # If you are using the same file for client and server rendering, having this set probably does
- # not affect performance.
- config.server_bundle_js_file = "server-bundle.js"
+ReactOnRails.configure do |config|
+ # This configures the script to run to build the production assets by webpack. Set this to nil
+ # if you don't want react_on_rails building this file for you.
+ # If nil, then the standard shakacode/shakapacker assets:precompile will run
+ # config.build_production_command = nil
- # Server bundle output path for private SSR bundles (React on Rails 16+)
- # This keeps server bundles separate from public assets for security
- # Using the default from React on Rails docs
- config.server_bundle_output_path = "ssr-generated"
+ ################################################################################
+ ################################################################################
+ # TEST CONFIGURATION OPTIONS
+ # Below options are used with the use of this test helper:
+ # ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
+ ################################################################################
- # React on Rails 16 compatibility: Workaround for removed error handling
+ # If you are using this in your spec_helper.rb (or rails_helper.rb):
#
- # BREAKING CHANGE in v16: React on Rails 14.2.1 had robust error handling that would
- # fallback to the Shakapacker output path when bundle lookup failed. This was removed
- # in v16.0.1.rc.2, causing it to look in the wrong directory during tests.
+ # ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
#
- # This configuration tells React on Rails where to find bundles in test environment.
- # Without this, it defaults to public/webpack/test/ instead of public/packs/
- config.generated_assets_dir = Rails.public_path.join("packs").to_s if Rails.env.test?
+ # with rspec then this controls what npm command is run
+ # to automatically refresh your webpack assets on every test run.
+ #
+ # Alternately, you can remove the `ReactOnRails::TestHelper.configure_rspec_to_compile_assets`
+ # and set the config/shakapacker.yml option for test to true.
+ config.build_test_command = "RAILS_ENV=test bin/shakapacker"
################################################################################
- # CLIENT RENDERING OPTIONS
- # Below options can be overriden by passing options to the react_on_rails
- # `render_component` view helper method.
- ################################################################################
-
- # Default is false. Can be overriden at the component level.
- # Set to false for debugging issues before turning on to true.
- config.prerender = true
-
- # default is true for development, off otherwise
- config.trace = Rails.env.development?
-
################################################################################
# SERVER RENDERING OPTIONS
- # Applicable options can be overriden by passing options to the react_on_rails
- # `render_component` view helper method.
################################################################################
+ # This is the file used for server rendering of React when using `(prerender: true)`
+ # If you are never using server rendering, you should set this to "".
+ # Note, there is only one server bundle, unlike JavaScript where you want to minimize the size
+ # of the JS sent to the client. For the server rendering, React on Rails creates a pool of
+ # JavaScript execution instances which should handle any component requested.
+ #
+ # While you may configure this to be the same as your client bundle file, this file is typically
+ # different. You should have ONE server bundle which can create all of your server rendered
+ # React components.
+ #
+ config.server_bundle_js_file = "server-bundle.js"
- # If set to true, this forces Rails to reload the server bundle if it is modified
- config.development_mode = Rails.env.development?
-
- # For server rendering. This can be set to false so that server side messages are discarded.
- # Default is true. Be cautious about turning this off.
- config.replay_console = true
-
- # Default is true. Logs server rendering messages to Rails.logger.info
- config.logging_on_server = true
-
- # Change to true to raise exception on server if the JS code throws. Let's do this only if not
- # in production, as the JS code might still work on the client and we don't want to blow up the
- # whole Rails page.
- config.raise_on_prerender_error = !Rails.env.production?
+ # Configure where server bundles are output. Defaults to "ssr-generated".
+ # This should match your webpack configuration for server bundles.
+ config.server_bundle_output_path = "ssr-generated"
- # Server rendering only (not for render_component helper)
- # You can configure your pool of JS virtual machines and specify where it should load code:
- # On MRI, use `therubyracer` for the best performance
- # (see [discussion](https://github.com/reactjs/react-rails/pull/290))
- # On MRI, you'll get a deadlock with `pool_size` > 1
- # If you're using JRuby, you can increase `pool_size` to have real multi-threaded rendering.
- config.server_renderer_pool_size = 1 # increase if you're on JRuby
- config.server_renderer_timeout = 20 # seconds
+ # Enforce that server bundles are only loaded from private (non-public) directories.
+ # When true, server bundles will only be loaded from the configured server_bundle_output_path.
+ # This is recommended for production to prevent server-side code from being exposed.
+ config.enforce_private_server_bundles = true
################################################################################
- # I18N OPTIONS
- ################################################################################
- # Replace the following line to the location where you keep translation.js & default.js.
- config.i18n_dir = Rails.root.join("client/app/libs/i18n")
-
################################################################################
- # MISCELLANEOUS OPTIONS
+ # FILE SYSTEM BASED COMPONENT REGISTRY
################################################################################
-
- # This allows you to add additional values to the Rails Context. Implement one static method
- # called `custom_context(view_context)` and return a Hash.
- config.rendering_extension = nil
- config.i18n_output_format = "js"
+ # `components_subdirectory` is the name of the matching directories that contain automatically registered components
+ # for use in the Rails views. The default is nil, you can enable the feature by updating it in the next line.
+ config.components_subdirectory = "ror_components"
+ #
+ # For automated component registry, `render_component` view helper method tries to load bundle for component from
+ # generated directory. default is false, you can pass option at the time of individual usage or update the default
+ # in the following line
+ config.auto_load_bundle = true
end
diff --git a/config/routes.rb b/config/routes.rb
index 1d8c7b7a..946aff4c 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
Rails.application.routes.draw do
+ get 'hello_world', to: 'hello_world#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
# Serve websocket cable requests in-process
diff --git a/config/shakapacker.yml b/config/shakapacker.yml
index ebc5e4c5..61c81837 100644
--- a/config/shakapacker.yml
+++ b/config/shakapacker.yml
@@ -1,47 +1,109 @@
# Note: You must restart bin/shakapacker-dev-server for changes to take effect
+# This file contains the defaults used by shakapacker.
default: &default
source_path: client/app
+
+ # You can have a subdirectory of the source_path, like 'packs' (recommended).
+ # Alternatively, you can use '/' to use the whole source_path directory.
+ # Notice that this is a relative path to source_path
source_entry_path: packs
+
+ # If nested_entries is true, then we'll pick up subdirectories within the source_entry_path.
+ # You cannot set this option to true if you set source_entry_path to '/'
+ nested_entries: true
+
+ # While using a File-System-based automated bundle generation feature, miscellaneous warnings suggesting css order
+ # conflicts may arise due to the mini-css-extract-plugin. For projects where css ordering has been mitigated through
+ # consistent use of scoping or naming conventions, the css order warnings can be disabled by setting
+ # css_extract_ignore_order_warnings to true
+ css_extract_ignore_order_warnings: false
+
public_root_path: public
public_output_path: packs
cache_path: tmp/shakapacker
webpack_compile_output: true
- nested_entries: true
+ # See https://github.com/shakacode/shakapacker#deployment
+ shakapacker_precompile: true
+
+ # Location for manifest.json, defaults to {public_output_path}/manifest.json if unset
+ # manifest_path: public/packs/manifest.json
- # Additional paths webpack should lookup modules
+ # Additional paths webpack should look up modules
# ['app/assets', 'engine/foo/app/assets']
additional_paths: []
# Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false
-
- # Use the config.build_production_command in config/initializers/react_on_rails.rb
- shakapacker_precompile: false
+
+ # Select loader to use, available options are 'babel' (default), 'swc' or 'esbuild'
+ webpack_loader: 'babel'
+
+ # Raises an error if there is a mismatch in the shakapacker gem and npm package being used
+ ensure_consistent_versioning: true
+
+ # Select whether the compiler will use SHA digest ('digest' option) or most recent modified timestamp ('mtime') to determine freshness
+ compiler_strategy: digest
+
+ # Select whether the compiler will always use a content hash and not just in production
+ # Don't use contentHash except for production for performance
+ # https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling
+ useContentHash: false
+
+ # Setting the asset host here will override Rails.application.config.asset_host.
+ # Here, you can set different asset_host per environment. Note that
+ # SHAKAPACKER_ASSET_HOST will override both configurations.
+ # asset_host: custom-path
+
+ # Utilizing webpack-subresource-integrity plugin, will generate integrity hashes for all entries in manifest.json
+ # https://github.com/waysact/webpack-subresource-integrity/tree/main/webpack-subresource-integrity
+ integrity:
+ enabled: false
+ # Which cryptographic function(s) to use, for generating the integrity hash(es). Default sha-384. Other possible values sha256, sha512
+ hash_functions: ["sha384"]
+ # Default "anonymous". Other possible value "use-credentials"
+ # https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity#cross-origin_resource_sharing_and_subresource_integrity
+ cross_origin: "anonymous"
development:
<<: *default
- # This is false since we're running `bin/shakapacker -w` in Procfile.dev-setic
- compile: false
+ compile: true
+ compiler_strategy: mtime
# Reference: https://webpack.js.org/configuration/dev-server/
+ # Keys not described there are documented inline and in https://github.com/shakacode/shakapacker/
dev_server:
- https: false
+ # For running dev server with https, set `server: https`.
+ # server: https
+
host: localhost
port: 3035
# Hot Module Replacement updates modules while the application is running without a full reload
+ # Used instead of the `hot` key in https://webpack.js.org/configuration/dev-server/#devserverhot
hmr: true
+ # If HMR is on, CSS will be inlined by delivering it as part of the script payload via style-loader. Be sure
+ # that you add style-loader to your project dependencies.
+ #
+ # If you want to instead deliver CSS via with the mini-css-extract-plugin, set inline_css to false.
+ # In that case, style-loader is not needed as a dependency.
+ #
+ # mini-css-extract-plugin is a required dependency in both cases.
+ inline_css: true
+ # Defaults to the inverse of hmr. Uncomment to manually set this.
+ # live_reload: true
client:
# Should we show a full-screen overlay in the browser when there are compiler errors or warnings?
overlay: true
# May also be a string
# webSocketURL:
- # hostname: "0.0.0.0"
- # pathname: "/ws"
+ # hostname: '0.0.0.0'
+ # pathname: '/ws'
# port: 8080
+ # Should we use gzip compression?
compress: true
# Note that apps that do not check the host are vulnerable to DNS rebinding attacks
- allowed_hosts: [ 'localhost' ]
+ allowed_hosts: 'auto'
+ # Shows progress and colorizes output of bin/shakapacker[-dev-server]
pretty: true
headers:
'Access-Control-Allow-Origin': '*'
@@ -53,11 +115,17 @@ test:
<<: *default
compile: true
+ # Compile test packs to a separate directory
+ public_output_path: packs-test
+
production:
<<: *default
# Production depends on precompilation of packs prior to booting for performance.
compile: false
+ # Use content hash for naming assets. Cannot be overridden in production.
+ useContentHash: true
+
# Cache manifest.json for performance
cache_manifest: true
diff --git a/config/webpack/alias.js b/config/webpack/alias.js
index 5645c184..8d904c85 100644
--- a/config/webpack/alias.js
+++ b/config/webpack/alias.js
@@ -4,6 +4,7 @@ module.exports = {
resolve: {
alias: {
Assets: resolve(__dirname, '..', '..', 'client', 'app', 'assets'),
+ libs: resolve(__dirname, '..', '..', 'client', 'app', 'libs'),
},
},
};
diff --git a/config/webpack/clientWebpackConfig.js b/config/webpack/clientWebpackConfig.js
index d1e29def..ad6b4383 100644
--- a/config/webpack/clientWebpackConfig.js
+++ b/config/webpack/clientWebpackConfig.js
@@ -1,5 +1,5 @@
-// The source code including full typescript support is available at:
-// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/clientWebpackConfig.js
+// The source code including full typescript support is available at:
+// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/clientWebpackConfig.js
const webpack = require('webpack');
const commonWebpackConfig = require('./commonWebpackConfig');
@@ -25,4 +25,3 @@ const configureClient = () => {
};
module.exports = configureClient;
-
diff --git a/config/webpack/commonWebpackConfig.js b/config/webpack/commonWebpackConfig.js
index b1d64ca2..58f33ef3 100644
--- a/config/webpack/commonWebpackConfig.js
+++ b/config/webpack/commonWebpackConfig.js
@@ -1,10 +1,12 @@
-// The source code including full typescript support is available at:
-// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/commonWebpackConfig.js
+// The source code including full typescript support is available at:
+// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/commonWebpackConfig.js
// Common configuration applying to client and server configuration
const { generateWebpackConfig, merge } = require('shakapacker');
+const aliasConfig = require('./alias');
const baseClientWebpackConfig = generateWebpackConfig();
+
const commonOptions = {
resolve: {
extensions: ['.css', '.ts', '.tsx'],
@@ -57,7 +59,6 @@ if (sassLoaderIndex !== -1) {
baseClientWebpackConfig.module.rules[scssConfigIndex].use.push(sassLoaderConfig);
// Copy the object using merge b/c the baseClientWebpackConfig and commonOptions are mutable globals
-const commonWebpackConfig = () => merge({}, baseClientWebpackConfig, commonOptions, ignoreWarningsConfig);
-
-module.exports = commonWebpackConfig;
+const commonWebpackConfig = () => merge({}, baseClientWebpackConfig, commonOptions, aliasConfig, ignoreWarningsConfig);
+module.exports = commonWebpackConfig;
\ No newline at end of file
diff --git a/config/webpack/development.js b/config/webpack/development.js
index 6b6b7609..99e63775 100644
--- a/config/webpack/development.js
+++ b/config/webpack/development.js
@@ -1,29 +1,22 @@
-// The source code including full typescript support is available at:
-// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/development.js
-
-process.env.NODE_ENV = process.env.NODE_ENV || 'development';
+// The source code including full typescript support is available at:
+// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/development.js
const { devServer, inliningCss } = require('shakapacker');
-const webpackConfig = require('./webpackConfig');
+const generateWebpackConfigs = require('./generateWebpackConfigs');
const developmentEnvOnly = (clientWebpackConfig, _serverWebpackConfig) => {
- // plugins
- if (inliningCss) {
- // Note, when this is run, we're building the server and client bundles in separate processes.
- // Thus, this plugin is not applied to the server bundle.
-
+ // React Refresh (Fast Refresh) setup - only when webpack-dev-server is running (HMR mode)
+ // This matches the condition in generateWebpackConfigs.js and babel.config.js
+ if (process.env.WEBPACK_SERVE) {
// eslint-disable-next-line global-require
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
clientWebpackConfig.plugins.push(
new ReactRefreshWebpackPlugin({
- overlay: {
- sockPort: devServer.port,
- },
+ // Use default overlay configuration for better compatibility
}),
);
}
};
-module.exports = webpackConfig(developmentEnvOnly);
-
+module.exports = generateWebpackConfigs(developmentEnvOnly);
diff --git a/config/webpack/generateWebpackConfigs.js b/config/webpack/generateWebpackConfigs.js
new file mode 100644
index 00000000..08e5f376
--- /dev/null
+++ b/config/webpack/generateWebpackConfigs.js
@@ -0,0 +1,37 @@
+// The source code including full typescript support is available at:
+// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/webpackConfig.js
+
+const clientWebpackConfig = require('./clientWebpackConfig');
+const serverWebpackConfig = require('./serverWebpackConfig');
+
+const webpackConfig = (envSpecific) => {
+ const clientConfig = clientWebpackConfig();
+ const serverConfig = serverWebpackConfig();
+
+ if (envSpecific) {
+ envSpecific(clientConfig, serverConfig);
+ }
+
+ let result;
+ // For HMR, need to separate the the client and server webpack configurations
+ if (process.env.WEBPACK_SERVE || process.env.CLIENT_BUNDLE_ONLY) {
+ // eslint-disable-next-line no-console
+ console.log('[React on Rails] Creating only the client bundles.');
+ result = clientConfig;
+ } else if (process.env.SERVER_BUNDLE_ONLY) {
+ // eslint-disable-next-line no-console
+ console.log('[React on Rails] Creating only the server bundle.');
+ result = serverConfig;
+ } else {
+ // default is the standard client and server build
+ // eslint-disable-next-line no-console
+ console.log('[React on Rails] Creating both client and server bundles.');
+ result = [clientConfig, serverConfig];
+ }
+
+ // To debug, uncomment next line and inspect "result"
+ // debugger
+ return result;
+};
+
+module.exports = webpackConfig;
diff --git a/config/webpack/production.js b/config/webpack/production.js
index 9faa5179..dce3586b 100644
--- a/config/webpack/production.js
+++ b/config/webpack/production.js
@@ -1,12 +1,10 @@
-// The source code including full typescript support is available at:
-// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/production.js
+// The source code including full typescript support is available at:
+// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/production.js
-process.env.NODE_ENV = process.env.NODE_ENV || 'production';
-
-const webpackConfig = require('./webpackConfig');
+const generateWebpackConfigs = require('./generateWebpackConfigs');
const productionEnvOnly = (_clientWebpackConfig, _serverWebpackConfig) => {
// place any code here that is for production only
};
-module.exports = webpackConfig(productionEnvOnly);
+module.exports = generateWebpackConfigs(productionEnvOnly);
diff --git a/config/webpack/serverWebpackConfig.js b/config/webpack/serverWebpackConfig.js
index a6e9631d..26147c66 100644
--- a/config/webpack/serverWebpackConfig.js
+++ b/config/webpack/serverWebpackConfig.js
@@ -1,8 +1,7 @@
-// The source code including full typescript support is available at:
-// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/serverWebpackConfig.js
+// The source code including full typescript support is available at:
+// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/serverWebpackConfig.js
-const path = require('path');
-const { config } = require('shakapacker');
+const { merge, config } = require('shakapacker');
const commonWebpackConfig = require('./commonWebpackConfig');
const webpack = require('webpack');
@@ -46,15 +45,14 @@ const configureServer = () => {
// Custom output for the server-bundle that matches the config in
// config/initializers/react_on_rails.rb
- // Output to a private directory for SSR bundles (not in public/)
- // Using the default React on Rails path: ssr-generated
+ // Server bundles are output to a private directory (not public) for security
serverWebpackConfig.output = {
filename: 'server-bundle.js',
globalObject: 'this',
// If using the React on Rails Pro node server renderer, uncomment the next line
// libraryTarget: 'commonjs2',
- path: path.resolve(__dirname, '../../ssr-generated'),
- publicPath: config.publicPath,
+ path: require('path').resolve(__dirname, '../../ssr-generated'),
+ // No publicPath needed since server bundles are not served via web
// https://webpack.js.org/configuration/output/#outputglobalobject
};
diff --git a/config/webpack/test.js b/config/webpack/test.js
index 8c378b39..eb449326 100644
--- a/config/webpack/test.js
+++ b/config/webpack/test.js
@@ -1,7 +1,10 @@
-const webpackConfig = require('./webpackConfig');
+// The source code including full typescript support is available at:
+// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/test.js
+
+const generateWebpackConfigs = require('./generateWebpackConfigs')
const testOnly = (_clientWebpackConfig, _serverWebpackConfig) => {
// place any code here that is for test only
-};
+}
-module.exports = webpackConfig(testOnly);
+module.exports = generateWebpackConfigs(testOnly)
diff --git a/package.json b/package.json
index afa73247..ebb99b62 100644
--- a/package.json
+++ b/package.json
@@ -93,7 +93,7 @@
"sass": "^1.58.3",
"sass-loader": "^13.3.2",
"sass-resources-loader": "^2.2.5",
- "shakapacker": "8.2.0",
+ "shakapacker": "8.4.0",
"stimulus": "^3.0.1",
"style-loader": "^3.3.1",
"tailwindcss": "^3.3.3",
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index 21f7a611..27a7fcc9 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -38,6 +38,11 @@
Rails.root.glob("spec/support/**/*.rb").sort.each { |f| require f }
RSpec.configure do |config|
+ # Ensure that if we are running js tests, we are using latest webpack assets
+ # This will use the defaults of :js and :server_rendering meta tags
+ ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
+end
+
config.include FactoryBot::Syntax::Methods
# Ensure that if we are running js tests, we are using latest webpack assets
# This will use the defaults of :js and :server_rendering meta tags
diff --git a/yarn.lock b/yarn.lock
index 0189edd8..62a91c94 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2905,9 +2905,9 @@ balanced-match@^1.0.0:
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
baseline-browser-mapping@^2.8.3:
- version "2.8.8"
- resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.8.tgz#ca0de7b23bf9c49d72e21dcbfba26f2bb223ea2e"
- integrity sha512-be0PUaPsQX/gPWWgFsdD+GFzaoig5PXaUC1xLkQiYdDnANU8sMnHoQd8JhbJQuvTWrWLyeFN9Imb5Qtfvr4RrQ==
+ version "2.8.9"
+ resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.9.tgz#fd0b8543c4f172595131e94965335536b3101b75"
+ integrity sha512-hY/u2lxLrbecMEWSB0IpGzGyDyeoMFQhCvZd2jGFSE5I17Fh01sYUBPCJtkWERw7zrac9+cIghxm/ytJa2X8iA==
batch@0.6.1:
version "0.6.1"
@@ -3888,9 +3888,9 @@ ee-first@1.1.1:
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
electron-to-chromium@^1.5.218:
- version "1.5.226"
- resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.226.tgz#2f9f795829dc5c5d1c5387f4c2648ca180cc933d"
- integrity sha512-0tS/r72Ze0WUBiDwnqw4X43TxA7gEuZg0kFwLthoCzkshIbNQFjkf6D8xEzBe6tY6Y65fUhZIuNedTugw+11Lw==
+ version "1.5.227"
+ resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.227.tgz#c81b6af045b0d6098faed261f0bd611dc282d3a7"
+ integrity sha512-ITxuoPfJu3lsNWUi2lBM2PaBPYgH3uqmxut5vmBxgYvyI4AlJ6P3Cai1O76mOrkJCBzq0IxWg/NtqOrpu/0gKA==
emittery@^0.13.1:
version "0.13.1"
@@ -8263,10 +8263,10 @@ setprototypeof@1.2.0:
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
-shakapacker@8.2.0:
- version "8.2.0"
- resolved "https://registry.npmjs.org/shakapacker/-/shakapacker-8.2.0.tgz#c7bed87b8be2ae565cfe616f68552be545c77e14"
- integrity sha512-Ct7BFqJVnKbxdqCzG+ja7Q6LPt/PlB7sSVBfG5jsAvmVCADM05cuoNwEgYNjFGKbDzHAxUqy5XgoI9Y030+JKQ==
+shakapacker@8.4.0:
+ version "8.4.0"
+ resolved "https://registry.npmjs.org/shakapacker/-/shakapacker-8.4.0.tgz#be37a2adba5a090f581811b8c0c1a00f2e227580"
+ integrity sha512-ZfuxfHxy5tdjv7tCdRZHJKJQLDFwvFXOVBVUj150zgNuRKUlOAyXzOBp9/G5hUhu4MLzuPAif/fuKOdjnZeVtw==
dependencies:
js-yaml "^4.1.0"
path-complete-extname "^1.0.0"