react_on_rails 16.0.0 → 16.0.1.rc.2

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +124 -77
  3. data/CLAUDE.md +46 -2
  4. data/CONTRIBUTING.md +12 -6
  5. data/Gemfile.development_dependencies +1 -0
  6. data/Gemfile.lock +3 -1
  7. data/LICENSE.md +15 -1
  8. data/README.md +68 -18
  9. data/bin/lefthook/check-trailing-newlines +38 -0
  10. data/bin/lefthook/get-changed-files +26 -0
  11. data/bin/lefthook/prettier-format +26 -0
  12. data/bin/lefthook/ruby-autofix +26 -0
  13. data/bin/lefthook/ruby-lint +27 -0
  14. data/eslint.config.ts +10 -0
  15. data/knip.ts +20 -9
  16. data/lib/generators/react_on_rails/USAGE +65 -0
  17. data/lib/generators/react_on_rails/base_generator.rb +7 -7
  18. data/lib/generators/react_on_rails/generator_helper.rb +4 -0
  19. data/lib/generators/react_on_rails/generator_messages.rb +2 -2
  20. data/lib/generators/react_on_rails/install_generator.rb +115 -7
  21. data/lib/generators/react_on_rails/react_no_redux_generator.rb +16 -4
  22. data/lib/generators/react_on_rails/react_with_redux_generator.rb +83 -14
  23. data/lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.tsx +25 -0
  24. data/lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.server.tsx +5 -0
  25. data/lib/generators/react_on_rails/templates/base/base/bin/dev +12 -24
  26. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/actions/helloWorldActionCreators.ts +18 -0
  27. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.tsx +24 -0
  28. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/constants/helloWorldConstants.ts +6 -0
  29. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/containers/HelloWorldContainer.ts +20 -0
  30. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/reducers/helloWorldReducer.ts +22 -0
  31. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/startup/HelloWorldApp.client.tsx +23 -0
  32. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/startup/HelloWorldApp.server.tsx +5 -0
  33. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/store/helloWorldStore.ts +18 -0
  34. data/lib/react_on_rails/configuration.rb +10 -6
  35. data/lib/react_on_rails/dev/server_manager.rb +185 -28
  36. data/lib/react_on_rails/doctor.rb +1149 -0
  37. data/lib/react_on_rails/helper.rb +9 -78
  38. data/lib/react_on_rails/pro/NOTICE +21 -0
  39. data/lib/react_on_rails/pro/helper.rb +122 -0
  40. data/lib/react_on_rails/pro/utils.rb +53 -0
  41. data/lib/react_on_rails/react_component/render_options.rb +6 -2
  42. data/lib/react_on_rails/system_checker.rb +659 -0
  43. data/lib/react_on_rails/version.rb +1 -1
  44. data/lib/tasks/doctor.rake +48 -0
  45. data/lib/tasks/generate_packs.rake +127 -4
  46. data/package-lock.json +11984 -0
  47. metadata +26 -6
  48. data/lib/generators/react_on_rails/bin/dev +0 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae77f76930b3765219ace75c93ac15ba789730f9d7fd98690db212e74489936d
4
- data.tar.gz: a81127c42c27640473994129251b9f18ea7c609837c0b414eaa83a4edc30442d
3
+ metadata.gz: 447fa3382ac19a61525d8e17f67534ed0d6243cb8352512bae81b002165aef9b
4
+ data.tar.gz: 26b1a80ba765de1cf379e7fddc7adda75de353c39fea0a8c8965d314099d1b91
5
5
  SHA512:
6
- metadata.gz: a0d4a4ece7bf8bd4a90dd7f3e11249f0d8de7d1dd1425a9f4654caeef3758722aaad5d2b6654e50f5526d32f6cddb65847ff3e0e865203017c331d283a01f12f
7
- data.tar.gz: 6ec4ef830ab5712e467de1a98d54ccfb6d174079f78d2f9aeb5e84f26eb71038200ad2b0b4f3c4ef03a8ded5b1def16869482afffbaf5c17bd861df10364d3f9
6
+ metadata.gz: ee112925a900c99b9b060e4eccf6fa18b5e249d2993b66d1a5b9ead17e989693d3dd512049a2276663616f9edb792b940f23334a600f56a4888deab47ea57ca2
7
+ data.tar.gz: dc7ba94789cfda1fcfce115d6db988b523810ed146d1db71d72d5942e920c7abf798317f8644ddc2e18dead08c4eacce62fb4b1a8c7ea751caaf63c85f40d35c
data/CHANGELOG.md CHANGED
@@ -23,86 +23,132 @@ After a release, please make sure to run `bundle exec rake update_changelog`. Th
23
23
 
24
24
  Changes since the last non-beta release.
25
25
 
26
- ### [16.0.0] - 2025-01-XX
27
-
28
- #### Removed (Breaking Changes)
29
-
30
- - **Webpacker support completely removed**. Shakapacker >= 6.0 is now required.
31
- - Migration:
32
- - Remove any `webpacker` gem references from your Gemfile
33
- - Ensure `shakapacker` gem version 6.0 or higher is installed (8.0+ recommended)
34
- - Replace any `bin/webpacker` commands with `bin/shakapacker`
35
- - Update any webpacker configuration files to shakapacker equivalents
36
- - Removed files: `rakelib/webpacker_examples.rake`, `lib/generators/react_on_rails/adapt_for_older_shakapacker_generator.rb`
37
- - All webpacker compatibility code and tests have been removed
38
- - **CI/Development runtime requirements updated**:
39
- - _Note, this is just what CI tests_. You can use older versions of Ruby and Node.js, but you may run into issues.\*
40
- - Minimum Ruby version: 3.2 (was 3.0)
41
- - Maximum Ruby version: 3.4 (was 3.3)
42
- - Minimum Node.js version: 20 (was 16)
43
- - Maximum Node.js version: 22 (was 20)
44
- - Migration: Upgrade your Ruby and Node.js versions to supported ranges
45
- - **Install generator now validates prerequisites**:
46
- - Generator now requires at least one JavaScript package manager (npm, pnpm, yarn, or bun)
47
- - Generator uses `Thor::Error` exceptions instead of `exit(1)` for better error handling
48
- - Migration: Ensure you have a JavaScript package manager installed before running the generator
49
-
50
- #### Enhanced
51
-
52
- - Simplified CI matrix configuration with clear dependency level naming (`minimum`/`latest` instead of `oldest`/`newest`)
53
- - Improved error messages in install generator with clearer troubleshooting steps
54
- - Enhanced package manager detection with multi-strategy validation
55
-
56
- ### [15.0.0] - 2025-08-28
57
-
58
- See [Release Notes](docs/release-notes/16.0.0.md) for full details.
59
-
60
- ### Removed (Breaking Changes)
61
-
62
- - Deprecated `defer_generated_component_packs` configuration option. You should use `generated_component_packs_loading_strategy` instead.
63
- - Migration:
64
- - `defer_generated_component_packs: true` → `generated_component_packs_loading_strategy: :defer`
65
- - `defer_generated_component_packs: false` → `generated_component_packs_loading_strategy: :sync`
66
- - For best performance, use `generated_component_packs_loading_strategy: :async`
67
- - [PR 1712](https://github.com/shakacode/react_on_rails/pull/1712) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
68
- - The package is ESM-only now. Migration:
69
- - If using `require('react-on-rails')`, upgrade to Node v20.19.0+ or change to `import`.
70
- - For TypeScript errors, upgrade to TypeScript 5.8+ and set `module` to `nodenext`.
71
- - `ReactOnRails.reactOnRailsPageLoaded` is now an async function. Migration:
72
- - Add `await` when calling this function: `await ReactOnRails.reactOnRailsPageLoaded()`.
73
- - **RENAMED**: `force_load` configuration renamed to `immediate_hydration` for better API clarity.
74
- - `immediate_hydration` now defaults to `false` and requires React on Rails Pro license.
75
- - Migration:
76
- - `config.force_load = true` → `config.immediate_hydration = true`
77
- - `react_component(force_load: true)` → `react_component(immediate_hydration: true)`
78
- - `redux_store(force_load: true)` → `redux_store(immediate_hydration: true)`
79
-
80
- For detailed migration instructions, see the [16.0.0 Release Notes](docs/release-notes/16.0.0.md).
81
-
82
- #### Fixed
83
-
84
- - Enable support for ReactRefreshWebpackPlugin v0.6.0 by adding conditional logic regarding configuration. [PR 1748](https://github.com/shakacode/react_on_rails/pull/1748) by [judahmeek](https://github.com/judahmeek).
85
- - Replace RenderOptions.renderRequestId and use local trackers instead. This change should only be relevant to ReactOnRails Pro users. [PR 1745](https://github.com/shakacode/react_on_rails/pull/1745) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
86
- - Fixed invalid warnings about non-exact versions when using a pre-release version of React on Rails, as well as missing warnings when using different pre-release versions of the gem and the Node package. [PR 1742](https://github.com/shakacode/react_on_rails/pull/1742) by [alexeyr-ci2](https://github.com/alexeyr-ci2).
26
+ #### Bug Fixes
87
27
 
88
- #### Improved
28
+ - **Doctor rake task**: Fixed LoadError in `rake react_on_rails:doctor` when using packaged gem. The task was trying to require excluded `rakelib/task_helpers` file. [PR 1795](https://github.com/shakacode/react_on_rails/pull/1795)
29
+
30
+ ### [16.0.1-rc.0] - 2025-09-19
31
+
32
+ #### Pro License Structure Implementation
33
+
34
+ **🔐 License Architecture**
35
+
36
+ - **Core/Pro separation**: Moved Pro features into dedicated `lib/react_on_rails/pro/` and `node_package/src/pro/` directories with clear licensing boundaries [PR 1791](https://github.com/shakacode/react_on_rails/pull/1791) by [abanoubghadban](https://github.com/AbanoubGhadban)
37
+ - **Runtime license validation**: Implemented Pro license gating with graceful fallback to core functionality when Pro license unavailable
38
+ - **License documentation**: Added NOTICE files in Pro directories referencing canonical `REACT-ON-RAILS-PRO-LICENSE.md`
39
+ - **Updated LICENSE.md**: Clearly distinguishes core MIT license from Pro-licensed directories
40
+
41
+ **⚡ Pro Feature Enhancements**
42
+
43
+ - **Immediate hydration**: Enhanced immediate hydration functionality with Pro license validation and warning badges
44
+ - **Security improvements**: Hardened DOM selectors using `CSS.escape()` and proper JavaScript escaping for XSS protection
45
+ - **Architecture refactoring**: Centralized Pro utilities and clean separation between core and Pro helper functionality
46
+
47
+ #### Enhanced TypeScript Generator Support
48
+
49
+ **🔧 Generator Improvements**
50
+
51
+ - **Modern TypeScript patterns**: Generators now produce more idiomatic TypeScript code with improved type inference instead of explicit type annotations [PR 1786](https://github.com/shakacode/react_on_rails/pull/1786) by [justin808](https://github.com/justin808)
52
+ - **Optimized tsconfig.json**: Updated compiler options to use `"moduleResolution": "bundler"` for better bundler compatibility
53
+ - **Enhanced Redux TypeScript integration**: Improved type safety and modern React patterns (useMemo, type-only imports)
54
+ - **Smart bin/dev defaults**: Generated `bin/dev` script now automatically navigates to `/hello_world` route for immediate component visibility
89
55
 
90
- - Ensured that the RSC payload is injected after the component's HTML markup to improve the performance of the RSC payload injection. [PR 1738](https://github.com/shakacode/react_on_rails/pull/1738) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
91
- - Improved RSC rendering flow by eliminating double rendering of server components and reducing the number of HTTP requests.
92
- - Updated communication protocol between Node Renderer and Rails to version 2.0.0 which supports the ability to upload multiple bundles at once.
93
- - Added `RSCRoute` component to enable seamless server-side rendering of React Server Components. This component automatically handles RSC payload injection and hydration, allowing server components to be rendered directly within client components while maintaining optimal performance. [PR 1696](https://github.com/shakacode/react_on_rails/pull/1696) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
94
- - The global context is now accessed using `globalThis`. [PR 1727](https://github.com/shakacode/react_on_rails/pull/1727) by [alexeyr-ci2](https://github.com/alexeyr-ci2).
95
- - Generated client packs now import from `react-on-rails/client` instead of `react-on-rails`. [PR 1706](https://github.com/shakacode/react_on_rails/pull/1706) by [alexeyr-ci](https://github.com/alexeyr-ci).
96
- - The "optimization opportunity" message when importing the server-side `react-on-rails` instead of `react-on-rails/client` in browsers is now a warning for two reasons:
97
- - Make it more prominent
98
- - Include a stack trace when clicked
56
+ **🔐 Security Enhancements**
57
+
58
+ - **Fixed command injection vulnerabilities**: Replaced unsafe string interpolation in generator package installation commands with secure array-based system calls
59
+ - **Improved input validation**: Enhanced package manager validation and argument sanitization across all generators
60
+
61
+ **🎯 Developer Experience**
62
+
63
+ - **Better component templates**: Removed unnecessary type annotations while maintaining type safety through TypeScript's inference
64
+ - **Cleaner generated code**: Streamlined templates following modern React and TypeScript best practices
65
+ - **Improved helper methods**: Added reusable `component_extension` helper for consistent file extension handling
99
66
 
100
67
  #### Added
101
68
 
102
- - Configuration option `generated_component_packs_loading_strategy` to control how generated component packs are loaded. It supports `sync`, `async`, and `defer` strategies. [PR 1712](https://github.com/shakacode/react_on_rails/pull/1712) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
103
- - Support for returning React component from async render-function. [PR 1720](https://github.com/shakacode/react_on_rails/pull/1720) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
104
- - React Server Components Support (Pro Feature) [PR 1644](https://github.com/shakacode/react_on_rails/pull/1644) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
105
- - Improved component and store hydration performance [PR 1656](https://github.com/shakacode/react_on_rails/pull/1656) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
69
+ - **`react_on_rails:doctor` rake task**: New diagnostic command to validate React on Rails setup and identify configuration issues. Provides comprehensive checks for environment prerequisites, dependencies, Rails integration, and Webpack configuration. Use `rake react_on_rails:doctor` to diagnose your setup, with optional `VERBOSE=true` for detailed output.
70
+
71
+ ### [16.0.0] - 2025-09-16
72
+
73
+ **React on Rails v16 is a major release that modernizes the library with ESM support, removes legacy Webpacker compatibility, and introduces significant performance improvements. This release builds on the foundation of v14 with enhanced RSC (React Server Components) support and streamlined configuration.**
74
+
75
+ See [Release Notes](docs/release-notes/16.0.0.md) for complete migration guide.
76
+
77
+ #### Major Enhancements
78
+
79
+ **🚀 React Server Components (RSC) -- Requires React on Rails Pro**
80
+
81
+ - **Enhanced RSC rendering flow**: Eliminated double rendering and reduced HTTP requests
82
+ - **`RSCRoute` component**: Seamless server-side rendering with automatic payload injection and hydration [PR 1696](https://github.com/shakacode/react_on_rails/pull/1696) by [AbanoubGhadban](https://github.com/AbanoubGhadban)
83
+ - **Optimized RSC payload injection**: Now injected after component HTML markup for better performance [PR 1738](https://github.com/shakacode/react_on_rails/pull/1738) by [AbanoubGhadban](https://github.com/AbanoubGhadban)
84
+ - **Communication protocol v2.0.0**: Supports uploading multiple bundles at once for improved efficiency
85
+
86
+ **⚡ Performance & Loading Strategy**
87
+
88
+ - **New `generated_component_packs_loading_strategy`**: Choose from `sync`, `async`, or `defer` strategies [PR 1712](https://github.com/shakacode/react_on_rails/pull/1712) by [AbanoubGhadban](https://github.com/AbanoubGhadban)
89
+ - **Async render function support**: Components can now return from async render functions [PR 1720](https://github.com/shakacode/react_on_rails/pull/1720) by [AbanoubGhadban](https://github.com/AbanoubGhadban)
90
+ - **Optimized client imports**: Generated packs now import from `react-on-rails/client` for better tree-shaking [PR 1706](https://github.com/shakacode/react_on_rails/pull/1706) by [alexeyr-ci](https://github.com/alexeyr-ci)
91
+
92
+ #### Developer Experience
93
+
94
+ - **Enhanced error messaging**: Clearer troubleshooting steps and prominent optimization warnings
95
+ - **Modern global access**: Using `globalThis` instead of window/global detection [PR 1727](https://github.com/shakacode/react_on_rails/pull/1727) by [alexeyr-ci2](https://github.com/alexeyr-ci2)
96
+ - **Simplified CI configuration**: Clear `minimum`/`latest` dependency naming instead of `oldest`/`newest`
97
+ - **ReactRefreshWebpackPlugin v0.6.0 support**: Added conditional logic for proper configuration [PR 1748](https://github.com/shakacode/react_on_rails/pull/1748) by [judahmeek](https://github.com/judahmeek)
98
+ - **Version validation improvements**: Fixed invalid warnings with pre-release versions [PR 1742](https://github.com/shakacode/react_on_rails/pull/1742) by [alexeyr-ci2](https://github.com/alexeyr-ci2)
99
+
100
+ #### Breaking Changes
101
+
102
+ **🔧 Webpacker Support Removed**
103
+
104
+ - **Complete removal of Webpacker support**. Shakapacker >= 6.0 is now required.
105
+ - Migration:
106
+ - Remove `webpacker` gem from your Gemfile
107
+ - Install `shakapacker` gem version 6.0+ (8.0+ recommended)
108
+ - Replace `bin/webpacker` commands with `bin/shakapacker`
109
+ - Update webpacker configuration files to shakapacker equivalents
110
+ - Removed files: `rakelib/webpacker_examples.rake`, `lib/generators/react_on_rails/adapt_for_older_shakapacker_generator.rb`
111
+
112
+ **📦 Package System Modernization**
113
+
114
+ - **ESM-only package**: CommonJS `require()` no longer supported
115
+ - Migration:
116
+ - Replace `require('react-on-rails')` with `import ReactOnRails from 'react-on-rails'`
117
+ - For Node.js < 20.19.0, upgrade or use dynamic imports
118
+ - For TypeScript errors, upgrade to TypeScript 5.8+ and set `module: "nodenext"`
119
+
120
+ **⚡ Configuration API Changes**
121
+
122
+ - **`defer_generated_component_packs` deprecated** → use `generated_component_packs_loading_strategy`
123
+ - Migration:
124
+
125
+ - `defer_generated_component_packs: true` → `generated_component_packs_loading_strategy: :defer`
126
+ - `defer_generated_component_packs: false` → `generated_component_packs_loading_strategy: :sync`
127
+ - Recommended: `generated_component_packs_loading_strategy: :async` for best performance
128
+
129
+ - **`force_load` renamed to `immediate_hydration`** for API clarity
130
+ - Migration:
131
+ - `config.force_load = true` → `config.immediate_hydration = true`
132
+ - `react_component(force_load: true)` → `react_component(immediate_hydration: true)`
133
+ - `redux_store(force_load: true)` → `redux_store(immediate_hydration: true)`
134
+ - Note: `immediate_hydration` requires React on Rails Pro license
135
+
136
+ **🔄 Async API Changes**
137
+
138
+ - **`ReactOnRails.reactOnRailsPageLoaded()` is now async**
139
+ - Migration: Add `await` when calling: `await ReactOnRails.reactOnRailsPageLoaded()`
140
+
141
+ **🏗️ Runtime Suggested Versions**
142
+
143
+ - Ruby: 3.2 - 3.4 (was 3.0 - 3.3)
144
+ - Node.js: 20 - 22 (was 16 - 20)
145
+ - Note: These are CI-tested versions; older versions may work but aren't guaranteed
146
+
147
+ **🎯 Generator Improvements**
148
+
149
+ - Install generator now validates JavaScript package manager presence
150
+ - Improved error handling with `Thor::Error` instead of `exit(1)`
151
+ - Enhanced error messages with clearer troubleshooting steps
106
152
 
107
153
  ### [15.0.0] - 2025-08-28 - RETRACTED
108
154
 
@@ -1606,8 +1652,9 @@ such as:
1606
1652
 
1607
1653
  - Fix several generator-related issues.
1608
1654
 
1609
- [Unreleased]: https://github.com/shakacode/react_on_rails/compare/15.0.0...master
1610
- [15.0.0]: https://github.com/shakacode/react_on_rails/compare/14.2.0...15.0.0
1655
+ [Unreleased]: https://github.com/shakacode/react_on_rails/compare/16.0.1-rc.0...master
1656
+ [16.0.1-rc.0]: https://github.com/shakacode/react_on_rails/compare/16.0.0...16.0.1-rc.0
1657
+ [16.0.0]: https://github.com/shakacode/react_on_rails/compare/14.2.0...16.0.0
1611
1658
  [14.2.0]: https://github.com/shakacode/react_on_rails/compare/14.1.1...14.2.0
1612
1659
  [14.1.1]: https://github.com/shakacode/react_on_rails/compare/14.1.0...14.1.1
1613
1660
  [14.1.0]: https://github.com/shakacode/react_on_rails/compare/14.0.5...14.1.0
data/CLAUDE.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
4
 
5
+ ## ⚠️ CRITICAL REQUIREMENTS
6
+
7
+ **BEFORE EVERY COMMIT/PUSH:**
8
+
9
+ 1. **ALWAYS run `bundle exec rubocop` and fix ALL violations**
10
+ 2. **ALWAYS ensure files end with a newline character**
11
+ 3. **NEVER push without running full lint check first**
12
+ 4. **ALWAYS let Prettier handle ALL formatting - never manually format**
13
+
14
+ These requirements are non-negotiable. CI will fail if not followed.
15
+
16
+ **🚀 AUTOMATIC: Git hooks are installed automatically during setup**
17
+
18
+ Git hooks will automatically run linting on **all changed files (staged + unstaged + untracked)** before each commit - making it fast while preventing CI failures!
19
+
20
+ **Note:** Git hooks are for React on Rails gem developers only, not for users who install the gem.
21
+
5
22
  ## Development Commands
6
23
 
7
24
  ### Essential Commands
@@ -11,15 +28,42 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
11
28
  - Ruby tests: `rake run_rspec`
12
29
  - JavaScript tests: `yarn run test` or `rake js_tests`
13
30
  - All tests: `rake` (default task runs lint and all tests except examples)
14
- - **Linting**:
31
+ - **Linting** (MANDATORY BEFORE EVERY COMMIT):
32
+ - **REQUIRED**: `bundle exec rubocop` - Must pass with zero offenses
15
33
  - All linters: `rake lint` (runs ESLint and RuboCop)
16
34
  - ESLint only: `yarn run lint` or `rake lint:eslint`
17
35
  - RuboCop only: `rake lint:rubocop`
18
36
  - **Code Formatting**:
19
- - Format code with Prettier: `yarn start format`
37
+ - Format code with Prettier: `rake autofix`
20
38
  - Check formatting without fixing: `yarn start format.listDifferent`
21
39
  - **Build**: `yarn run build` (compiles TypeScript to JavaScript in node_package/lib)
22
40
  - **Type checking**: `yarn run type-check`
41
+ - **⚠️ MANDATORY BEFORE GIT PUSH**: `bundle exec rubocop` and fix ALL violations + ensure trailing newlines
42
+
43
+ ## ⚠️ FORMATTING RULES
44
+
45
+ **Prettier is the SOLE authority for formatting. NEVER manually format code.**
46
+
47
+ ### Standard Workflow
48
+ 1. Make code changes
49
+ 2. Run `rake autofix` or `yarn start format`
50
+ 3. Commit changes
51
+
52
+ ### Merge Conflict Resolution Workflow
53
+ **CRITICAL**: When resolving merge conflicts, follow this exact sequence:
54
+
55
+ 1. **Resolve logical conflicts only** - don't worry about formatting
56
+ 2. **Add resolved files**: `git add .` (or specific files)
57
+ 3. **Auto-fix everything**: `rake autofix`
58
+ 4. **Add any formatting changes**: `git add .`
59
+ 5. **Continue rebase/merge**: `git rebase --continue` or `git commit`
60
+
61
+ **❌ NEVER manually format during conflict resolution** - this causes formatting wars between tools.
62
+
63
+ ### Debugging Formatting Issues
64
+ - Check current formatting: `yarn start format.listDifferent`
65
+ - Fix all formatting: `rake autofix`
66
+ - If CI fails on formatting, always run automated fixes, never manual fixes
23
67
 
24
68
  ### Development Setup Commands
25
69
 
data/CONTRIBUTING.md CHANGED
@@ -7,6 +7,10 @@
7
7
  ## Prerequisites
8
8
 
9
9
  - [Yalc](https://github.com/whitecolor/yalc) must be installed globally for most local development.
10
+ - **Git hooks setup** (automatic during normal setup):
11
+
12
+ Git hooks are installed automatically when you run the standard setup commands. They will run automatic linting on **all changed files (staged + unstaged + untracked)** - making commits fast while preventing CI failures.
13
+
10
14
  - After updating code via Git, to prepare all examples:
11
15
 
12
16
  ```sh
@@ -457,7 +461,9 @@ This approach:
457
461
 
458
462
  ## Pre-Commit Requirements
459
463
 
460
- **CRITICAL**: Before committing any changes, always run the following commands to ensure code quality:
464
+ **AUTOMATED**: If you've set up Lefthook (see Prerequisites), linting runs automatically on changed files before each commit.
465
+
466
+ **MANUAL OPTION**: If you need to run linting manually:
461
467
 
462
468
  ```bash
463
469
  # Navigate to the main react_on_rails directory
@@ -476,14 +482,14 @@ rake lint:rubocop
476
482
  rake lint
477
483
  ```
478
484
 
479
- **Automated checks:**
485
+ **Git hooks automatically run:**
480
486
 
481
- - Format all JavaScript/TypeScript files with Prettier
487
+ - Format JavaScript/TypeScript files with Prettier (on changed files only)
482
488
  - Check and fix linting issues with ESLint
483
- - Check and fix Ruby style issues with RuboCop
484
- - Ensure all tests pass before pushing
489
+ - Check and fix Ruby style issues with RuboCop (on all changed files)
490
+ - Ensure trailing newlines on all files
485
491
 
486
- **Tip**: Set up your IDE to run these automatically on save to catch issues early.
492
+ **Setup**: Automatic during normal development setup
487
493
 
488
494
  ## 🤖 Best Practices for AI Coding Agents
489
495
 
@@ -38,6 +38,7 @@ group :development, :test do
38
38
  gem "rubocop-rspec", "~>2.26", require: false
39
39
  gem "scss_lint", require: false
40
40
  gem "spring", "~> 4.0"
41
+ gem "lefthook", require: false
41
42
  end
42
43
 
43
44
  group :test do
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- react_on_rails (15.0.0)
4
+ react_on_rails (16.0.1.rc.0)
5
5
  addressable
6
6
  connection_pool
7
7
  execjs (~> 2.5)
@@ -156,6 +156,7 @@ GEM
156
156
  launchy (3.0.1)
157
157
  addressable (~> 2.8)
158
158
  childprocess (~> 5.0)
159
+ lefthook (1.13.1)
159
160
  listen (3.9.0)
160
161
  rb-fsevent (~> 0.10, >= 0.10.3)
161
162
  rb-inotify (~> 0.9, >= 0.9.10)
@@ -412,6 +413,7 @@ DEPENDENCIES
412
413
  jbuilder
413
414
  jquery-rails
414
415
  launchy
416
+ lefthook
415
417
  listen
416
418
  package_json
417
419
  pry
data/LICENSE.md CHANGED
@@ -5,7 +5,12 @@
5
5
 
6
6
  ---
7
7
 
8
- # MIT License
8
+ ## MIT License for Core React on Rails
9
+
10
+ This license applies to all files within this repository, with the exception of the code located in the following directories, which are licensed separately under the React on Rails Pro License:
11
+
12
+ - `lib/react_on_rails/pro/`
13
+ - `node_package/src/pro/`
9
14
 
10
15
  Copyright (c) 2017, 2018 Justin Gordon and ShakaCode
11
16
  Copyright (c) 2015–2025 ShakaCode, LLC
@@ -31,3 +36,12 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
36
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
37
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
38
  SOFTWARE.
39
+
40
+ ---
41
+
42
+ ## React on Rails Pro License
43
+
44
+ The code in the directories listed above is part of the React on Rails Pro framework and is licensed under the React on Rails Pro License.
45
+
46
+ You can find the full text of the license agreement here:
47
+ [REACT-ON-RAILS-PRO-LICENSE.md](./REACT-ON-RAILS-PRO-LICENSE.md)
data/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  ---
11
11
 
12
- [![License](https://img.shields.io/badge/license-mit-green.svg)](LICENSE.md)[![Gem Version](https://badge.fury.io/rb/react_on_rails.svg)](https://badge.fury.io/rb/react_on_rails) [![npm version](https://badge.fury.io/js/react-on-rails.svg)](https://badge.fury.io/js/react-on-rails) [![Code Climate](https://codeclimate.com/github/shakacode/react_on_rails/badges/gpa.svg)](https://codeclimate.com/github/shakacode/react_on_rails) [![Coverage Status](https://coveralls.io/repos/shakacode/react_on_rails/badge.svg?branch=master&service=github)](https://coveralls.io/github/shakacode/react_on_rails?branch=master) [![](https://ruby-gem-downloads-badge.herokuapp.com/react_on_rails?type=total)](https://rubygems.org/gems/react_on_rails)
12
+ [![License](https://img.shields.io/badge/license-mit-green.svg)](LICENSE.md)[![Gem Version](https://badge.fury.io/rb/react_on_rails.svg)](https://badge.fury.io/rb/react_on_rails) [![npm version](https://badge.fury.io/js/react-on-rails.svg)](https://badge.fury.io/js/react-on-rails) [![Coverage Status](https://coveralls.io/repos/shakacode/react_on_rails/badge.svg?branch=master&service=github)](https://coveralls.io/github/shakacode/react_on_rails?branch=master) [![](https://ruby-gem-downloads-badge.herokuapp.com/react_on_rails?type=total)](https://rubygems.org/gems/react_on_rails)
13
13
 
14
14
  [![Build Main](https://github.com/shakacode/react_on_rails/actions/workflows/main.yml/badge.svg)](https://github.com/shakacode/react_on_rails/actions/workflows/main.yml)
15
15
  [![Build JS Tests](https://github.com/shakacode/react_on_rails/actions/workflows/package-js-tests.yml/badge.svg)](https://github.com/shakacode/react_on_rails/actions/workflows/package-js-tests.yml)
@@ -18,13 +18,18 @@
18
18
 
19
19
  # News
20
20
 
21
+ **🚀 React on Rails v16.0 Released!** Major modernization with ESM support, enhanced React Server Components, and streamlined configuration.
22
+
23
+ - **ESM-only package**: Modern module system with better tree-shaking and performance
24
+ - **React Server Components**: Improved rendering flow and new `RSCRoute` component for seamless SSR
25
+ - **Performance improvements**: New async loading strategies and optimized bundle generation
26
+ - **Webpacker removal**: Streamlined for Shakapacker-only support (>= 6.0)
21
27
  - [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/) supports the latest features of React 18, including [React Server Components](https://react.dev/reference/rsc/server-components) and [streaming](https://react.dev/reference/react-dom/server/renderToPipeableStream). Contact [Justin Gordon](mailto:justin@shakacode.com) for more information.
22
28
  - ShakaCode now maintains the official successor to `rails/webpacker`, [`shakapacker`](https://github.com/shakacode/shakapacker).
23
- - Project is updated to support Rails 7 and Shakapacker v6+!
24
29
 
25
30
  ---
26
31
 
27
- _These are the docs for React on Rails 14. To see the older docs and code: [v13](https://github.com/shakacode/react_on_rails/tree/13.4.0), [v12](https://github.com/shakacode/react_on_rails/tree/12.6.0), and [v11](https://github.com/shakacode/react_on_rails/tree/11.3.0)._
32
+ _These are the docs for React on Rails 16. To see the older docs and code: [v14](https://github.com/shakacode/react_on_rails/tree/14.0.0), [v13](https://github.com/shakacode/react_on_rails/tree/13.4.0), [v12](https://github.com/shakacode/react_on_rails/tree/12.6.0), and [v11](https://github.com/shakacode/react_on_rails/tree/11.3.0)._
28
33
 
29
34
  # About
30
35
 
@@ -42,16 +47,55 @@ We also specialize in helping development teams lower infrastructure and CI cost
42
47
 
43
48
  If you think ShakaCode can help your project, [click here](https://meetings.hubspot.com/justingordon/30-minute-consultation) to book a call with [Justin Gordon](mailto:justin@shakacode.com), the creator of React on Rails.
44
49
 
50
+ ## Upgrading React on Rails
51
+
52
+ After upgrading to a new major version, run the generator to get latest defaults:
53
+
54
+ ```bash
55
+ rails generate react_on_rails:install
56
+ ```
57
+
58
+ **Important**: Review changes carefully before applying to avoid overwriting custom configurations. The generator updates:
59
+
60
+ - `bin/dev` (improved development workflow)
61
+ - webpack configurations
62
+ - `shakapacker.yml` settings
63
+ - other configuration files
64
+
65
+ ### Troubleshooting Setup Issues
66
+
67
+ If you encounter issues during installation or after upgrading, use the doctor command to diagnose your setup:
68
+
69
+ ```bash
70
+ rake react_on_rails:doctor
71
+ ```
72
+
73
+ The doctor command checks your environment, dependencies, and configuration files to identify potential issues. Use `VERBOSE=true rake react_on_rails:doctor` for detailed output.
74
+
75
+ For detailed upgrade instructions, see [upgrade guide documentation](docs/guides/upgrading-react-on-rails.md).
76
+
45
77
  ## React on Rails Pro
46
78
 
47
- Are you interested in optimizing your Webpack setup for React on Rails, including code splitting with [React Router](https://reactrouter.com/) and [loadable-components](https://loadable-components.com/) with server-side rendering for SEO and hot-reloading for developers?
79
+ Some features of React on Rails regarding performance require a React on Rails Pro subscription.
80
+
81
+ Note: the subscription price is free for evaluation and non-production use.
82
+
83
+ Notable new features include:
84
+
85
+ - React Server Components
86
+ - Streaming SSR
87
+ - Loadable Components
88
+ - Code Splitting with React Router
89
+
90
+ React on Rails Pro is the best way to optimize your Webpack setup for React on Rails, including code splitting with [React Router](https://reactrouter.com/) and [loadable-components](https://loadable-components.com/) with server-side rendering for SEO and hot-reloading for developers.
91
+
48
92
  We did this for Popmenu, [lowering Heroku costs 20-25% while getting a 73% decrease in average response times](https://www.shakacode.com/recent-work/popmenu/). Several years later, Popmenu serves tens of millions of SSR requests daily with React on Rails Pro.
49
93
 
50
94
  If you're interested, read more about [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/) and [book a call](https://meetings.hubspot.com/justingordon/30-minute-consultation).
51
95
 
52
96
  # Documentation
53
97
 
54
- See the documentation at **[shakacode.com/react-on-rails/docs](https://www.shakacode.com/react-on-rails/docs/)**.
98
+ See the documentation at **[shakacode.com/react-on-rails/docs](https://www.shakacode.com/react-on-rails/docs/)** and [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/).
55
99
 
56
100
  ## Project Objective
57
101
 
@@ -61,18 +105,20 @@ To provide a high-performance framework for integrating Ruby on Rails with React
61
105
 
62
106
  Given that `shakacode/shakapacker` gem already provides basic React integration, why would you use "React on Rails"?
63
107
 
64
- 1. Automatic configuration of what bundles are added to the page based on what React components are on the page. This results in faster browser loading time via smaller bundle sizes.
65
- 1. Keep up with the latest changes in different versions of React. React 18 is supported.
66
- 1. Easy passing of props directly from your Rails view to your React components rather than having your Rails view load and then make a separate request to your API.
67
- Tight integration with [shakapacker](https://github.com/shakacode/shakapacker) (or its predecessor [rails/webpacker](https://github.com/rails/webpacker)).
68
- 1. Server-Side Rendering (SSR), often used for SEO crawler indexing and UX performance.
69
- 1. [Automated optimized entry-point creation and bundle inclusion when placing a component on a page. With this feature, you no longer need to configure `javascript_pack_tags` and `stylesheet_pack_tags` on your layouts based on what’s shown. “It just works!”](https://www.shakacode.com/react-on-rails/docs/guides/file-system-based-automated-bundle-generation/)
70
- 1. [Redux](https://redux.js.org/) and [React Router](https://reactrouter.com/) integration with server-side-rendering.
71
- 1. [Internationalization (I18n) and (localization)](https://www.shakacode.com/react-on-rails/docs/guides/i18n)
72
- 1. A supportive community. This [web search shows how live public sites are using React on Rails](https://publicwww.com/websites/%22react-on-rails%22++-undeveloped.com+depth%3Aall/).
73
- 1. [ReScript Support](https://github.com/shakacode/rescript-react-on-rails-example).
74
-
75
- See [Rails/Webpacker React Integration Options](https://www.shakacode.com/react-on-rails/docs/guides/rails-webpacker-react-integration-options) for comparisons to other gems.
108
+ 1. **Modern ESM-only package** with optimized tree-shaking for smaller bundle sizes and better performance.
109
+ 1. **Advanced loading strategies** with `sync`, `async`, and `defer` options for optimal performance based on your needs.
110
+ 1. **Automatic configuration** of what bundles are added to the page based on what React components are on the page. This results in faster browser loading time via smaller bundle sizes.
111
+ 1. **Keep up with the latest changes** in different versions of React. React 18+ is fully supported with enhanced React Server Components.
112
+ 1. **Easy prop passing** directly from your Rails view to your React components rather than having your Rails view load and then make a separate request to your API.
113
+ Tight integration with [shakapacker](https://github.com/shakacode/shakapacker).
114
+ 1. **Server-Side Rendering (SSR)** with enhanced React Server Components support, often used for SEO crawler indexing and UX performance.
115
+ 1. **[Automated optimized entry-point creation and bundle inclusion](https://www.shakacode.com/react-on-rails/docs/guides/file-system-based-automated-bundle-generation/)** when placing a component on a page. With this feature, you no longer need to configure `javascript_pack_tags` and `stylesheet_pack_tags` on your layouts based on what's shown. "It just works!"
116
+ 1. **[Redux](https://redux.js.org/) and [React Router](https://reactrouter.com/) integration** with server-side-rendering.
117
+ 1. **[Internationalization (I18n) and (localization)](https://www.shakacode.com/react-on-rails/docs/guides/i18n)** support.
118
+ 1. **Supportive community**. This [web search shows how live public sites are using React on Rails](https://publicwww.com/websites/%22react-on-rails%22++-undeveloped.com+depth%3Aall/).
119
+ 1. **[ReScript Support](https://github.com/shakacode/rescript-react-on-rails-example)**.
120
+
121
+ See [Rails/Shakapacker React Integration Options](https://www.shakacode.com/react-on-rails/docs/guides/rails-webpacker-react-integration-options) for comparisons to other gems.
76
122
 
77
123
  ## Online demo
78
124
 
@@ -88,7 +134,11 @@ _Requires creating a free account._
88
134
 
89
135
  ## Prerequisites
90
136
 
91
- Ruby on Rails >=5, rails/webpacker >= 4.2 or shakapacker > 6, Ruby >= 3.0.0
137
+ - Ruby on Rails >= 5
138
+ - Shakapacker >= 6.0 (Webpacker is no longer supported as of v16)
139
+ - Ruby >= 3.2 (CI tested: 3.2 - 3.4)
140
+ - Node.js >= 20 (CI tested: 20 - 22)
141
+ - A JavaScript package manager (npm, yarn, pnpm, or bun)
92
142
 
93
143
  # Support
94
144
 
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+ # Check for trailing newlines on all changed files
3
+ set -euo pipefail
4
+
5
+ CONTEXT="${1:-staged}"
6
+ files="$(bin/lefthook/get-changed-files "$CONTEXT" '.*')"
7
+
8
+ if [ -z "$files" ]; then
9
+ echo "✅ No files to check for trailing newlines"
10
+ exit 0
11
+ fi
12
+
13
+ if [ "$CONTEXT" = "all-changed" ]; then
14
+ echo "🔍 Checking trailing newlines on all changed files..."
15
+ else
16
+ echo "🔍 Checking trailing newlines on $CONTEXT files..."
17
+ fi
18
+
19
+ failed_files=""
20
+ for file in $files; do
21
+ if [ -f "$file" ] && [ -s "$file" ]; then
22
+ if ! tail -c 1 "$file" | grep -q '^$'; then
23
+ echo "❌ Missing trailing newline: $file"
24
+ failed_files="$failed_files $file"
25
+ fi
26
+ fi
27
+ done
28
+
29
+ if [ -n "$failed_files" ]; then
30
+ echo ""
31
+ echo "❌ Trailing newline check failed!"
32
+ echo "💡 Add trailing newlines to:$failed_files"
33
+ echo "🔧 Quick fix: for file in$failed_files; do echo >> \"\$file\"; done"
34
+ echo "🚫 Skip hook: git commit --no-verify"
35
+ exit 1
36
+ fi
37
+
38
+ echo "✅ All files have proper trailing newlines"
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env bash
2
+ # Get changed files based on context (staged, branch, or all)
3
+ set -euo pipefail
4
+
5
+ CONTEXT="${1:-staged}"
6
+ PATTERN="${2:-.*}"
7
+
8
+ case "$CONTEXT" in
9
+ staged)
10
+ git diff --cached --name-only --diff-filter=ACM | grep -E "$PATTERN" || true
11
+ ;;
12
+ all-changed)
13
+ # Get all changed files (staged + unstaged + untracked) vs working directory
14
+ (git diff --cached --name-only --diff-filter=ACM; git diff --name-only --diff-filter=ACM; git ls-files --others --exclude-standard) | sort -u | grep -E "$PATTERN" || true
15
+ ;;
16
+ branch)
17
+ # Find base branch (prefer main over master)
18
+ base="origin/main"
19
+ git rev-parse --verify --quiet "$base" >/dev/null || base="origin/master"
20
+ git diff --name-only --diff-filter=ACM "$base"...HEAD | grep -E "$PATTERN" || true
21
+ ;;
22
+ *)
23
+ echo "Usage: $0 {staged|all-changed|branch} [pattern]" >&2
24
+ exit 1
25
+ ;;
26
+ esac
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env bash
2
+ # Format JS/TS/JSON/MD files with Prettier
3
+ set -euo pipefail
4
+
5
+ CONTEXT="${1:-staged}"
6
+ files="$(bin/lefthook/get-changed-files "$CONTEXT" '\.(js|jsx|ts|tsx|json|md|yml|yaml)$')"
7
+
8
+ if [ -z "$files" ]; then
9
+ echo "✅ No files to format with Prettier"
10
+ exit 0
11
+ fi
12
+
13
+ if [ "$CONTEXT" = "all-changed" ]; then
14
+ echo "💅 Prettier on all changed files:"
15
+ else
16
+ echo "💅 Prettier on $CONTEXT files:"
17
+ fi
18
+ printf " %s\n" $files
19
+
20
+ yarn run prettier --write $files
21
+
22
+ # Re-stage files if running on staged or all-changed context
23
+ if [ "$CONTEXT" = "staged" ] || [ "$CONTEXT" = "all-changed" ]; then
24
+ echo $files | xargs -r git add
25
+ echo "✅ Re-staged formatted files"
26
+ fi