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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36adf78621e6d6b409a6242cccfe34fc7ab916357771c81683c17ef58c80b9a7
4
- data.tar.gz: 4a4f18f2c4b3749376bb2c3adae8c9be6a881f9df04411a49c903c01d917282f
3
+ metadata.gz: 91ed3c8b3020fda5a5d811b059fdc654dd22c220878c42e76a42011ee899713e
4
+ data.tar.gz: a3ea26760e50e90e85d35a790fac7df24fbbaa38c717e56f071b61dc7003dcfd
5
5
  SHA512:
6
- metadata.gz: 665b92d9ba95e189fbc7791ad3a620df282df1ac9d865ccdd481618f41d47f53d86cb013881f5beac312115b73a7f862933145980ba6b4d9cda872ec3cd3e938
7
- data.tar.gz: 2be3a86848583a94dcf49cd0b1f637b20d9f88ed8f2ca5abafe357f50ae51589d74c14164024a46e4c0ef6b9f969baa0e76017ba79518b4d98d1ff8a72716e59
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
- **Zero-touch Sprockets manifest generation for react-rails apps**
3
+ Generate per-controller Sprockets manifests for React code in Rails.
4
4
 
5
- A Rails gem that automatically generates lean, controller-specific JavaScript bundles for applications using `react-rails` and Sprockets, eliminating the need for monolithic `application.js` files.
5
+ This gem creates `ux_*.js` bundles and includes them with `react_bundle_tag`.
6
6
 
7
- ## Features
7
+ ## Quick Start (Development)
8
8
 
9
- - **Automatic bundle generation**: Creates per-controller `ux_*.js` manifests on-demand
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
- gem 'react-manifest-rails'
12
+ # Gemfile
13
+ gem "react-manifest-rails"
14
+
15
+ group :development do
16
+ gem "listen", "~> 3.0"
17
+ end
47
18
  ```
48
19
 
49
- Then run:
20
+ 2. Install:
50
21
 
51
22
  ```bash
52
23
  bundle install
53
24
  ```
54
25
 
55
- ## Setup
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
- Create an initializer at `config/initializers/react_manifest.rb`:
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
- # Bundles to always include on every page (default: [])
97
- # config.always_include = ["ux_main"]
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
- ### 3. Use the view helper
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
- ```erb
160
- <%= react_bundle_tag %>
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
- ### With HTML options
67
+ 5. Include bundles in your layout:
164
68
 
165
69
  ```erb
166
- <%= react_bundle_tag defer: true, async: true %>
70
+ <%= react_bundle_tag defer: true %>
167
71
  ```
168
72
 
169
- ### Automatic resolution
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 react_manifest:generate
76
+ bundle exec rails s
185
77
  ```
186
78
 
187
- ### Watch for changes (development)
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
- ```bash
190
- rails react_manifest:watch
191
- ```
85
+ ## Configuration Notes
192
86
 
193
- ### Show bundle contents
87
+ - `ignore`:
88
+ - Skips controller directory names directly under `ux/app/`.
89
+ - Example: `ignore = ["admin"]` skips `ux/app/admin/*`.
194
90
 
195
- ```bash
196
- rails react_manifest:report
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
- ## Configuration Reference
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
- ## Troubleshooting
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
- ### Bundle not being generated
217
- - Check that your components are in the correct directory structure (`app/assets/javascripts/ux/app/...`)
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
- ### Components not loading
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
- ### Size warnings
227
- - The gem warns when bundles exceed 500KB
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
- ## TypeScript / Custom Extensions
111
+ Example:
112
+ - `ux/app/users/...` -> `ux_users.js`
113
+ - `ux/app/admin/...` -> `ux_admin.js`
232
114
 
233
- By default the gem scans `*.js` and `*.jsx` files. To add TypeScript support:
115
+ ## Commands
234
116
 
235
- ```ruby
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
- REACT_MANIFEST_DRY_RUN=1 rails react_manifest:migrate_application
120
+ bundle exec rails react_manifest:generate
271
121
  ```
272
122
 
273
- **Step 3 Apply changes:**
123
+ - Watch in foreground (debugging only; not required in normal dev):
274
124
 
275
125
  ```bash
276
- rails react_manifest:migrate_application
126
+ bundle exec rails react_manifest:watch
277
127
  ```
278
128
 
279
- A `.bak` backup is created next to each modified file before any write.
280
-
281
- **Step 4 — Generate bundles and verify:**
129
+ - Print bundle size report:
282
130
 
283
131
  ```bash
284
- rails react_manifest:generate
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
- ### Bundle not being generated
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
- ### Bundle appears more than once in HTML output
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
- ### Watcher stops responding
306
- - This is usually resolved by restarting the development server
307
- - Ensure the `listen` gem is installed (see above)
141
+ ```bash
142
+ bundle exec rails -T | grep react_manifest
143
+ ```
308
144
 
309
- ### Generator crashes on first run
310
- - Check that the process has write permission to `config.output_dir`
311
- - Verify `config.ux_root` exists; the generator is a no-op if the directory is missing
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
- ### Size warnings
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
- ## Performance
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
- | Scenario | Typical time |
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
- Scanning is purely regex-based no Node.js or transpilation step required.
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
- | Dependency | Supported versions |
332
- |------------|-------------------|
333
- | Ruby | 3.2, 3.3 |
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 License. See LICENSE for details.
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
- # Directories under app_dir to completely ignore
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
- # Top-level dirs under output_dir to never scan (vendor libs, etc.)
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
- # Print what would change, write nothing
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
@@ -1,3 +1,3 @@
1
1
  module ReactManifest
2
- VERSION = "0.2.2".freeze
2
+ VERSION = "0.2.5".freeze
3
3
  end
@@ -65,6 +65,7 @@ module ReactManifest
65
65
  msg = "[ReactManifest] #{message}"
66
66
  if defined?(Rails) && Rails.logger
67
67
  Rails.logger.info(msg)
68
+ $stdout.puts(msg) if Rails.env.development? && ReactManifest.configuration.stdout_logging?
68
69
  else
69
70
  $stdout.puts msg
70
71
  end
@@ -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
- results = ReactManifest::Generator.new.run!
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.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