react_on_rails 15.0.0.rc.2 → 16.0.1.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/CHANGELOG.md +103 -34
- data/CLAUDE.md +102 -0
- data/CODING_AGENTS.md +312 -0
- data/CONTRIBUTING.md +378 -3
- data/Gemfile.lock +2 -1
- data/LICENSE.md +30 -4
- data/LICENSES/README.md +14 -0
- data/REACT-ON-RAILS-PRO-LICENSE.md +129 -0
- data/README.md +70 -20
- data/TODO.md +135 -0
- data/eslint.config.ts +5 -0
- data/knip.ts +20 -9
- data/lib/generators/USAGE +4 -5
- data/lib/generators/react_on_rails/USAGE +65 -0
- data/lib/generators/react_on_rails/base_generator.rb +263 -57
- data/lib/generators/react_on_rails/dev_tests_generator.rb +1 -0
- data/lib/generators/react_on_rails/generator_helper.rb +35 -1
- data/lib/generators/react_on_rails/generator_messages.rb +138 -17
- data/lib/generators/react_on_rails/install_generator.rb +336 -26
- data/lib/generators/react_on_rails/react_no_redux_generator.rb +19 -6
- data/lib/generators/react_on_rails/react_with_redux_generator.rb +111 -18
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev +5 -0
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-prod-assets +8 -0
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-static-assets +2 -0
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +0 -5
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/packs/server-bundle.js +1 -8
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx +21 -0
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.tsx +25 -0
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.module.css +4 -0
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.server.jsx +5 -0
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.server.tsx +5 -0
- data/lib/generators/react_on_rails/templates/base/base/app/views/hello_world/index.html.erb.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/app/views/layouts/hello_world.html.erb +4 -2
- data/lib/generators/react_on_rails/templates/base/base/babel.config.js.tt +5 -2
- data/lib/generators/react_on_rails/templates/base/base/bin/dev +34 -0
- data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt +3 -3
- data/lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml +76 -7
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/commonWebpackConfig.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/development.js.tt +8 -8
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/production.js.tt +2 -2
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/test.js.tt +2 -2
- data/lib/generators/react_on_rails/templates/dev_tests/spec/system/hello_world_spec.rb +0 -2
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/actions/helloWorldActionCreators.ts +18 -0
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +0 -6
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.module.css +4 -0
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.tsx +24 -0
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/constants/helloWorldConstants.ts +6 -0
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/containers/HelloWorldContainer.ts +20 -0
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/reducers/helloWorldReducer.ts +22 -0
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/startup/HelloWorldApp.client.tsx +23 -0
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/startup/HelloWorldApp.server.jsx +5 -0
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/startup/HelloWorldApp.server.tsx +5 -0
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/store/helloWorldStore.ts +18 -0
- data/lib/react_on_rails/configuration.rb +15 -11
- data/lib/react_on_rails/controller.rb +5 -3
- data/lib/react_on_rails/dev/file_manager.rb +78 -0
- data/lib/react_on_rails/dev/pack_generator.rb +27 -0
- data/lib/react_on_rails/dev/process_manager.rb +61 -0
- data/lib/react_on_rails/dev/server_manager.rb +487 -0
- data/lib/react_on_rails/dev.rb +20 -0
- data/lib/react_on_rails/doctor.rb +1149 -0
- data/lib/react_on_rails/engine.rb +6 -0
- data/lib/react_on_rails/git_utils.rb +12 -2
- data/lib/react_on_rails/helper.rb +19 -44
- data/lib/react_on_rails/packer_utils.rb +4 -18
- data/lib/react_on_rails/packs_generator.rb +134 -8
- data/lib/react_on_rails/pro/NOTICE +21 -0
- data/lib/react_on_rails/pro/helper.rb +122 -0
- data/lib/react_on_rails/pro/utils.rb +53 -0
- data/lib/react_on_rails/react_component/render_options.rb +8 -4
- data/lib/react_on_rails/server_rendering_js_code.rb +0 -1
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +1 -0
- data/lib/react_on_rails/system_checker.rb +659 -0
- data/lib/react_on_rails/test_helper/webpack_assets_status_checker.rb +1 -0
- data/lib/react_on_rails/utils.rb +16 -1
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/version_syntax_converter.rb +1 -1
- data/lib/react_on_rails.rb +1 -0
- data/lib/tasks/doctor.rake +51 -0
- data/lib/tasks/generate_packs.rake +144 -1
- data/package-lock.json +11984 -0
- data/react_on_rails.gemspec +1 -0
- metadata +55 -11
- data/REACT-ON-RAILS-PRO-LICENSE +0 -95
- data/lib/generators/react_on_rails/adapt_for_older_shakapacker_generator.rb +0 -41
- data/lib/generators/react_on_rails/bin/dev +0 -30
- data/lib/generators/react_on_rails/bin/dev-static +0 -30
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-static.tt +0 -9
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev.tt +0 -5
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/packs/registration.js.tt +0 -8
- /data/lib/generators/react_on_rails/templates/base/base/config/webpack/{webpackConfig.js.tt → generateWebpackConfigs.js.tt} +0 -0
- /data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/startup/{HelloWorldApp.jsx → HelloWorldApp.client.jsx} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6df96f164d23050adbea7f31bb61ab36a092fbad393d2d1d0e8a307f5c6a41d0
|
4
|
+
data.tar.gz: e6e4b7e5c65175310edc4e1c7a01df8ffdfc8cdb9ca7fc1b5012988db174d360
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf0ae04e65fe1225e159154df70a1043a447e15c058fe62a743e99fd4e8ef489b61b64766da0516d93faec781ed4d968e5b3bce85228e560f5c2c3a3646518ee
|
7
|
+
data.tar.gz: e604837b4b5182504ca2c2c38acbcdb8cf2dbea6f8fd94310fcedc28e4e8f4fe072048fdce21bed26317b0147d5712fb4a530a4c1fb3ae9bf52f47c05fa63a00
|
data/CHANGELOG.md
CHANGED
@@ -23,63 +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
|
-
####
|
26
|
+
#### Pro License Structure Implementation
|
27
27
|
|
28
|
-
|
28
|
+
**🔐 License Architecture**
|
29
29
|
|
30
|
-
-
|
30
|
+
- **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)
|
31
|
+
- **Runtime license validation**: Implemented Pro license gating with graceful fallback to core functionality when Pro license unavailable
|
32
|
+
- **License documentation**: Added NOTICE files in Pro directories referencing canonical `REACT-ON-RAILS-PRO-LICENSE.md`
|
33
|
+
- **Updated LICENSE.md**: Clearly distinguishes core MIT license from Pro-licensed directories
|
31
34
|
|
32
|
-
|
35
|
+
**⚡ Pro Feature Enhancements**
|
33
36
|
|
34
|
-
|
37
|
+
- **Immediate hydration**: Enhanced immediate hydration functionality with Pro license validation and warning badges
|
38
|
+
- **Security improvements**: Hardened DOM selectors using `CSS.escape()` and proper JavaScript escaping for XSS protection
|
39
|
+
- **Architecture refactoring**: Centralized Pro utilities and clean separation between core and Pro helper functionality
|
35
40
|
|
36
|
-
####
|
41
|
+
#### Enhanced TypeScript Generator Support
|
37
42
|
|
38
|
-
|
43
|
+
**🔧 Generator Improvements**
|
39
44
|
|
40
|
-
|
45
|
+
- **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)
|
46
|
+
- **Optimized tsconfig.json**: Updated compiler options to use `"moduleResolution": "bundler"` for better bundler compatibility
|
47
|
+
- **Enhanced Redux TypeScript integration**: Improved type safety and modern React patterns (useMemo, type-only imports)
|
48
|
+
- **Smart bin/dev defaults**: Generated `bin/dev` script now automatically navigates to `/hello_world` route for immediate component visibility
|
41
49
|
|
42
|
-
|
50
|
+
**🔐 Security Enhancements**
|
43
51
|
|
44
|
-
-
|
45
|
-
-
|
46
|
-
- 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.
|
52
|
+
- **Fixed command injection vulnerabilities**: Replaced unsafe string interpolation in generator package installation commands with secure array-based system calls
|
53
|
+
- **Improved input validation**: Enhanced package manager validation and argument sanitization across all generators
|
47
54
|
|
48
|
-
|
55
|
+
**🎯 Developer Experience**
|
56
|
+
|
57
|
+
- **Better component templates**: Removed unnecessary type annotations while maintaining type safety through TypeScript's inference
|
58
|
+
- **Cleaner generated code**: Streamlined templates following modern React and TypeScript best practices
|
59
|
+
- **Improved helper methods**: Added reusable `component_extension` helper for consistent file extension handling
|
49
60
|
|
50
61
|
#### Added
|
51
62
|
|
52
|
-
-
|
63
|
+
- **`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.
|
53
64
|
|
54
|
-
|
65
|
+
### [16.0.0] - 2025-09-16
|
55
66
|
|
56
|
-
|
67
|
+
**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.**
|
57
68
|
|
58
|
-
|
69
|
+
See [Release Notes](docs/release-notes/16.0.0.md) for complete migration guide.
|
59
70
|
|
60
|
-
|
71
|
+
#### Major Enhancements
|
61
72
|
|
62
|
-
|
63
|
-
- 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).
|
64
|
-
- 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).
|
65
|
-
- 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:
|
66
|
-
- Make it more prominent
|
67
|
-
- Include a stack trace when clicked
|
73
|
+
**🚀 React Server Components (RSC) -- Requires React on Rails Pro**
|
68
74
|
|
69
|
-
|
75
|
+
- **Enhanced RSC rendering flow**: Eliminated double rendering and reduced HTTP requests
|
76
|
+
- **`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)
|
77
|
+
- **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)
|
78
|
+
- **Communication protocol v2.0.0**: Supports uploading multiple bundles at once for improved efficiency
|
70
79
|
|
71
|
-
|
80
|
+
**⚡ Performance & Loading Strategy**
|
72
81
|
|
73
|
-
|
82
|
+
- **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)
|
83
|
+
- **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)
|
84
|
+
- **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)
|
85
|
+
|
86
|
+
#### Developer Experience
|
74
87
|
|
75
|
-
-
|
76
|
-
-
|
88
|
+
- **Enhanced error messaging**: Clearer troubleshooting steps and prominent optimization warnings
|
89
|
+
- **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)
|
90
|
+
- **Simplified CI configuration**: Clear `minimum`/`latest` dependency naming instead of `oldest`/`newest`
|
91
|
+
- **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)
|
92
|
+
- **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)
|
77
93
|
|
78
94
|
#### Breaking Changes
|
79
95
|
|
80
|
-
|
81
|
-
|
82
|
-
-
|
96
|
+
**🔧 Webpacker Support Removed**
|
97
|
+
|
98
|
+
- **Complete removal of Webpacker support**. Shakapacker >= 6.0 is now required.
|
99
|
+
- Migration:
|
100
|
+
- Remove `webpacker` gem from your Gemfile
|
101
|
+
- Install `shakapacker` gem version 6.0+ (8.0+ recommended)
|
102
|
+
- Replace `bin/webpacker` commands with `bin/shakapacker`
|
103
|
+
- Update webpacker configuration files to shakapacker equivalents
|
104
|
+
- Removed files: `rakelib/webpacker_examples.rake`, `lib/generators/react_on_rails/adapt_for_older_shakapacker_generator.rb`
|
105
|
+
|
106
|
+
**📦 Package System Modernization**
|
107
|
+
|
108
|
+
- **ESM-only package**: CommonJS `require()` no longer supported
|
109
|
+
- Migration:
|
110
|
+
- Replace `require('react-on-rails')` with `import ReactOnRails from 'react-on-rails'`
|
111
|
+
- For Node.js < 20.19.0, upgrade or use dynamic imports
|
112
|
+
- For TypeScript errors, upgrade to TypeScript 5.8+ and set `module: "nodenext"`
|
113
|
+
|
114
|
+
**⚡ Configuration API Changes**
|
115
|
+
|
116
|
+
- **`defer_generated_component_packs` deprecated** → use `generated_component_packs_loading_strategy`
|
117
|
+
- Migration:
|
118
|
+
|
119
|
+
- `defer_generated_component_packs: true` → `generated_component_packs_loading_strategy: :defer`
|
120
|
+
- `defer_generated_component_packs: false` → `generated_component_packs_loading_strategy: :sync`
|
121
|
+
- Recommended: `generated_component_packs_loading_strategy: :async` for best performance
|
122
|
+
|
123
|
+
- **`force_load` renamed to `immediate_hydration`** for API clarity
|
124
|
+
- Migration:
|
125
|
+
- `config.force_load = true` → `config.immediate_hydration = true`
|
126
|
+
- `react_component(force_load: true)` → `react_component(immediate_hydration: true)`
|
127
|
+
- `redux_store(force_load: true)` → `redux_store(immediate_hydration: true)`
|
128
|
+
- Note: `immediate_hydration` requires React on Rails Pro license
|
129
|
+
|
130
|
+
**🔄 Async API Changes**
|
131
|
+
|
132
|
+
- **`ReactOnRails.reactOnRailsPageLoaded()` is now async**
|
133
|
+
- Migration: Add `await` when calling: `await ReactOnRails.reactOnRailsPageLoaded()`
|
134
|
+
|
135
|
+
**🏗️ Runtime Suggested Versions**
|
136
|
+
|
137
|
+
- Ruby: 3.2 - 3.4 (was 3.0 - 3.3)
|
138
|
+
- Node.js: 20 - 22 (was 16 - 20)
|
139
|
+
- Note: These are CI-tested versions; older versions may work but aren't guaranteed
|
140
|
+
|
141
|
+
**🎯 Generator Improvements**
|
142
|
+
|
143
|
+
- Install generator now validates JavaScript package manager presence
|
144
|
+
- Improved error handling with `Thor::Error` instead of `exit(1)`
|
145
|
+
- Enhanced error messages with clearer troubleshooting steps
|
146
|
+
|
147
|
+
### [15.0.0] - 2025-08-28 - RETRACTED
|
148
|
+
|
149
|
+
**⚠️ This version has been retracted due to API design issues. Please upgrade directly to v16.0.0.**
|
150
|
+
|
151
|
+
The `force_load` feature was incorrectly available without a Pro license and has been renamed to `immediate_hydration` for better clarity. All features from v15 are available in v16 with the corrected API.
|
83
152
|
|
84
153
|
### [14.2.0] - 2025-03-03
|
85
154
|
|
@@ -1577,8 +1646,8 @@ such as:
|
|
1577
1646
|
|
1578
1647
|
- Fix several generator-related issues.
|
1579
1648
|
|
1580
|
-
[Unreleased]: https://github.com/shakacode/react_on_rails/compare/
|
1581
|
-
[
|
1649
|
+
[Unreleased]: https://github.com/shakacode/react_on_rails/compare/16.0.0...master
|
1650
|
+
[16.0.0]: https://github.com/shakacode/react_on_rails/compare/14.2.0...16.0.0
|
1582
1651
|
[14.2.0]: https://github.com/shakacode/react_on_rails/compare/14.1.1...14.2.0
|
1583
1652
|
[14.1.1]: https://github.com/shakacode/react_on_rails/compare/14.1.0...14.1.1
|
1584
1653
|
[14.1.0]: https://github.com/shakacode/react_on_rails/compare/14.0.5...14.1.0
|
data/CLAUDE.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# CLAUDE.md
|
2
|
+
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
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
|
+
|
13
|
+
These requirements are non-negotiable. CI will fail if not followed.
|
14
|
+
|
15
|
+
## Development Commands
|
16
|
+
|
17
|
+
### Essential Commands
|
18
|
+
|
19
|
+
- **Install dependencies**: `bundle && yarn`
|
20
|
+
- **Run tests**:
|
21
|
+
- Ruby tests: `rake run_rspec`
|
22
|
+
- JavaScript tests: `yarn run test` or `rake js_tests`
|
23
|
+
- All tests: `rake` (default task runs lint and all tests except examples)
|
24
|
+
- **Linting** (MANDATORY BEFORE EVERY COMMIT):
|
25
|
+
- **REQUIRED**: `bundle exec rubocop` - Must pass with zero offenses
|
26
|
+
- All linters: `rake lint` (runs ESLint and RuboCop)
|
27
|
+
- ESLint only: `yarn run lint` or `rake lint:eslint`
|
28
|
+
- RuboCop only: `rake lint:rubocop`
|
29
|
+
- **Code Formatting**:
|
30
|
+
- Format code with Prettier: `rake autofix`
|
31
|
+
- Check formatting without fixing: `yarn start format.listDifferent`
|
32
|
+
- **Build**: `yarn run build` (compiles TypeScript to JavaScript in node_package/lib)
|
33
|
+
- **Type checking**: `yarn run type-check`
|
34
|
+
- **⚠️ MANDATORY BEFORE GIT PUSH**: `bundle exec rubocop` and fix ALL violations + ensure trailing newlines
|
35
|
+
|
36
|
+
### Development Setup Commands
|
37
|
+
|
38
|
+
- **Initial setup**: `bundle && yarn && rake shakapacker_examples:gen_all && rake node_package && rake`
|
39
|
+
- **Prepare examples**: `rake shakapacker_examples:gen_all`
|
40
|
+
- **Generate node package**: `rake node_package`
|
41
|
+
- **Run single test example**: `rake run_rspec:example_basic`
|
42
|
+
|
43
|
+
### Test Environment Commands
|
44
|
+
|
45
|
+
- **Dummy app tests**: `rake run_rspec:dummy`
|
46
|
+
- **Gem-only tests**: `rake run_rspec:gem`
|
47
|
+
- **All tests except examples**: `rake all_but_examples`
|
48
|
+
|
49
|
+
## Project Architecture
|
50
|
+
|
51
|
+
### Dual Package Structure
|
52
|
+
|
53
|
+
This project maintains both a Ruby gem and an NPM package:
|
54
|
+
|
55
|
+
- **Ruby gem**: Located in `lib/`, provides Rails integration and server-side rendering
|
56
|
+
- **NPM package**: Located in `node_package/src/`, provides client-side React integration
|
57
|
+
|
58
|
+
### Core Components
|
59
|
+
|
60
|
+
#### Ruby Side (`lib/react_on_rails/`)
|
61
|
+
|
62
|
+
- **`helper.rb`**: Rails view helpers for rendering React components
|
63
|
+
- **`server_rendering_pool.rb`**: Manages Node.js processes for server-side rendering
|
64
|
+
- **`configuration.rb`**: Global configuration management
|
65
|
+
- **`engine.rb`**: Rails engine integration
|
66
|
+
- **Generators**: Located in `lib/generators/react_on_rails/`
|
67
|
+
|
68
|
+
#### JavaScript/TypeScript Side (`node_package/src/`)
|
69
|
+
|
70
|
+
- **`ReactOnRails.ts`**: Main entry point for client-side functionality
|
71
|
+
- **`serverRenderReactComponent.ts`**: Server-side rendering logic
|
72
|
+
- **`ComponentRegistry.ts`**: Manages React component registration
|
73
|
+
- **`StoreRegistry.ts`**: Manages Redux store registration
|
74
|
+
|
75
|
+
### Build System
|
76
|
+
|
77
|
+
- **Ruby**: Standard gemspec-based build
|
78
|
+
- **JavaScript**: TypeScript compilation to `node_package/lib/`
|
79
|
+
- **Testing**: Jest for JS, RSpec for Ruby
|
80
|
+
- **Linting**: ESLint for JS/TS, RuboCop for Ruby
|
81
|
+
|
82
|
+
### Examples and Testing
|
83
|
+
|
84
|
+
- **Dummy app**: `spec/dummy/` - Rails app for testing integration
|
85
|
+
- **Examples**: Generated via rake tasks for different webpack configurations
|
86
|
+
- **Rake tasks**: Defined in `rakelib/` for various development operations
|
87
|
+
|
88
|
+
## Important Notes
|
89
|
+
|
90
|
+
- Use `yalc` for local development when testing with external apps
|
91
|
+
- The project supports both Webpacker and Shakapacker
|
92
|
+
- Server-side rendering uses isolated Node.js processes
|
93
|
+
- React Server Components support available in Pro version
|
94
|
+
- Generated examples are in `gen-examples/` (ignored by git)
|
95
|
+
|
96
|
+
## IDE Configuration
|
97
|
+
|
98
|
+
Exclude these directories to prevent IDE slowdowns:
|
99
|
+
|
100
|
+
- `/coverage`, `/tmp`, `/gen-examples`, `/node_package/lib`
|
101
|
+
- `/node_modules`, `/spec/dummy/node_modules`, `/spec/dummy/tmp`
|
102
|
+
- `/spec/dummy/app/assets/webpack`, `/spec/dummy/log`
|
data/CODING_AGENTS.md
ADDED
@@ -0,0 +1,312 @@
|
|
1
|
+
# 🤖 Coding Agents & AI Contributors Guide
|
2
|
+
|
3
|
+
This guide provides specific guidelines for AI coding agents (like Claude Code) contributing to React on Rails. It supplements the main [CONTRIBUTING.md](./CONTRIBUTING.md) with AI-specific workflows and patterns.
|
4
|
+
|
5
|
+
## Quick Reference Commands
|
6
|
+
|
7
|
+
### Essential Commands
|
8
|
+
|
9
|
+
```bash
|
10
|
+
# Install dependencies
|
11
|
+
bundle && yarn
|
12
|
+
|
13
|
+
# Run tests
|
14
|
+
bundle exec rspec # All tests (from project root)
|
15
|
+
cd spec/dummy && bundle exec rspec # Dummy app tests only
|
16
|
+
|
17
|
+
# Linting & Formatting
|
18
|
+
bundle exec rubocop # Ruby linting
|
19
|
+
bundle exec rubocop [file_path] # Lint specific file
|
20
|
+
# Note: yarn format requires local setup, format manually
|
21
|
+
|
22
|
+
# Development
|
23
|
+
cd spec/dummy && foreman start # Start dummy app with webpack
|
24
|
+
```
|
25
|
+
|
26
|
+
### CI Compliance Checklist
|
27
|
+
|
28
|
+
- [ ] `bundle exec rubocop` passes with no offenses
|
29
|
+
- [ ] All RSpec tests pass
|
30
|
+
- [ ] No trailing whitespace
|
31
|
+
- [ ] Line length ≤120 characters
|
32
|
+
- [ ] Security violations properly scoped with disable comments
|
33
|
+
|
34
|
+
## Development Patterns for AI Contributors
|
35
|
+
|
36
|
+
### 1. Task Management
|
37
|
+
|
38
|
+
Always use TodoWrite tool for multi-step tasks to:
|
39
|
+
|
40
|
+
- Track progress transparently
|
41
|
+
- Show the user what's being worked on
|
42
|
+
- Ensure no steps are forgotten
|
43
|
+
- Mark tasks complete as you finish them
|
44
|
+
|
45
|
+
```markdown
|
46
|
+
Example workflow:
|
47
|
+
|
48
|
+
1. Analyze the problem
|
49
|
+
2. Create test cases
|
50
|
+
3. Implement the fix
|
51
|
+
4. Run tests
|
52
|
+
5. Fix linting issues
|
53
|
+
6. Update documentation
|
54
|
+
```
|
55
|
+
|
56
|
+
### 2. Test-Driven Development
|
57
|
+
|
58
|
+
When fixing bugs or adding features:
|
59
|
+
|
60
|
+
1. **Create failing tests first** that reproduce the issue
|
61
|
+
2. **Implement the minimal fix** to make tests pass
|
62
|
+
3. **Add comprehensive test coverage** for edge cases
|
63
|
+
4. **Verify all existing tests still pass**
|
64
|
+
|
65
|
+
### 3. File Processing Guidelines
|
66
|
+
|
67
|
+
When working with file generation or processing:
|
68
|
+
|
69
|
+
- **Filter by extension**: Only process relevant files (e.g., `.js/.jsx/.ts/.tsx` for React components)
|
70
|
+
- **Validate assumptions**: Don't assume all files in a directory are components
|
71
|
+
- **Handle edge cases**: CSS modules, config files, etc. should be excluded appropriately
|
72
|
+
|
73
|
+
Example from CSS module fix:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
COMPONENT_EXTENSIONS = /\.(jsx?|tsx?)$/
|
77
|
+
|
78
|
+
def filter_component_files(paths)
|
79
|
+
paths.grep(COMPONENT_EXTENSIONS)
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
## RuboCop Compliance Patterns
|
84
|
+
|
85
|
+
### Common Fixes
|
86
|
+
|
87
|
+
1. **Trailing Whitespace**
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
# Bad
|
91
|
+
let(:value) { "test" }
|
92
|
+
|
93
|
+
# Good
|
94
|
+
let(:value) { "test" }
|
95
|
+
```
|
96
|
+
|
97
|
+
2. **Line Length (120 chars max)**
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
# Bad
|
101
|
+
expect { eval(pack_content.gsub(/import.*from.*['"];/, "").gsub(/ReactOnRails\.register.*/, "")) }.not_to raise_error
|
102
|
+
|
103
|
+
# Good
|
104
|
+
sanitized_content = pack_content.gsub(/import.*from.*['"];/, "")
|
105
|
+
.gsub(/ReactOnRails\.register.*/, "")
|
106
|
+
expect { eval(sanitized_content) }.not_to raise_error
|
107
|
+
```
|
108
|
+
|
109
|
+
3. **Named Subjects (RSpec)**
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
# Bad
|
113
|
+
describe "#method_name" do
|
114
|
+
subject { instance.method_name(arg) }
|
115
|
+
|
116
|
+
it "does something" do
|
117
|
+
expect(subject).to eq "result"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Good
|
122
|
+
describe "#method_name" do
|
123
|
+
subject(:method_result) { instance.method_name(arg) }
|
124
|
+
|
125
|
+
it "does something" do
|
126
|
+
expect(method_result).to eq "result"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
```
|
130
|
+
|
131
|
+
4. **Security/Eval Violations**
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
# Bad
|
135
|
+
expect { eval(dangerous_code) }.not_to raise_error
|
136
|
+
|
137
|
+
# Good
|
138
|
+
# rubocop:disable Security/Eval
|
139
|
+
sanitized_content = dangerous_code.gsub(/harmful_pattern/, "")
|
140
|
+
expect { eval(sanitized_content) }.not_to raise_error
|
141
|
+
# rubocop:enable Security/Eval
|
142
|
+
```
|
143
|
+
|
144
|
+
### RuboCop Workflow
|
145
|
+
|
146
|
+
1. Run `bundle exec rubocop [file]` to see violations
|
147
|
+
2. Fix violations manually or with auto-correct where safe
|
148
|
+
3. Re-run to verify fixes
|
149
|
+
4. Use disable comments sparingly and with good reason
|
150
|
+
|
151
|
+
## Testing Best Practices
|
152
|
+
|
153
|
+
### Test Structure
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
describe "FeatureName" do
|
157
|
+
context "when condition A" do
|
158
|
+
let(:setup) { create_test_condition }
|
159
|
+
|
160
|
+
before do
|
161
|
+
# Setup code
|
162
|
+
end
|
163
|
+
|
164
|
+
it "does expected behavior" do
|
165
|
+
# Arrange, Act, Assert
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
```
|
170
|
+
|
171
|
+
### Test Fixtures
|
172
|
+
|
173
|
+
- Create realistic test data that represents edge cases
|
174
|
+
- Use descriptive names for fixtures and variables
|
175
|
+
- Clean up after tests (handled by RSpec automatically in most cases)
|
176
|
+
|
177
|
+
### CSS Module Testing Example
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
# Create test fixtures
|
181
|
+
Write.create("ComponentWithCSSModule.module.css", css_content)
|
182
|
+
Write.create("ComponentWithCSSModule.jsx", jsx_content)
|
183
|
+
|
184
|
+
# Test the behavior
|
185
|
+
it "ignores CSS module files during pack generation" do
|
186
|
+
generated_packs = PacksGenerator.instance.generate_packs_if_stale
|
187
|
+
expect(generated_packs).not_to include("ComponentWithCSSModule.module.js")
|
188
|
+
end
|
189
|
+
```
|
190
|
+
|
191
|
+
## Git & PR Workflow
|
192
|
+
|
193
|
+
### Branch Management
|
194
|
+
|
195
|
+
```bash
|
196
|
+
git checkout -b fix/descriptive-name
|
197
|
+
# Make changes
|
198
|
+
git add .
|
199
|
+
git commit -m "Descriptive commit message
|
200
|
+
|
201
|
+
- Bullet points for major changes
|
202
|
+
- Reference issue numbers
|
203
|
+
- Include 🤖 Generated with Claude Code signature"
|
204
|
+
|
205
|
+
git push -u origin fix/descriptive-name
|
206
|
+
```
|
207
|
+
|
208
|
+
### Commit Message Format
|
209
|
+
|
210
|
+
```
|
211
|
+
Brief description of the change
|
212
|
+
|
213
|
+
- Detailed bullet points of what changed
|
214
|
+
- Why the change was needed
|
215
|
+
- Any breaking changes or considerations
|
216
|
+
|
217
|
+
Fixes #issue_number
|
218
|
+
|
219
|
+
🤖 Generated with [Claude Code](https://claude.ai/code)
|
220
|
+
|
221
|
+
Co-Authored-By: Claude <noreply@anthropic.com>
|
222
|
+
```
|
223
|
+
|
224
|
+
### PR Creation
|
225
|
+
|
226
|
+
Use `gh pr create` with:
|
227
|
+
|
228
|
+
- Clear title referencing the issue
|
229
|
+
- Comprehensive description with summary and test plan
|
230
|
+
- Link to the issue being fixed
|
231
|
+
- Include the Claude Code signature
|
232
|
+
|
233
|
+
## Common Pitfalls & Solutions
|
234
|
+
|
235
|
+
### 1. File Path Issues
|
236
|
+
|
237
|
+
- Always use absolute paths in tools
|
238
|
+
- Check current working directory with `pwd`
|
239
|
+
- Use proper path joining methods
|
240
|
+
|
241
|
+
### 2. Test Environment
|
242
|
+
|
243
|
+
- Run tests from correct directory (often project root)
|
244
|
+
- Understand the difference between gem tests vs dummy app tests
|
245
|
+
- Clean up test artifacts appropriately
|
246
|
+
|
247
|
+
### 3. Dependency Management
|
248
|
+
|
249
|
+
- Don't assume packages are installed globally
|
250
|
+
- Use `bundle exec` for Ruby commands
|
251
|
+
- Verify setup with `bundle && yarn` when needed
|
252
|
+
|
253
|
+
### 4. RuboCop Configuration
|
254
|
+
|
255
|
+
- Different rules may apply to different directories
|
256
|
+
- Use `bundle exec rubocop` (not global rubocop)
|
257
|
+
- Check `.rubocop.yml` files for project-specific rules
|
258
|
+
|
259
|
+
## Debugging Workflow
|
260
|
+
|
261
|
+
1. **Understand the Problem**
|
262
|
+
|
263
|
+
- Read the issue carefully
|
264
|
+
- Reproduce the bug if possible
|
265
|
+
- Identify root cause
|
266
|
+
|
267
|
+
2. **Create Minimal Test Case**
|
268
|
+
|
269
|
+
- Write failing test that demonstrates issue
|
270
|
+
- Keep it focused and minimal
|
271
|
+
|
272
|
+
3. **Implement Fix**
|
273
|
+
|
274
|
+
- Make smallest change possible
|
275
|
+
- Ensure fix doesn't break existing functionality
|
276
|
+
- Follow existing code patterns
|
277
|
+
|
278
|
+
4. **Verify Solution**
|
279
|
+
- All new tests pass
|
280
|
+
- All existing tests still pass
|
281
|
+
- RuboCop compliance maintained
|
282
|
+
- Manual testing if applicable
|
283
|
+
|
284
|
+
## IDE Configuration for AI Context
|
285
|
+
|
286
|
+
When analyzing codebases, ignore these directories to avoid confusion:
|
287
|
+
|
288
|
+
- `/coverage`, `/tmp`, `/gen-examples`
|
289
|
+
- `/node_package/lib`, `/node_modules`
|
290
|
+
- `/spec/dummy/app/assets/webpack`
|
291
|
+
- `/spec/dummy/log`, `/spec/dummy/node_modules`, `/spec/dummy/tmp`
|
292
|
+
- `/spec/react_on_rails/dummy-for-generators`
|
293
|
+
|
294
|
+
## Communication with Human Maintainers
|
295
|
+
|
296
|
+
- Be transparent about AI-generated changes
|
297
|
+
- Explain reasoning behind implementation choices
|
298
|
+
- Ask for clarification when requirements are ambiguous
|
299
|
+
- Provide comprehensive commit messages and PR descriptions
|
300
|
+
- Include test plans and verification steps
|
301
|
+
|
302
|
+
## Resources
|
303
|
+
|
304
|
+
- [Main Contributing Guide](./CONTRIBUTING.md)
|
305
|
+
- [Pull Request Guidelines](./docs/contributor-info/pull-requests.md)
|
306
|
+
- [Generator Testing](./docs/contributor-info/generator-testing.md)
|
307
|
+
- [RuboCop Documentation](https://docs.rubocop.org/)
|
308
|
+
- [RSpec Best Practices](https://rspec.info/)
|
309
|
+
|
310
|
+
---
|
311
|
+
|
312
|
+
This guide evolves based on AI contributor experiences. Suggest improvements via issues or PRs!
|