Class: Railpack::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/railpack/manager.rb

Overview

Rails asset pipeline manager for multi-bundler support.

This class provides a unified interface for building, watching, and managing assets with different bundlers (bun, esbuild, rollup, webpack). It handles:

  • Build lifecycle management with timing and logging
  • Asset manifest generation for Rails asset pipeline integration
  • Bundle size analysis and reporting
  • Error handling and recovery
  • Hook system for extensibility

The manager automatically detects the Rails asset pipeline type (Propshaft/Sprockets) and generates appropriate manifests for asset discovery.

Constant Summary collapse

BUNDLERS =
{
  'bun'     => BunBundler,
  'esbuild' => EsbuildBundler,
  'rollup'  => RollupBundler,
  'webpack' => WebpackBundler
}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize ⇒ Manager

Returns a new instance of Manager.



27
28
29
# File 'lib/railpack/manager.rb', line 27

def initialize
  @bundler = create_bundler
end

Class Method Details

.enhance_assets_precompile(*tasks, &block) ⇒ Object

Rails asset pipeline integration



125
126
127
128
129
# File 'lib/railpack/manager.rb', line 125

def self.enhance_assets_precompile(*tasks, &block)
  if defined?(Rake::Task) && Rake::Task.task_defined?("assets:precompile")
    Rake::Task["assets:precompile"].enhance(tasks, &block)
  end
end

Instance Method Details

#add(*packages) ⇒ Object



104
105
106
# File 'lib/railpack/manager.rb', line 104

def add(*packages)
  @bundler.add(*packages)
end

#build!(args = []) ⇒ Object

Build assets using the configured bundler.

This method orchestrates the complete build lifecycle:

  1. Triggers build_start hooks
  2. Validates output directory exists
  3. Executes bundler build command
  4. Calculates bundle size and timing
  5. Generates asset manifest for Rails
  6. Triggers build_complete hooks

Parameters:

  • args (Array) (defaults to: []) —

    Additional arguments to pass to the bundler

Returns:

  • (Object) —

    Result from the bundler build command

Raises:

  • (Error) —

    If build fails or configuration is invalid



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/railpack/manager.rb', line 44

def build!(args = [])
  start_time = Time.now
  config = Railpack.config.for_environment(Rails.env)
  Railpack.trigger_build_start(config)

  # Pre-build validation: warn if output directory issues
  validate_output_directory(config)

  begin
    Railpack.logger.info "🚀 Starting #{config['bundler']} build for #{Rails.env} environment"
    result = @bundler.build!(args)
    duration = ((Time.now - start_time) * 1000).round(2)

    # Calculate bundle size if output directory exists
    bundle_size = calculate_bundle_size(config)

    # Build result hash passed to build_complete hooks
    # Contains: success status, config used, build duration, and bundle size
    success_result = {
      success: true,
      config: config,
      duration: duration,
      bundle_size: bundle_size
    }

    Railpack.logger.info "✅ Build completed successfully in #{duration}ms (#{bundle_size})"

    # Generate asset manifest for Rails
    generate_asset_manifest(config)

    # Trigger build_complete hooks with success result
    Railpack.trigger_build_complete(success_result)
    result
  rescue => error
    duration = ((Time.now - start_time) * 1000).round(2)
    Railpack.logger.error "❌ Build failed after #{duration}ms: #{error.message}"

    # Error result hash passed to build_complete hooks
    # Contains: failure status, error object, config used, and build duration
    error_result = {
      success: false,
      error: error,
      config: config,
      duration: duration
    }

    Railpack.trigger_error(error)
    Railpack.trigger_build_complete(error_result)
    raise
  end
end

#exec(*args) ⇒ Object



112
113
114
# File 'lib/railpack/manager.rb', line 112

def exec(*args)
  @bundler.exec(*args)
end

#install!(args = []) ⇒ Object



100
101
102
# File 'lib/railpack/manager.rb', line 100

def install!(args = [])
  @bundler.install!(args)
end

#installed? ⇒ Boolean

Returns:

  • (Boolean)


120
121
122
# File 'lib/railpack/manager.rb', line 120

def installed?
  @bundler.installed?
end

#remove(*packages) ⇒ Object



108
109
110
# File 'lib/railpack/manager.rb', line 108

def remove(*packages)
  @bundler.remove(*packages)
end

#version ⇒ Object



116
117
118
# File 'lib/railpack/manager.rb', line 116

def version
  @bundler.version
end

#watch(args = []) ⇒ Object



96
97
98
# File 'lib/railpack/manager.rb', line 96

def watch(args = [])
  @bundler.watch(args)
end