react-manifest-rails 0.2.2 → 0.2.5
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 +27 -0
- data/README.md +95 -276
- data/lib/react-manifest-rails.rb +1 -0
- data/lib/react_manifest/configuration.rb +18 -4
- data/lib/react_manifest/railtie.rb +46 -0
- data/lib/react_manifest/version.rb +1 -1
- data/lib/react_manifest/watcher.rb +1 -0
- data/tasks/react_manifest.rake +12 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 91ed3c8b3020fda5a5d811b059fdc654dd22c220878c42e76a42011ee899713e
|
|
4
|
+
data.tar.gz: a3ea26760e50e90e85d35a790fac7df24fbbaa38c717e56f071b61dc7003dcfd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6648f2f5dbe48b37a3a96db8a472308be09af4ca652a1b5cb70132ec82d7a6b423451298c5c58721baf566a8b798df33e05a6da7a399036d5b589385bf3ba0a
|
|
7
|
+
data.tar.gz: 25ec716c8cb0c806152762e0e70c93468a68b3d07cb68a002180be303be892953ae2f2b4b400343c1607e821b44928a7303f264ec2129366f200230d71e523e2
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.5] - 2026-04-15
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Updated root `Gemfile.lock` to stay in sync with gemspec version changes, fixing frozen Bundler install failures in the release workflow.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Follow-up release from `0.2.4` to ensure GitHub Release trusted publishing can complete successfully.
|
|
15
|
+
|
|
16
|
+
## [0.2.4] - 2026-04-15
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- Clarified configuration semantics for `ignore`, `exclude_paths`, `dry_run`, `verbose`, and `stdout_logging` in inline code comments.
|
|
20
|
+
- Updated README with clearer guidance on default configuration usage and explicit behavior notes for `ignore` vs `exclude_paths`.
|
|
21
|
+
- Documented that scanning scope is limited to `ux_root` and that `exclude_paths` is path-segment based (not `application.js` include based).
|
|
22
|
+
|
|
23
|
+
## [0.2.3] - 2026-04-15
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- Compatibility entrypoint (`lib/react-manifest-rails.rb`) so default Bundler auto-require reliably loads the Railtie and rake tasks.
|
|
27
|
+
- Development boot-time sync that generates missing `ux_*.js` manifests once on server start.
|
|
28
|
+
- Configurable stdout logging with `config.stdout_logging` for visible generation events in development.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
- Streamlined README into a concise development-first quickstart with direct troubleshooting for missing tasks and watcher behavior.
|
|
32
|
+
- Improved `react_manifest:generate` diagnostics when `ux_root` is missing or no controller bundles are detected.
|
|
33
|
+
- Watcher and boot-time generation now emit clearer runtime status lines for easier debugging.
|
|
34
|
+
|
|
8
35
|
## [0.2.2] - 2026-04-15
|
|
9
36
|
|
|
10
37
|
### Changed
|
data/README.md
CHANGED
|
@@ -1,353 +1,172 @@
|
|
|
1
1
|
# react-manifest-rails
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Generate per-controller Sprockets manifests for React code in Rails.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This gem creates `ux_*.js` bundles and includes them with `react_bundle_tag`.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Quick Start (Development)
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- **Smart file watching**: Automatically regenerates bundles when files change in development
|
|
11
|
-
- **Intelligent bundle resolution**: The `react_bundle_tag` view helper automatically selects the correct bundles for each controller
|
|
12
|
-
- **Namespace-aware**: Handles nested controllers and namespaces gracefully (e.g., `admin/users` → `ux_admin_users`)
|
|
13
|
-
- **Shared bundles**: Automatically extracts shared dependencies into a `ux_shared` bundle
|
|
14
|
-
- **Always-include bundles**: Configure bundles that should be loaded on every page
|
|
15
|
-
- **Production-ready**: Integrates seamlessly with `assets:precompile` for CI/production deployments
|
|
16
|
-
- **Zero configuration**: Works out-of-the-box with sensible defaults for standard Rails projects
|
|
17
|
-
|
|
18
|
-
## Advantages
|
|
19
|
-
|
|
20
|
-
### 1. Smaller Bundle Sizes
|
|
21
|
-
Instead of a single monolithic `application.js` that loads all React components for the entire app, each controller gets its own lean bundle containing only the components it needs. This means:
|
|
22
|
-
- **Faster page loads**: Users only download what they need
|
|
23
|
-
- **Better caching**: Components unchanged on their page won't bust the cache
|
|
24
|
-
- **Reduced bandwidth**: Particularly beneficial for mobile users
|
|
25
|
-
|
|
26
|
-
### 2. Simplified Development
|
|
27
|
-
- **Automatic regeneration**: Changes to component files are automatically bundled—no manual build steps
|
|
28
|
-
- **No configuration needed**: Works with standard Rails directory structures immediately
|
|
29
|
-
- **Easy integration**: Drop the gem in and it works with your existing `react-rails` setup
|
|
30
|
-
|
|
31
|
-
### 3. Production Reliability
|
|
32
|
-
- **CI/CD friendly**: Integrates with `assets:precompile` for automated deployments
|
|
33
|
-
- **Deterministic builds**: Consistent bundle generation across environments
|
|
34
|
-
- **Safety checks**: Warns about oversized bundles to catch potential issues
|
|
35
|
-
|
|
36
|
-
### 4. Developer Experience
|
|
37
|
-
- **Per-controller organization**: Bundle structure mirrors your Rails controller layout
|
|
38
|
-
- **Smart bundle selection**: View helper automatically picks the right bundles—no manual tag management
|
|
39
|
-
- **Clear visibility**: Built-in reporter shows exactly what's in each bundle
|
|
40
|
-
|
|
41
|
-
## Installation
|
|
42
|
-
|
|
43
|
-
Add the gem to your `Gemfile`:
|
|
9
|
+
1. Add gems:
|
|
44
10
|
|
|
45
11
|
```ruby
|
|
46
|
-
|
|
12
|
+
# Gemfile
|
|
13
|
+
gem "react-manifest-rails"
|
|
14
|
+
|
|
15
|
+
group :development do
|
|
16
|
+
gem "listen", "~> 3.0"
|
|
17
|
+
end
|
|
47
18
|
```
|
|
48
19
|
|
|
49
|
-
|
|
20
|
+
2. Install:
|
|
50
21
|
|
|
51
22
|
```bash
|
|
52
23
|
bundle install
|
|
53
24
|
```
|
|
54
25
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
### 1. Create your UX directory structure
|
|
58
|
-
|
|
59
|
-
By default, the gem expects your React components to live in `app/assets/javascripts/ux/`. You should organize it like this:
|
|
26
|
+
If your app uses this standard layout, you can keep defaults and only create the initializer if you want overrides:
|
|
60
27
|
|
|
28
|
+
```text
|
|
29
|
+
ux_root: app/assets/javascripts/ux
|
|
30
|
+
app_dir: app
|
|
31
|
+
output_dir: app/assets/javascripts
|
|
32
|
+
extensions: js, jsx
|
|
61
33
|
```
|
|
62
|
-
app/assets/javascripts/ux/
|
|
63
|
-
├── app/ # Per-controller components (becomes ux_*.js bundles)
|
|
64
|
-
│ ├── users/
|
|
65
|
-
│ │ ├── UserCard.jsx
|
|
66
|
-
│ │ └── UserList.jsx
|
|
67
|
-
│ ├── products/
|
|
68
|
-
│ │ └── ProductGrid.jsx
|
|
69
|
-
│ └── dashboard/
|
|
70
|
-
│ └── Dashboard.jsx
|
|
71
|
-
├── shared/ # Shared utilities (becomes ux_shared)
|
|
72
|
-
│ ├── api.js
|
|
73
|
-
│ └── utils.js
|
|
74
|
-
└── components/ # Global components (becomes ux_shared)
|
|
75
|
-
└── Navigation.jsx
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### 2. Configure the gem (Optional)
|
|
79
34
|
|
|
80
|
-
|
|
35
|
+
3. Add initializer:
|
|
81
36
|
|
|
82
37
|
```ruby
|
|
38
|
+
# config/initializers/react_manifest.rb
|
|
39
|
+
require "react_manifest"
|
|
40
|
+
|
|
83
41
|
ReactManifest.configure do |config|
|
|
84
|
-
# Where your UX root lives (default: "app/assets/javascripts/ux")
|
|
85
42
|
config.ux_root = "app/assets/javascripts/ux"
|
|
86
|
-
|
|
87
|
-
# Subdir within ux_root containing per-controller components (default: "app")
|
|
88
43
|
config.app_dir = "app"
|
|
89
|
-
|
|
90
|
-
# Where generated manifests are written (default: "app/assets/javascripts")
|
|
91
44
|
config.output_dir = "app/assets/javascripts"
|
|
92
|
-
|
|
93
|
-
# Name of the shared bundle (default: "ux_shared")
|
|
94
45
|
config.shared_bundle = "ux_shared"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
# Directories within app_dir to ignore (default: [])
|
|
100
|
-
# config.ignore = ["internal_tools"]
|
|
101
|
-
|
|
102
|
-
# Warn if any bundle exceeds this size in KB (default: 500, 0 to disable)
|
|
46
|
+
config.always_include = []
|
|
47
|
+
config.ignore = []
|
|
48
|
+
config.exclude_paths = ["react", "react_dev", "vendor"]
|
|
103
49
|
config.size_threshold_kb = 500
|
|
50
|
+
config.dry_run = false
|
|
51
|
+
config.verbose = false
|
|
52
|
+
config.stdout_logging = true
|
|
104
53
|
end
|
|
105
54
|
```
|
|
106
55
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
In your layout template (`app/views/layouts/application.html.erb` or similar):
|
|
110
|
-
|
|
111
|
-
```erb
|
|
112
|
-
<head>
|
|
113
|
-
<%= javascript_include_tag "application" %>
|
|
114
|
-
<%= react_bundle_tag defer: true %>
|
|
115
|
-
</head>
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
The `react_bundle_tag` helper automatically:
|
|
119
|
-
1. Includes the shared bundle (`ux_shared`)
|
|
120
|
-
2. Includes any bundles in `config.always_include`
|
|
121
|
-
3. Includes the controller-specific bundle (e.g., `ux_users` for UsersController)
|
|
122
|
-
4. Returns an empty string gracefully if there's no matching bundle
|
|
123
|
-
|
|
124
|
-
## How It Works
|
|
125
|
-
|
|
126
|
-
### Bundle Generation
|
|
127
|
-
|
|
128
|
-
The gem scans your `app/assets/javascripts/ux/` directory and generates Sprockets manifests:
|
|
129
|
-
|
|
130
|
-
- **Controller-specific bundles**: Each directory under `ux/app/` becomes a bundle
|
|
131
|
-
- `ux/app/users/` → `ux_users.js`
|
|
132
|
-
- `ux/app/admin/reports/` → `ux_admin_reports.js`
|
|
133
|
-
|
|
134
|
-
- **Shared bundle**: Everything outside `ux/app/` (e.g., `shared/`, `components/`) automatically goes into `ux_shared.js`
|
|
135
|
-
|
|
136
|
-
- **Dependency tracking**: The gem analyzes dependencies to prevent duplication across bundles
|
|
137
|
-
|
|
138
|
-
### Development
|
|
139
|
-
|
|
140
|
-
In development, a file watcher automatically:
|
|
141
|
-
- Detects changes to component files
|
|
142
|
-
- Regenerates affected bundles
|
|
143
|
-
- Updates manifests in real-time
|
|
144
|
-
|
|
145
|
-
### Production
|
|
146
|
-
|
|
147
|
-
The gem integrates with Rails' `assets:precompile` task:
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
rails assets:precompile
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
This ensures all bundles are generated before deployment.
|
|
154
|
-
|
|
155
|
-
## View Helper Usage
|
|
156
|
-
|
|
157
|
-
### Basic usage
|
|
56
|
+
4. Put React files under:
|
|
158
57
|
|
|
159
|
-
```
|
|
160
|
-
|
|
58
|
+
```text
|
|
59
|
+
app/assets/javascripts/ux/
|
|
60
|
+
app/
|
|
61
|
+
users/
|
|
62
|
+
users_index.jsx
|
|
63
|
+
components/
|
|
64
|
+
nav.jsx
|
|
161
65
|
```
|
|
162
66
|
|
|
163
|
-
|
|
67
|
+
5. Include bundles in your layout:
|
|
164
68
|
|
|
165
69
|
```erb
|
|
166
|
-
<%= react_bundle_tag defer: true
|
|
70
|
+
<%= react_bundle_tag defer: true %>
|
|
167
71
|
```
|
|
168
72
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
The helper automatically resolves bundles based on `controller_path`:
|
|
172
|
-
|
|
173
|
-
| Controller | Resolved Bundles |
|
|
174
|
-
|-----------|------------------|
|
|
175
|
-
| UsersController | ux_shared + ux_users |
|
|
176
|
-
| Admin::ReportsController | ux_shared + ux_admin_reports (or ux_admin if not found) |
|
|
177
|
-
| Pages::LandingController | ux_shared + ux_pages_landing (or ux_pages, or ux_landing) |
|
|
178
|
-
|
|
179
|
-
## Rake Tasks
|
|
180
|
-
|
|
181
|
-
### Generate bundles (one-time)
|
|
73
|
+
6. Start server:
|
|
182
74
|
|
|
183
75
|
```bash
|
|
184
|
-
rails
|
|
76
|
+
bundle exec rails s
|
|
185
77
|
```
|
|
186
78
|
|
|
187
|
-
|
|
79
|
+
In development:
|
|
80
|
+
- If expected `ux_*.js` files are missing, the gem generates them once on boot.
|
|
81
|
+
- If `listen` is installed, file changes regenerate manifests automatically.
|
|
82
|
+
- If `listen` is missing, run `bundle exec rails react_manifest:generate` manually.
|
|
83
|
+
- Set `config.stdout_logging = false` to silence ReactManifest console lines while keeping Rails logger output.
|
|
188
84
|
|
|
189
|
-
|
|
190
|
-
rails react_manifest:watch
|
|
191
|
-
```
|
|
85
|
+
## Configuration Notes
|
|
192
86
|
|
|
193
|
-
|
|
87
|
+
- `ignore`:
|
|
88
|
+
- Skips controller directory names directly under `ux/app/`.
|
|
89
|
+
- Example: `ignore = ["admin"]` skips `ux/app/admin/*`.
|
|
194
90
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
91
|
+
- `exclude_paths`:
|
|
92
|
+
- Excludes files by matching path segments while scanning the `ux_root` tree.
|
|
93
|
+
- Example: `exclude_paths = ["vendor"]` excludes `ux/vendor/*` and any nested `.../vendor/...` segment.
|
|
94
|
+
- This is not based on what is included in `application.js`.
|
|
198
95
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
| Option | Default | Description |
|
|
202
|
-
|--------|---------|-------------|
|
|
203
|
-
| `ux_root` | `"app/assets/javascripts/ux"` | Root directory of your React components |
|
|
204
|
-
| `app_dir` | `"app"` | Subdirectory of `ux_root` for per-controller components |
|
|
205
|
-
| `output_dir` | `"app/assets/javascripts"` | Where generated manifests are written |
|
|
206
|
-
| `shared_bundle` | `"ux_shared"` | Name of the shared bundle |
|
|
207
|
-
| `always_include` | `[]` | Array of bundle names to load on every page |
|
|
208
|
-
| `ignore` | `[]` | Directories to skip during scanning |
|
|
209
|
-
| `exclude_paths` | `["react", "react_dev", "vendor"]` | Top-level directories to exclude |
|
|
210
|
-
| `size_threshold_kb` | `500` | Warn if a bundle exceeds this size (0 = disabled) |
|
|
211
|
-
| `dry_run` | `false` | Print what would change without writing files |
|
|
212
|
-
| `verbose` | `false` | Enable extra logging |
|
|
96
|
+
- `dry_run`:
|
|
97
|
+
- Preview mode only; computes and prints changes but writes no files.
|
|
213
98
|
|
|
214
|
-
|
|
99
|
+
- `verbose` vs `stdout_logging`:
|
|
100
|
+
- `verbose`: extra diagnostic detail.
|
|
101
|
+
- `stdout_logging`: whether ReactManifest status lines are printed to terminal stdout.
|
|
215
102
|
|
|
216
|
-
|
|
217
|
-
-
|
|
218
|
-
- Run `rails react_manifest:report` to see what bundles were detected
|
|
219
|
-
- Check Rails logs for any file watcher errors
|
|
103
|
+
- Scope:
|
|
104
|
+
- Manifest generation only scans files under `ux_root`.
|
|
220
105
|
|
|
221
|
-
|
|
222
|
-
- Verify `react_bundle_tag` is in your layout
|
|
223
|
-
- Check that the bundle name matches your controller path
|
|
224
|
-
- Make sure components are in the `ux/` directory, not elsewhere
|
|
106
|
+
## What Gets Generated
|
|
225
107
|
|
|
226
|
-
|
|
227
|
-
-
|
|
228
|
-
- Consider splitting large bundles into smaller, more focused ones
|
|
229
|
-
- Adjust `config.size_threshold_kb` in your initializer if needed
|
|
108
|
+
- `ux_shared.js`: shared files outside `ux/app/`
|
|
109
|
+
- `ux_<controller>.js`: one bundle per directory under `ux/app/`
|
|
230
110
|
|
|
231
|
-
|
|
111
|
+
Example:
|
|
112
|
+
- `ux/app/users/...` -> `ux_users.js`
|
|
113
|
+
- `ux/app/admin/...` -> `ux_admin.js`
|
|
232
114
|
|
|
233
|
-
|
|
115
|
+
## Commands
|
|
234
116
|
|
|
235
|
-
|
|
236
|
-
ReactManifest.configure do |config|
|
|
237
|
-
config.extensions = %w[js jsx ts tsx]
|
|
238
|
-
end
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
This affects file scanning, manifest generation, and the development file watcher.
|
|
242
|
-
|
|
243
|
-
## File Watching (`listen` gem)
|
|
244
|
-
|
|
245
|
-
The development file watcher requires the `listen` gem, which is **not** a hard dependency. If `listen` is absent the watcher is silently disabled and you must regenerate manifests manually.
|
|
246
|
-
|
|
247
|
-
To enable watching, add `listen` to the development group in your app's `Gemfile`:
|
|
248
|
-
|
|
249
|
-
```ruby
|
|
250
|
-
gem "listen", "~> 3.0", group: :development
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
> **Note:** Changes to `config/initializers/react_manifest.rb` are not picked up by the watcher — you must restart the server after editing the initializer.
|
|
254
|
-
|
|
255
|
-
## Migrating an Existing `application.js`
|
|
256
|
-
|
|
257
|
-
If you are adding this gem to an app that already has a monolithic `application.js`, use the built-in migration tools:
|
|
258
|
-
|
|
259
|
-
**Step 1 — Analyse what's there:**
|
|
260
|
-
|
|
261
|
-
```bash
|
|
262
|
-
rails react_manifest:analyze
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
This classifies each `//= require` line as `:vendor` (keep), `:ux_code` (remove), or `:unknown` (review manually). No files are modified.
|
|
266
|
-
|
|
267
|
-
**Step 2 — Preview changes:**
|
|
117
|
+
- Generate manifests now:
|
|
268
118
|
|
|
269
119
|
```bash
|
|
270
|
-
|
|
120
|
+
bundle exec rails react_manifest:generate
|
|
271
121
|
```
|
|
272
122
|
|
|
273
|
-
|
|
123
|
+
- Watch in foreground (debugging only; not required in normal dev):
|
|
274
124
|
|
|
275
125
|
```bash
|
|
276
|
-
rails react_manifest:
|
|
126
|
+
bundle exec rails react_manifest:watch
|
|
277
127
|
```
|
|
278
128
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
**Step 4 — Generate bundles and verify:**
|
|
129
|
+
- Print bundle size report:
|
|
282
130
|
|
|
283
131
|
```bash
|
|
284
|
-
rails react_manifest:
|
|
285
|
-
rails assets:precompile # or just start the dev server
|
|
132
|
+
bundle exec rails react_manifest:report
|
|
286
133
|
```
|
|
287
134
|
|
|
288
|
-
**Rolling back:** Simply restore the `.bak` file and remove the generated `ux_*.js` manifests.
|
|
289
|
-
|
|
290
135
|
## Troubleshooting
|
|
291
136
|
|
|
292
|
-
###
|
|
293
|
-
- Verify components live under `ux/app/<controller>/` (not directly under `ux/`)
|
|
294
|
-
- Run `rails react_manifest:report` to see detected bundles
|
|
295
|
-
- Check Rails logs for file watcher errors
|
|
296
|
-
|
|
297
|
-
### Components not loading
|
|
298
|
-
- Confirm `react_bundle_tag` is present in your layout
|
|
299
|
-
- Check that the bundle name matches your controller path
|
|
300
|
-
- Run `rails react_manifest:generate` to force regeneration
|
|
137
|
+
### `react_manifest:generate` is not recognized
|
|
301
138
|
|
|
302
|
-
|
|
303
|
-
- A bundle name in `config.always_include` that is also the controller bundle will be deduplicated automatically. Check whether both the shared bundle name and a specific bundle are listed in `always_include`.
|
|
139
|
+
Run:
|
|
304
140
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
141
|
+
```bash
|
|
142
|
+
bundle exec rails -T | grep react_manifest
|
|
143
|
+
```
|
|
308
144
|
|
|
309
|
-
|
|
310
|
-
-
|
|
311
|
-
-
|
|
145
|
+
If nothing appears:
|
|
146
|
+
- Confirm the gem is in `Gemfile` and installed (`bundle show react-manifest-rails`).
|
|
147
|
+
- Ensure the gem is not disabled with `require: false`.
|
|
148
|
+
- Restart Spring/server (`bin/spring stop`, then re-run command).
|
|
312
149
|
|
|
313
|
-
###
|
|
314
|
-
- The gem warns when bundles exceed `config.size_threshold_kb` (default 500 KB)
|
|
315
|
-
- Consider splitting large controller directories or moving shared code into the shared bundle
|
|
316
|
-
- Adjust the threshold: `config.size_threshold_kb = 1000`
|
|
150
|
+
### Server starts but nothing happens
|
|
317
151
|
|
|
318
|
-
|
|
152
|
+
Check these in order:
|
|
153
|
+
- `app/assets/javascripts/ux` exists.
|
|
154
|
+
- Your controller files are under `ux/app/<controller>/`.
|
|
155
|
+
- Your layout includes `<%= react_bundle_tag %>`.
|
|
156
|
+
- Run `bundle exec rails react_manifest:generate` once and check for generated `ux_*.js` in `app/assets/javascripts`.
|
|
319
157
|
|
|
320
|
-
|
|
321
|
-
|----------|-------------|
|
|
322
|
-
| Initial generation (small project, ~20 controllers) | < 1 s |
|
|
323
|
-
| Initial generation (large project, ~100 controllers) | 2–5 s |
|
|
324
|
-
| Watcher debounce (regeneration after file change) | ~300 ms |
|
|
325
|
-
| Memory overhead (symbol index, large project) | < 10 MB |
|
|
158
|
+
### Auto-watch in dev does not run
|
|
326
159
|
|
|
327
|
-
|
|
160
|
+
- Ensure `listen` is in the development group.
|
|
161
|
+
- Restart the Rails server after adding `listen`.
|
|
162
|
+
- If you choose not to install `listen`, manual generation is the supported fallback.
|
|
328
163
|
|
|
329
164
|
## Compatibility
|
|
330
165
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
| Rails / Railties | 6.1 – 8.x |
|
|
335
|
-
| Sprockets | 3.x, 4.x |
|
|
336
|
-
| listen (optional) | ~> 3.0 |
|
|
337
|
-
|
|
338
|
-
> **Pre-1.0 notice:** The public API (configuration keys, rake task names, view helper signature) may change in minor versions until 1.0 is released. Pin to a patch version if stability is critical: `gem "react-manifest-rails", "~> 0.1.0"`.
|
|
339
|
-
|
|
340
|
-
## Requirements
|
|
341
|
-
|
|
342
|
-
- Ruby >= 3.2
|
|
343
|
-
- Rails >= 6.1
|
|
344
|
-
- Sprockets
|
|
345
|
-
- react-rails
|
|
166
|
+
- Ruby: 3.2+
|
|
167
|
+
- Rails/Railties: 7.x to 8.x
|
|
168
|
+
- Asset pipeline: Sprockets
|
|
346
169
|
|
|
347
170
|
## License
|
|
348
171
|
|
|
349
|
-
MIT
|
|
350
|
-
|
|
351
|
-
## Contributing
|
|
352
|
-
|
|
353
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/olivernoonan/react-manifest-rails.
|
|
172
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "react_manifest_rails"
|
|
@@ -23,10 +23,14 @@ module ReactManifest
|
|
|
23
23
|
# Bundles always prepended by react_bundle_tag (e.g. ["ux_main"])
|
|
24
24
|
attr_accessor :always_include
|
|
25
25
|
|
|
26
|
-
#
|
|
26
|
+
# Controller directory names directly under ux_root/app_dir to skip entirely.
|
|
27
|
+
# Example: ignore = ["admin"] skips ux/app/admin/* when building ux_<controller>.js.
|
|
27
28
|
attr_accessor :ignore
|
|
28
29
|
|
|
29
|
-
#
|
|
30
|
+
# Path segments to exclude while scanning files under ux_root.
|
|
31
|
+
# This is segment matching (not full path matching), so "vendor" excludes
|
|
32
|
+
# ux/vendor/foo.js and ux/app/users/vendor/bar.jsx, but not ux/vendor_custom/x.js.
|
|
33
|
+
# These are not application.js includes; they only affect ux tree scanning.
|
|
30
34
|
attr_accessor :exclude_paths
|
|
31
35
|
|
|
32
36
|
# Warn if a bundle exceeds this size in KB (0 = disabled)
|
|
@@ -35,12 +39,17 @@ module ReactManifest
|
|
|
35
39
|
# File extensions to scan (default: js and jsx; add "ts", "tsx" for TypeScript)
|
|
36
40
|
attr_accessor :extensions
|
|
37
41
|
|
|
38
|
-
#
|
|
42
|
+
# Preview mode: print what would change, write nothing.
|
|
43
|
+
# Applies anywhere generation runs (manual task, boot sync, watcher).
|
|
39
44
|
attr_accessor :dry_run
|
|
40
45
|
|
|
41
|
-
# Extra logging
|
|
46
|
+
# Extra diagnostic logging (summary lines and richer error context).
|
|
42
47
|
attr_accessor :verbose
|
|
43
48
|
|
|
49
|
+
# Emit ReactManifest status lines to stdout in development.
|
|
50
|
+
# Independent from Rails.logger output.
|
|
51
|
+
attr_accessor :stdout_logging
|
|
52
|
+
|
|
44
53
|
def initialize
|
|
45
54
|
@ux_root = "app/assets/javascripts/ux"
|
|
46
55
|
@app_dir = "app"
|
|
@@ -53,6 +62,7 @@ module ReactManifest
|
|
|
53
62
|
@extensions = %w[js jsx]
|
|
54
63
|
@dry_run = false
|
|
55
64
|
@verbose = false
|
|
65
|
+
@stdout_logging = true
|
|
56
66
|
end
|
|
57
67
|
|
|
58
68
|
def dry_run?
|
|
@@ -63,6 +73,10 @@ module ReactManifest
|
|
|
63
73
|
!!@verbose
|
|
64
74
|
end
|
|
65
75
|
|
|
76
|
+
def stdout_logging?
|
|
77
|
+
!!@stdout_logging
|
|
78
|
+
end
|
|
79
|
+
|
|
66
80
|
# Glob fragment used by Dir.glob, e.g. "*.{js,jsx}" or "*.{js,jsx,ts,tsx}"
|
|
67
81
|
def extensions_glob
|
|
68
82
|
"*.{#{extensions.join(',')}}"
|
|
@@ -2,6 +2,35 @@ require "rails/railtie"
|
|
|
2
2
|
|
|
3
3
|
module ReactManifest
|
|
4
4
|
class Railtie < Rails::Railtie
|
|
5
|
+
# ----------------------------------------------------------------
|
|
6
|
+
# In development, generate once on boot if expected manifests are missing.
|
|
7
|
+
# This makes first-run setup deterministic even before any file change event.
|
|
8
|
+
# ----------------------------------------------------------------
|
|
9
|
+
initializer "react_manifest.ensure_manifests" do
|
|
10
|
+
next unless Rails.env.development?
|
|
11
|
+
|
|
12
|
+
config = ReactManifest.configuration
|
|
13
|
+
missing = self.class.missing_manifest_bundles(config)
|
|
14
|
+
next if missing.empty?
|
|
15
|
+
|
|
16
|
+
message = "[ReactManifest] Missing manifests on boot: #{missing.join(', ')}. Generating now..."
|
|
17
|
+
Rails.logger&.info(message)
|
|
18
|
+
$stdout.puts(message) if config.stdout_logging?
|
|
19
|
+
|
|
20
|
+
begin
|
|
21
|
+
results = ReactManifest::Generator.new(config).run!
|
|
22
|
+
written = results.count { |r| r[:status] == :written }
|
|
23
|
+
unchanged = results.count { |r| r[:status] == :unchanged }
|
|
24
|
+
done = "[ReactManifest] Boot generation complete: #{written} written, #{unchanged} unchanged"
|
|
25
|
+
Rails.logger&.info(done)
|
|
26
|
+
$stdout.puts(done) if config.stdout_logging?
|
|
27
|
+
rescue StandardError => e
|
|
28
|
+
error = "[ReactManifest] Could not generate manifests on boot: #{e.message}"
|
|
29
|
+
Rails.logger&.warn(error)
|
|
30
|
+
$stdout.puts(error) if config.stdout_logging?
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
5
34
|
# Expose config as Rails.application.config.react_manifest
|
|
6
35
|
config.react_manifest = ReactManifest.configuration
|
|
7
36
|
|
|
@@ -12,6 +41,7 @@ module ReactManifest
|
|
|
12
41
|
if Rails.env.development? && !ReactManifest::Watcher.running?
|
|
13
42
|
begin
|
|
14
43
|
ReactManifest::Watcher.start(ReactManifest.configuration)
|
|
44
|
+
Rails.logger&.info("[ReactManifest] Development watcher is active") if ReactManifest.configuration.verbose?
|
|
15
45
|
rescue StandardError => e
|
|
16
46
|
Rails.logger.warn "[ReactManifest] Could not start file watcher: #{e.message}"
|
|
17
47
|
end
|
|
@@ -42,5 +72,21 @@ module ReactManifest
|
|
|
42
72
|
Rake::Task["assets:precompile"].enhance(["react_manifest:generate"])
|
|
43
73
|
end
|
|
44
74
|
end
|
|
75
|
+
|
|
76
|
+
class << self
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
def missing_manifest_bundles(config)
|
|
80
|
+
output_dir = config.abs_output_dir
|
|
81
|
+
expected_manifest_bundles(config).reject do |bundle_name|
|
|
82
|
+
File.exist?(File.join(output_dir, "#{bundle_name}.js"))
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def expected_manifest_bundles(config)
|
|
87
|
+
classification = ReactManifest::TreeClassifier.new(config).classify
|
|
88
|
+
([config.shared_bundle] + classification.controller_dirs.map { |ctrl| ctrl[:bundle_name] }).uniq
|
|
89
|
+
end
|
|
90
|
+
end
|
|
45
91
|
end
|
|
46
92
|
end
|
data/tasks/react_manifest.rake
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
namespace :react_manifest do
|
|
2
2
|
desc "Generate all ux_*.js Sprockets manifests from the ux/ directory tree"
|
|
3
3
|
task generate: :environment do
|
|
4
|
-
|
|
4
|
+
config = ReactManifest.configuration
|
|
5
|
+
|
|
6
|
+
unless Dir.exist?(config.abs_ux_root)
|
|
7
|
+
puts "[ReactManifest] ux_root not found: #{config.abs_ux_root}"
|
|
8
|
+
puts "[ReactManifest] Create it (for example: app/assets/javascripts/ux) then run this task again."
|
|
9
|
+
next
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
results = ReactManifest::Generator.new(config).run!
|
|
5
13
|
|
|
6
14
|
written = results.count { |r| r[:status] == :written }
|
|
7
15
|
unchanged = results.count { |r| r[:status] == :unchanged }
|
|
@@ -12,6 +20,9 @@ namespace :react_manifest do
|
|
|
12
20
|
puts "[ReactManifest] DRY-RUN complete: #{dry} manifest(s) would be written"
|
|
13
21
|
else
|
|
14
22
|
puts "[ReactManifest] Done: #{written} written, #{unchanged} unchanged, #{skipped} skipped"
|
|
23
|
+
if (written + unchanged + skipped).zero?
|
|
24
|
+
puts "[ReactManifest] No manifests generated. Ensure ux/app/<controller>/ contains .js or .jsx files."
|
|
25
|
+
end
|
|
15
26
|
end
|
|
16
27
|
|
|
17
28
|
# Print any scanner warnings
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: react-manifest-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Oliver Noonan
|
|
@@ -134,6 +134,7 @@ extra_rdoc_files: []
|
|
|
134
134
|
files:
|
|
135
135
|
- CHANGELOG.md
|
|
136
136
|
- README.md
|
|
137
|
+
- lib/react-manifest-rails.rb
|
|
137
138
|
- lib/react_manifest.rb
|
|
138
139
|
- lib/react_manifest/application_analyzer.rb
|
|
139
140
|
- lib/react_manifest/application_migrator.rb
|