railpack 1.3.0 → 1.3.1
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 +10 -0
- data/README.md +58 -0
- data/lib/railpack/manager.rb +82 -82
- data/lib/railpack/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f0e77f850d344d1b29f2e275c3cd49be7a4a684d0f3d5c880d03146b5cbeed6b
|
|
4
|
+
data.tar.gz: 2d2874defb0fd76f9c2c0ca3d4e746edf9067ce59fba07ef151ff096ffad5016
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7308ab9513cfbdb703dac82f3534b8382948e9ee705dc39505014ad951141e3e75c7c2277977e20912975236b9f0efbe9acecf0032ad4203723a273f48cb8d9
|
|
7
|
+
data.tar.gz: 652705db3d4555423ea5ddcfbf8aecb6aa3584063a1c594934594052e5d7ec370c8ac44e7804092963a5b550f740fc15b414e86d03cb53811f732a0638b384d6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.3.1] - 2026-01-26
|
|
4
|
+
|
|
5
|
+
This patch release includes final polish and documentation improvements.
|
|
6
|
+
|
|
7
|
+
### Changes
|
|
8
|
+
|
|
9
|
+
- **Code style**: Properly indented private methods and removed duplicate `private` keyword
|
|
10
|
+
- **Pre-build validation**: Added `FileUtils.mkdir_p(outdir)` to ensure output directories exist before build
|
|
11
|
+
- **Documentation**: Added comprehensive examples for `analyze_bundle` (gzip output), build hooks (payload details), and manifest delegation
|
|
12
|
+
|
|
3
13
|
## [1.3.0] - 2026-01-26
|
|
4
14
|
|
|
5
15
|
### 🚀 **Major Architecture Refactoring**
|
data/README.md
CHANGED
|
@@ -43,6 +43,7 @@ default:
|
|
|
43
43
|
sourcemap: false
|
|
44
44
|
entrypoint: "./app/javascript/application.js"
|
|
45
45
|
outdir: "app/assets/builds"
|
|
46
|
+
analyze_bundle: false # Enable for gzip size reporting
|
|
46
47
|
|
|
47
48
|
# Bundler-specific config
|
|
48
49
|
bun:
|
|
@@ -52,9 +53,11 @@ bun:
|
|
|
52
53
|
# Environment overrides
|
|
53
54
|
development:
|
|
54
55
|
sourcemap: true
|
|
56
|
+
analyze_bundle: true # Show gzip sizes in dev
|
|
55
57
|
|
|
56
58
|
production:
|
|
57
59
|
minify: true
|
|
60
|
+
analyze_bundle: true # Production bundle analysis
|
|
58
61
|
```
|
|
59
62
|
|
|
60
63
|
## Usage
|
|
@@ -111,6 +114,61 @@ Railpack.on_build_complete do |result|
|
|
|
111
114
|
end
|
|
112
115
|
```
|
|
113
116
|
|
|
117
|
+
### Advanced Usage
|
|
118
|
+
|
|
119
|
+
#### Bundle Analysis with Gzip
|
|
120
|
+
|
|
121
|
+
Enable `analyze_bundle: true` to see both uncompressed and gzipped bundle sizes:
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
# config/railpack.yml
|
|
125
|
+
default:
|
|
126
|
+
analyze_bundle: true
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Output example:
|
|
130
|
+
```
|
|
131
|
+
✅ Build completed successfully in 45.23ms (1.23 MB (0.45 MB gzipped))
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### Build Hooks with Payload Details
|
|
135
|
+
|
|
136
|
+
Hook payloads provide detailed information about build results:
|
|
137
|
+
|
|
138
|
+
```ruby
|
|
139
|
+
# config/initializers/railpack.rb
|
|
140
|
+
Railpack.on_build_complete do |payload|
|
|
141
|
+
if payload[:success]
|
|
142
|
+
# Success payload: { success: true, config: {...}, duration: 45.23, bundle_size: "1.23 MB" }
|
|
143
|
+
Rails.logger.info "Build succeeded in #{payload[:duration]}ms - #{payload[:bundle_size]}"
|
|
144
|
+
else
|
|
145
|
+
# Error payload: { success: false, error: #<Error>, config: {...}, duration: 12.34 }
|
|
146
|
+
Rails.logger.error "Build failed after #{payload[:duration]}ms: #{payload[:error].message}"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
Railpack.on_build_start do |config|
|
|
151
|
+
# Config hash contains all current settings
|
|
152
|
+
Rails.logger.info "Starting #{config['bundler']} build for #{Rails.env}"
|
|
153
|
+
end
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### Manifest Generation
|
|
157
|
+
|
|
158
|
+
Railpack automatically detects your asset pipeline and generates appropriate manifests:
|
|
159
|
+
|
|
160
|
+
```ruby
|
|
161
|
+
# For Propshaft (Rails 7+ default)
|
|
162
|
+
# Generates: app/assets/builds/.manifest.json
|
|
163
|
+
Railpack::Manifest::Propshaft.generate(config)
|
|
164
|
+
|
|
165
|
+
# For Sprockets (Rails < 7)
|
|
166
|
+
# Generates: app/assets/builds/.sprockets-manifest-*.json
|
|
167
|
+
Railpack::Manifest::Sprockets.generate(config)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The manifest generation is handled automatically after each build, but you can trigger it manually if needed.
|
|
171
|
+
|
|
114
172
|
## Supported Bundlers
|
|
115
173
|
|
|
116
174
|
### Bun (Default)
|
data/lib/railpack/manager.rb
CHANGED
|
@@ -132,107 +132,107 @@ module Railpack
|
|
|
132
132
|
|
|
133
133
|
private
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
def create_bundler
|
|
136
|
+
bundler_name = Railpack.config.bundler
|
|
137
|
+
bundler_class = BUNDLERS[bundler_name]
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
unless bundler_class
|
|
140
|
+
raise Error, "Unsupported bundler: #{bundler_name}. Available: #{BUNDLERS.keys.join(', ')}"
|
|
141
|
+
end
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
bundler_class.new(Railpack.config)
|
|
144
|
+
end
|
|
145
145
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
# Calculate human-readable bundle size with optional gzip compression
|
|
147
|
+
def calculate_bundle_size(config)
|
|
148
|
+
outdir = config['outdir']
|
|
149
|
+
return 'unknown' unless outdir && Dir.exist?(outdir)
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
total_size = 0
|
|
152
|
+
Dir.glob("#{outdir}/**/*.{js,css,map}").each do |file|
|
|
153
|
+
total_size += File.size(file) if File.file?(file)
|
|
154
|
+
end
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
# Include gzip size if analyze_bundle is enabled
|
|
157
|
+
if config['analyze_bundle']
|
|
158
|
+
gzip_size = calculate_gzip_size(outdir)
|
|
159
|
+
"#{human_size(total_size)} (#{human_size(gzip_size)} gzipped)"
|
|
160
|
+
else
|
|
161
|
+
human_size(total_size)
|
|
162
|
+
end
|
|
163
|
+
rescue => error
|
|
164
|
+
Railpack.logger.debug "Bundle size calculation failed: #{error.message}"
|
|
165
|
+
'unknown'
|
|
162
166
|
end
|
|
163
|
-
rescue => error
|
|
164
|
-
Railpack.logger.debug "Bundle size calculation failed: #{error.message}"
|
|
165
|
-
'unknown'
|
|
166
|
-
end
|
|
167
167
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
# Calculate total gzip-compressed size of assets
|
|
169
|
+
def calculate_gzip_size(outdir)
|
|
170
|
+
Dir.glob("#{outdir}/**/*.{js,css}").sum do |file|
|
|
171
|
+
next 0 unless File.file?(file)
|
|
172
|
+
Zlib::Deflate.deflate(File.read(file)).bytesize
|
|
173
|
+
end
|
|
174
|
+
rescue => error
|
|
175
|
+
Railpack.logger.debug "Gzip size calculation failed: #{error.message}"
|
|
176
|
+
0
|
|
173
177
|
end
|
|
174
|
-
rescue => error
|
|
175
|
-
Railpack.logger.debug "Gzip size calculation failed: #{error.message}"
|
|
176
|
-
0
|
|
177
|
-
end
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
179
|
+
# Convert bytes to human-readable format (B, KB, MB, GB)
|
|
180
|
+
def human_size(bytes)
|
|
181
|
+
units = %w[B KB MB GB]
|
|
182
|
+
size = bytes.to_f
|
|
183
|
+
units.each do |unit|
|
|
184
|
+
return "#{(size).round(2)} #{unit}" if size < 1024
|
|
185
|
+
size /= 1024
|
|
186
|
+
end
|
|
186
187
|
end
|
|
187
|
-
end
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
def generate_asset_manifest(config)
|
|
190
|
+
outdir = config['outdir']
|
|
191
|
+
return unless outdir && Dir.exist?(outdir)
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
193
|
+
# Detect asset pipeline type and delegate to appropriate manifest generator
|
|
194
|
+
pipeline_type = detect_asset_pipeline
|
|
195
|
+
manifest_class = Railpack::Manifest.const_get(pipeline_type.capitalize)
|
|
196
196
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
197
|
+
manifest_class.generate(config)
|
|
198
|
+
rescue => error
|
|
199
|
+
# Enhanced error logging with context
|
|
200
|
+
asset_files = Dir.glob("#{outdir}/**/*.{js,css}").length rescue 0
|
|
201
|
+
Railpack.logger.warn "⚠️ Failed to generate #{pipeline_type} asset manifest for #{outdir} (#{asset_files} assets): #{error.message}"
|
|
202
|
+
end
|
|
203
203
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
204
|
+
# Validate output directory exists and is writable before build
|
|
205
|
+
def validate_output_directory(config)
|
|
206
|
+
outdir = config['outdir']
|
|
207
|
+
return unless outdir
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
unless Dir.exist?(outdir)
|
|
210
|
+
Railpack.logger.warn "⚠️ Output directory #{outdir} does not exist - assets will be created on first build"
|
|
211
|
+
# Ensure directory exists to prevent early build failures
|
|
212
|
+
FileUtils.mkdir_p(outdir)
|
|
213
|
+
end
|
|
211
214
|
end
|
|
212
|
-
end
|
|
213
215
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
216
|
+
def detect_asset_pipeline
|
|
217
|
+
# Check Rails.application.config.assets class directly (more reliable)
|
|
218
|
+
if defined?(Rails) && Rails.respond_to?(:application) && Rails.application
|
|
219
|
+
assets_config = Rails.application.config.assets
|
|
220
|
+
if assets_config.is_a?(Propshaft::Assembler) || defined?(Propshaft::Assembler)
|
|
221
|
+
:propshaft
|
|
222
|
+
elsif defined?(Sprockets::Manifest)
|
|
223
|
+
:sprockets
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Fallback to version-based detection
|
|
228
|
+
if defined?(Rails) && Rails.version.to_f >= 7.0
|
|
219
229
|
:propshaft
|
|
220
|
-
elsif defined?(Sprockets
|
|
230
|
+
elsif defined?(Rails) && Rails.version.to_f < 7.0 && defined?(Sprockets)
|
|
221
231
|
:sprockets
|
|
232
|
+
else
|
|
233
|
+
# Safe default for modern Rails
|
|
234
|
+
:propshaft
|
|
222
235
|
end
|
|
223
236
|
end
|
|
224
|
-
|
|
225
|
-
# Fallback to version-based detection
|
|
226
|
-
if defined?(Rails) && Rails.version.to_f >= 7.0
|
|
227
|
-
:propshaft
|
|
228
|
-
elsif defined?(Rails) && Rails.version.to_f < 7.0 && defined?(Sprockets)
|
|
229
|
-
:sprockets
|
|
230
|
-
else
|
|
231
|
-
# Safe default for modern Rails
|
|
232
|
-
:propshaft
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
|
|
237
237
|
end
|
|
238
|
-
end
|
|
238
|
+
end
|
data/lib/railpack/version.rb
CHANGED