react_on_rails 17.1.0 → 17.2.0.rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.development_dependencies +2 -2
- data/Gemfile.lock +65 -73
- data/Steepfile +1 -0
- data/docs/agent/install-and-upgrade.md +8 -3
- data/docs/agent/rsc-adoption.md +3 -0
- data/lib/generators/react_on_rails/base_generator.rb +2 -1
- data/lib/generators/react_on_rails/generated_webpack_config_pair.rb +84 -0
- data/lib/generators/react_on_rails/generator_helper.rb +2 -4
- data/lib/generators/react_on_rails/generator_messages.rb +1 -1
- data/lib/generators/react_on_rails/install_generator.rb +2 -1
- data/lib/generators/react_on_rails/js_dependency_manager.rb +14 -14
- data/lib/generators/react_on_rails/pro/USAGE +14 -3
- data/lib/generators/react_on_rails/pro_generator.rb +1 -1
- data/lib/generators/react_on_rails/pro_setup.rb +41 -213
- data/lib/generators/react_on_rails/rsc_setup.rb +7 -16
- data/lib/generators/react_on_rails/templates/pro/base/config/initializers/react_on_rails_pro.rb.tt +1 -1
- data/lib/react_on_rails/agent_guardrails.rb +217 -39
- data/lib/react_on_rails/dev/process_manager.rb +14 -0
- data/lib/react_on_rails/dev/server_manager.rb +1727 -103
- data/lib/react_on_rails/doctor.rb +875 -44
- data/lib/react_on_rails/helper.rb +3 -3
- data/lib/react_on_rails/react_component/render_options.rb +5 -7
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +27 -116
- data/lib/react_on_rails/utils.rb +65 -0
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/version_checker/lockfile_resolution.rb +170 -0
- data/lib/react_on_rails/version_checker.rb +43 -22
- data/rakelib/run_rspec.rake +6 -1
- data/sig/react_on_rails/configuration.rbs +28 -26
- data/sig/react_on_rails/controller.rbs +2 -1
- data/sig/react_on_rails/dev/process_manager.rbs +1 -0
- data/sig/react_on_rails/dev/server_manager.rbs +150 -10
- data/sig/react_on_rails/git_utils.rbs +5 -1
- data/sig/react_on_rails/locales.rbs +4 -4
- data/sig/react_on_rails/prerender_error.rbs +2 -2
- data/sig/react_on_rails/test_helper.rbs +15 -1
- data/sig/react_on_rails/utils.rbs +2 -2
- data/sig/react_on_rails/version_checker/lockfile_resolution.rbs +31 -0
- data/sig/react_on_rails/version_checker.rbs +30 -7
- metadata +4 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "securerandom"
|
|
4
4
|
require_relative "generator_messages"
|
|
5
|
+
require_relative "generated_webpack_config_pair"
|
|
5
6
|
require "react_on_rails/node_renderer_procfile"
|
|
6
7
|
require "react_on_rails/pro_migration"
|
|
7
8
|
|
|
@@ -36,9 +37,8 @@ module ReactOnRails
|
|
|
36
37
|
# Loader helpers emitted by
|
|
37
38
|
# templates/base/base/config/webpack/serverWebpackConfig.js.tt.
|
|
38
39
|
#
|
|
39
|
-
# Keep
|
|
40
|
-
#
|
|
41
|
-
# the two must produce the same source text so drift is detectable (issue #4786).
|
|
40
|
+
# Keep these parity-test anchors byte-identical to the template (issue #4786).
|
|
41
|
+
# Migration recognition uses the entire rendered pair, never these snippets.
|
|
42
42
|
GET_LOADER_PATH_JS = <<~JS
|
|
43
43
|
// Normalizes an entry of a webpack/rspack `rule.use` array to its loader path.
|
|
44
44
|
// Entries may be a bare string, a `{ loader, options }` object, or null.
|
|
@@ -56,15 +56,6 @@ module ReactOnRails
|
|
|
56
56
|
}
|
|
57
57
|
JS
|
|
58
58
|
|
|
59
|
-
BUNDLER_REQUIRE_PATTERN =
|
|
60
|
-
%r{(const bundler = config\.assets_bundler.*\n.*require\('@rspack/core'\).*\n.*: require\('webpack'\);)}
|
|
61
|
-
|
|
62
|
-
# Matches any declaration of the getLoaderPath symbol, however it is written. The
|
|
63
|
-
# emitted extractLoader calls getLoaderPath, so we must never add a second
|
|
64
|
-
# declaration: `function` next to an existing `const` is a SyntaxError, not a
|
|
65
|
-
# silent shadow, and the generated config would fail to parse in Node.
|
|
66
|
-
GET_LOADER_PATH_DECLARATION = /(?:function\s+getLoaderPath\s*\(|(?:const|let|var)\s+getLoaderPath\s*=)/
|
|
67
|
-
|
|
68
59
|
# Main entry point for Pro setup.
|
|
69
60
|
# Orchestrates creation of all Pro-related files and configuration.
|
|
70
61
|
#
|
|
@@ -157,8 +148,8 @@ module ReactOnRails
|
|
|
157
148
|
|
|
158
149
|
Then run: bundle install
|
|
159
150
|
|
|
160
|
-
No license needed for
|
|
161
|
-
|
|
151
|
+
No license key is needed to run Pro. Production is free for small organizations, charities, schools, and hospitals;
|
|
152
|
+
larger organizations subscribe: https://reactonrails.com/pricing/
|
|
162
153
|
See the upgrade guide: https://reactonrails.com/docs/pro/upgrading-to-pro/
|
|
163
154
|
MSG
|
|
164
155
|
true
|
|
@@ -439,228 +430,65 @@ module ReactOnRails
|
|
|
439
430
|
say "✅ Added Node Renderer to #{procfile}", :green
|
|
440
431
|
end
|
|
441
432
|
|
|
442
|
-
#
|
|
443
|
-
#
|
|
444
|
-
# created webpack configs without Pro settings enabled.
|
|
445
|
-
#
|
|
446
|
-
# Updates serverWebpackConfig.js:
|
|
447
|
-
# - Adds extractLoader helper function (required by rscWebpackConfig.js)
|
|
448
|
-
# - Adds Babel SSR caller setup (required for correct SSR compilation)
|
|
449
|
-
# - Enables libraryTarget: 'commonjs2' (required for Node Renderer)
|
|
450
|
-
# - Enables serverWebpackConfig.target = 'node' (required for Node.js modules)
|
|
451
|
-
# - Disables Node.js polyfills via node = false (required for real __dirname)
|
|
452
|
-
# - Changes module.exports to Pro style (required by rscWebpackConfig.js)
|
|
453
|
-
#
|
|
454
|
-
# Updates ServerClientOrBoth.js:
|
|
455
|
-
# - Changes import to destructured style (required for Pro object export)
|
|
433
|
+
# Only replace complete, unchanged generated pairs. Inspecting declarations or
|
|
434
|
+
# individual markers cannot establish that customized JavaScript is safe to rewrite.
|
|
456
435
|
def update_webpack_config_for_pro
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
436
|
+
paths = generated_webpack_pair_paths
|
|
437
|
+
contents = read_generated_webpack_pair(paths) if paths
|
|
438
|
+
replacement = GeneratedWebpackConfigPair.pro_upgrade(contents) if contents
|
|
439
|
+
unless replacement
|
|
440
|
+
warn_unknown_webpack_pair
|
|
461
441
|
return
|
|
462
442
|
end
|
|
463
443
|
|
|
464
|
-
|
|
465
|
-
server_config_ready = pro_server_config_ready?(content)
|
|
466
|
-
import_ready = server_client_import_ready?
|
|
467
|
-
|
|
468
|
-
# Skip only when both server config and import style are already updated.
|
|
469
|
-
if server_config_ready && import_ready
|
|
444
|
+
if replacement == contents
|
|
470
445
|
say "ℹ️ Webpack config already has Pro settings enabled, skipping", :yellow
|
|
471
446
|
return
|
|
472
447
|
end
|
|
473
448
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
unless server_config_ready
|
|
477
|
-
# Add extractLoader helper function after bundler require
|
|
478
|
-
add_extract_loader_to_server_config(webpack_config, content)
|
|
479
|
-
|
|
480
|
-
# Add Babel SSR caller setup (uses extractLoader, so must come after)
|
|
481
|
-
add_babel_ssr_caller_to_server_config(webpack_config, content)
|
|
482
|
-
|
|
483
|
-
# Uncomment libraryTarget: 'commonjs2'
|
|
484
|
-
library_target_pattern = %r{// If using the React on Rails Pro.*\n\s*// libraryTarget: 'commonjs2',}
|
|
485
|
-
library_target_replacement = "// Required for React on Rails Pro Node Renderer\n " \
|
|
486
|
-
"libraryTarget: 'commonjs2',"
|
|
487
|
-
gsub_file(webpack_config, library_target_pattern, library_target_replacement)
|
|
488
|
-
|
|
489
|
-
# Replace stale comments and uncomment target = 'node', add node = false
|
|
490
|
-
# The base template has 4 lines: 2 explanatory comments + "uncomment" hint + commented code
|
|
491
|
-
# Replace with clean Pro output matching the template's use_pro? branch
|
|
492
|
-
# rubocop:disable Layout/LineLength
|
|
493
|
-
target_node_pattern = %r{\s*// If using the default 'web',.*\n\s*// break with SSR\..*\n\s*// If using the React on Rails Pro.*\n\s*// serverWebpackConfig\.target = 'node'}
|
|
494
|
-
# rubocop:enable Layout/LineLength
|
|
495
|
-
target_node_replacement = "\n\n " \
|
|
496
|
-
"// React on Rails Pro uses Node renderer, so target must be 'node'\n " \
|
|
497
|
-
"// This fixes issues with libraries like Emotion and loadable-components\n " \
|
|
498
|
-
"serverWebpackConfig.target = 'node';\n\n " \
|
|
499
|
-
"// Disable Node.js polyfills - not needed when targeting Node\n " \
|
|
500
|
-
"serverWebpackConfig.node = false;"
|
|
501
|
-
gsub_file(webpack_config, target_node_pattern, target_node_replacement)
|
|
502
|
-
|
|
503
|
-
# Change module.exports to Pro style (exports object with default and extractLoader)
|
|
504
|
-
update_server_config_exports(webpack_config)
|
|
449
|
+
paths.zip(replacement).each do |path, content|
|
|
450
|
+
create_file(path, content, force: true)
|
|
505
451
|
end
|
|
506
|
-
|
|
507
|
-
# Update ServerClientOrBoth.js import style
|
|
508
|
-
update_server_client_or_both_import
|
|
509
|
-
|
|
510
|
-
verify_pro_webpack_transforms(webpack_config)
|
|
511
452
|
say "✅ Updated webpack configs for Pro", :green
|
|
512
453
|
end
|
|
513
454
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
# Skip if extractLoader already exists
|
|
521
|
-
return if content.include?("function extractLoader")
|
|
522
|
-
|
|
523
|
-
if content.include?(GET_LOADER_PATH_JS)
|
|
524
|
-
# Config rendered by the current base template: append extractLoader directly after
|
|
525
|
-
# the shared getLoaderPath helper so the result matches the template's Pro output.
|
|
526
|
-
gsub_file(webpack_config, GET_LOADER_PATH_JS, "#{GET_LOADER_PATH_JS}\n#{EXTRACT_LOADER_JS}")
|
|
527
|
-
elsif content.match?(GET_LOADER_PATH_DECLARATION)
|
|
528
|
-
# The app already declares getLoaderPath but has customized it (reformatted, recommented,
|
|
529
|
-
# or rewritten as an arrow function). Reuse whatever is there and emit extractLoader only.
|
|
530
|
-
# Emitting our own copy would redeclare the identifier, which is a SyntaxError next to an
|
|
531
|
-
# existing const/let and silent shadowing next to another function declaration.
|
|
532
|
-
gsub_file(webpack_config, BUNDLER_REQUIRE_PATTERN, "\\1\n\n#{EXTRACT_LOADER_JS}".chomp)
|
|
533
|
-
else
|
|
534
|
-
# Base config generated before getLoaderPath existed: emit both helpers after the
|
|
535
|
-
# bundler require so extractLoader's dependency is present.
|
|
536
|
-
gsub_file(
|
|
537
|
-
webpack_config,
|
|
538
|
-
BUNDLER_REQUIRE_PATTERN,
|
|
539
|
-
"\\1\n\n#{GET_LOADER_PATH_JS}\n#{EXTRACT_LOADER_JS}".chomp
|
|
540
|
-
)
|
|
455
|
+
# Unlike resolve_server_client_or_both_path, discovery must not rename files
|
|
456
|
+
# or edit environment imports before the entire pair has been recognized.
|
|
457
|
+
def generated_webpack_pair_paths
|
|
458
|
+
server = destination_config_path("config/webpack/serverWebpackConfig.js")
|
|
459
|
+
companions = %w[ServerClientOrBoth.js generateWebpackConfigs.js].map do |name|
|
|
460
|
+
destination_config_path("config/webpack/#{name}")
|
|
541
461
|
end
|
|
542
|
-
|
|
462
|
+
existing = companions.select do |path|
|
|
463
|
+
absolute = File.join(destination_root, path)
|
|
464
|
+
File.exist?(absolute) || File.symlink?(absolute)
|
|
465
|
+
end
|
|
466
|
+
return unless existing.one?
|
|
543
467
|
|
|
544
|
-
|
|
545
|
-
return
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
"const babelLoader = extractLoader(rule, 'babel-loader');\n " \
|
|
550
|
-
"if (babelLoader && babelLoader.options) {\n " \
|
|
551
|
-
"babelLoader.options.caller = { ssr: true };\n " \
|
|
552
|
-
"}"
|
|
553
|
-
|
|
554
|
-
# Insert after cssLoader.options.modules; [\s\S]*? covers both single-line and spread syntax patterns.
|
|
555
|
-
gsub_file(
|
|
556
|
-
webpack_config,
|
|
557
|
-
/(cssLoader\.options\.modules = \{[\s\S]*?exportOnlyLocals: true[\s\S]*?\};\s*\n\s*\})/,
|
|
558
|
-
"\\1#{babel_ssr_code}"
|
|
559
|
-
)
|
|
560
|
-
new_content = File.read(File.join(destination_root, webpack_config))
|
|
561
|
-
return if new_content.include?("babelLoader.options.caller")
|
|
468
|
+
paths = [server, existing.first]
|
|
469
|
+
return unless paths.all? do |path|
|
|
470
|
+
absolute = File.join(destination_root, path)
|
|
471
|
+
File.file?(absolute) && !File.symlink?(absolute)
|
|
472
|
+
end
|
|
562
473
|
|
|
563
|
-
|
|
474
|
+
paths
|
|
564
475
|
end
|
|
565
476
|
|
|
566
|
-
def
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
webpack_config,
|
|
571
|
-
/^module\.exports = configureServer;\s*$/,
|
|
572
|
-
"module.exports = {\n default: configureServer,\n extractLoader,\n};\n"
|
|
573
|
-
)
|
|
477
|
+
def read_generated_webpack_pair(paths)
|
|
478
|
+
paths.map { |path| File.binread(File.join(destination_root, path)) }
|
|
479
|
+
rescue SystemCallError, IOError
|
|
480
|
+
nil
|
|
574
481
|
end
|
|
575
482
|
|
|
576
|
-
def
|
|
577
|
-
content = File.read(File.join(destination_root, webpack_config))
|
|
578
|
-
missing = missing_server_config_transforms(content)
|
|
579
|
-
missing.concat(missing_server_client_import_transform)
|
|
580
|
-
return if missing.empty?
|
|
581
|
-
|
|
483
|
+
def warn_unknown_webpack_pair
|
|
582
484
|
GeneratorMessages.add_warning(<<~MSG.strip)
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
This can happen if your webpack config has been customized.
|
|
589
|
-
Please verify #{webpack_config} manually.
|
|
485
|
+
Skipped Pro webpack updates: the config pair is missing, ambiguous, customized,
|
|
486
|
+
or does not match a supported current generated pair.
|
|
487
|
+
Both webpack configs and their paths were left unchanged. Update them manually using the Pro setup guide:
|
|
488
|
+
https://reactonrails.com/docs/pro/upgrading-to-pro/
|
|
590
489
|
MSG
|
|
591
490
|
end
|
|
592
491
|
|
|
593
|
-
def missing_server_config_transforms(content)
|
|
594
|
-
checks = [
|
|
595
|
-
"libraryTarget: 'commonjs2',",
|
|
596
|
-
"function extractLoader",
|
|
597
|
-
"babelLoader.options.caller = { ssr: true }",
|
|
598
|
-
"serverWebpackConfig.target = 'node'",
|
|
599
|
-
"serverWebpackConfig.node = false",
|
|
600
|
-
"default: configureServer",
|
|
601
|
-
"extractLoader,"
|
|
602
|
-
]
|
|
603
|
-
|
|
604
|
-
checks.reject { |pattern| content.include?(pattern) }
|
|
605
|
-
end
|
|
606
|
-
|
|
607
|
-
def missing_server_client_import_transform
|
|
608
|
-
server_client_path = resolve_server_client_or_both_path
|
|
609
|
-
return [] unless server_client_path
|
|
610
|
-
|
|
611
|
-
content = File.read(File.join(destination_root, server_client_path))
|
|
612
|
-
return [] if content.include?("{ default: serverWebpackConfig }")
|
|
613
|
-
|
|
614
|
-
["{ default: serverWebpackConfig }"]
|
|
615
|
-
end
|
|
616
|
-
|
|
617
|
-
def update_server_client_or_both_import
|
|
618
|
-
server_client_path = resolve_server_client_or_both_path
|
|
619
|
-
return unless server_client_path
|
|
620
|
-
|
|
621
|
-
content = File.read(File.join(destination_root, server_client_path))
|
|
622
|
-
|
|
623
|
-
# Skip if already using destructured import
|
|
624
|
-
return if content.include?("{ default: serverWebpackConfig }")
|
|
625
|
-
|
|
626
|
-
# Change from: const serverWebpackConfig = require('./serverWebpackConfig');
|
|
627
|
-
# To: const { default: serverWebpackConfig } = require('./serverWebpackConfig');
|
|
628
|
-
gsub_file(
|
|
629
|
-
server_client_path,
|
|
630
|
-
%r{^const serverWebpackConfig = require\('\./serverWebpackConfig'\);$},
|
|
631
|
-
"const { default: serverWebpackConfig } = require('./serverWebpackConfig');"
|
|
632
|
-
)
|
|
633
|
-
|
|
634
|
-
new_content = File.read(File.join(destination_root, server_client_path))
|
|
635
|
-
return if new_content.include?("{ default: serverWebpackConfig }")
|
|
636
|
-
|
|
637
|
-
say_status(
|
|
638
|
-
:warning,
|
|
639
|
-
"ServerClientOrBoth import update failed in #{server_client_path}; manual edit required.",
|
|
640
|
-
:yellow
|
|
641
|
-
)
|
|
642
|
-
end
|
|
643
|
-
|
|
644
|
-
def pro_server_config_ready?(content)
|
|
645
|
-
# Check for the Pro-specific comment marker (written by the transform) to avoid
|
|
646
|
-
# false-negatives when commented-out lines also contain the pattern string.
|
|
647
|
-
content.include?("// Required for React on Rails Pro Node Renderer") &&
|
|
648
|
-
content.include?("function extractLoader") &&
|
|
649
|
-
content.include?("babelLoader.options.caller = { ssr: true }") &&
|
|
650
|
-
content.include?("serverWebpackConfig.target = 'node'") &&
|
|
651
|
-
content.include?("serverWebpackConfig.node = false") &&
|
|
652
|
-
content.include?("default: configureServer") &&
|
|
653
|
-
content.include?("extractLoader,")
|
|
654
|
-
end
|
|
655
|
-
|
|
656
|
-
def server_client_import_ready?
|
|
657
|
-
server_client_path = resolve_server_client_or_both_path
|
|
658
|
-
return true unless server_client_path
|
|
659
|
-
|
|
660
|
-
content = File.read(File.join(destination_root, server_client_path))
|
|
661
|
-
content.include?("{ default: serverWebpackConfig }")
|
|
662
|
-
end
|
|
663
|
-
|
|
664
492
|
def pro_gem_auto_install_command
|
|
665
493
|
"bundle add #{PRO_GEM_NAME} --version='#{pro_gem_version_requirement}' --strict"
|
|
666
494
|
end
|
|
@@ -82,17 +82,9 @@ module ReactOnRails
|
|
|
82
82
|
react_version = detect_react_version
|
|
83
83
|
return if react_version.nil? # React not installed yet, will be installed by generator
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
major, minor, patch = version.segments
|
|
85
|
+
major, minor, patch = react_version.split(".").map(&:to_i)
|
|
87
86
|
|
|
88
|
-
if
|
|
89
|
-
GeneratorMessages.add_warning(<<~MSG.strip)
|
|
90
|
-
⚠️ RSC requires stable React (detected: #{react_version}).
|
|
91
|
-
|
|
92
|
-
React prereleases are not supported. Install matching stable React/React DOM versions:
|
|
93
|
-
#{manual_add_packages_command(["react@#{RSC_REACT_VERSION_RANGE}", "react-dom@#{RSC_REACT_VERSION_RANGE}"])}
|
|
94
|
-
MSG
|
|
95
|
-
elsif major != RSC_SUPPORTED_REACT_MAJOR || minor != RSC_SUPPORTED_REACT_MINOR
|
|
87
|
+
if major != RSC_SUPPORTED_REACT_MAJOR || minor != RSC_SUPPORTED_REACT_MINOR
|
|
96
88
|
GeneratorMessages.add_warning(<<~MSG.strip)
|
|
97
89
|
⚠️ RSC requires React #{RSC_SUPPORTED_REACT_LINE} (detected: #{react_version})
|
|
98
90
|
|
|
@@ -105,14 +97,13 @@ module ReactOnRails
|
|
|
105
97
|
MSG
|
|
106
98
|
elsif patch < RSC_MINIMUM_REACT_PATCH
|
|
107
99
|
GeneratorMessages.add_warning(<<~MSG.strip)
|
|
108
|
-
⚠️ React #{react_version} is below the
|
|
100
|
+
⚠️ React #{react_version} is below the recommended minimum for RSC.
|
|
109
101
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
The Node Renderer refuses startup until React and React DOM are upgraded together:
|
|
113
|
-
#{manual_add_packages_command(["react@#{RSC_REACT_VERSION_RANGE}", "react-dom@#{RSC_REACT_VERSION_RANGE}"])}
|
|
102
|
+
Please upgrade to at least React #{RSC_MINIMUM_REACT_VERSION}:
|
|
103
|
+
#{manual_add_packages_command(["react@#{RSC_MINIMUM_REACT_VERSION}", "react-dom@#{RSC_MINIMUM_REACT_VERSION}"])}
|
|
114
104
|
|
|
115
|
-
|
|
105
|
+
react-on-rails-rsc 19.2.x with patch >= 19.2.1 is coordinated with
|
|
106
|
+
React/React DOM #{RSC_MINIMUM_REACT_VERSION}+ for the React on Rails Pro 17 RSC runtime.
|
|
116
107
|
MSG
|
|
117
108
|
end
|
|
118
109
|
end
|
data/lib/generators/react_on_rails/templates/pro/base/config/initializers/react_on_rails_pro.rb.tt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# See https://reactonrails.com/docs/configuration/configuration-pro
|
|
4
|
-
#
|
|
4
|
+
# Optional license key from your subscription: set REACT_ON_RAILS_PRO_LICENSE to mark your pages Licensed.
|
|
5
5
|
ReactOnRailsPro.configure do |config|
|
|
6
6
|
config.server_renderer = "NodeRenderer"
|
|
7
7
|
config.renderer_url = ENV.fetch("REACT_RENDERER_URL", "http://localhost:3800")
|