Class: Shakapacker::BundlerSwitcher

Inherits:
Object
  • Object
show all
Defined in:
lib/shakapacker/bundler_switcher.rb

Overview

Provides functionality to switch between webpack and rspack bundlers

Constant Summary collapse

SHAKAPACKER_CONFIG =
"config/shakapacker.yml"
CUSTOM_DEPS_CONFIG =
".shakapacker-switch-bundler-dependencies.yml"
DEFAULT_RSPACK_DEPS =

Default dependencies for each bundler (package names only, no versions)

{
  dev: %w[@rspack/cli @rspack/plugin-react-refresh],
  prod: %w[@rspack/core rspack-manifest-plugin]
}.freeze
DEFAULT_WEBPACK_DEPS =
{
  dev: %w[webpack webpack-cli webpack-dev-server @pmmmwh/react-refresh-webpack-plugin @swc/core swc-loader],
  prod: %w[webpack-assets-manifest webpack-merge]
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root_path = nil) ⇒ BundlerSwitcher

Returns a new instance of BundlerSwitcher.



25
26
27
# File 'lib/shakapacker/bundler_switcher.rb', line 25

def initialize(root_path = nil)
  @root_path = root_path || (defined?(Rails) ? Rails.root : Pathname.new(Dir.pwd))
end

Instance Attribute Details

#root_pathObject (readonly)

Returns the value of attribute root_path.



23
24
25
# File 'lib/shakapacker/bundler_switcher.rb', line 23

def root_path
  @root_path
end

Instance Method Details

#current_bundlerObject



29
30
31
32
# File 'lib/shakapacker/bundler_switcher.rb', line 29

def current_bundler
  config = load_yaml_config(config_path)
  config.dig("default", "assets_bundler") || "webpack"
end

#init_configObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/shakapacker/bundler_switcher.rb', line 69

def init_config
  if File.exist?(custom_config_path)
    puts "⚠️  #{CUSTOM_DEPS_CONFIG} already exists"
    return
  end

  config = {
    "rspack" => {
      "devDependencies" => DEFAULT_RSPACK_DEPS[:dev],
      "dependencies" => DEFAULT_RSPACK_DEPS[:prod]
    },
    "webpack" => {
      "devDependencies" => DEFAULT_WEBPACK_DEPS[:dev],
      "dependencies" => DEFAULT_WEBPACK_DEPS[:prod]
    }
  }

  File.write(custom_config_path, YAML.dump(config))
  puts "✅ Created #{CUSTOM_DEPS_CONFIG}"
  puts ""
  puts "You can now customize the dependencies for each bundler in this file."
  puts "The script will automatically use these custom dependencies when switching bundlers."
end

#show_usageObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/shakapacker/bundler_switcher.rb', line 93

def show_usage
  current = current_bundler
  puts "Current bundler: #{current}"
  puts ""
  puts "Usage:"
  puts "  rails shakapacker:switch_bundler [webpack|rspack] [OPTIONS]"
  puts "  rake shakapacker:switch_bundler [webpack|rspack] -- [OPTIONS]"
  puts ""
  puts "Options:"
  puts "  --install-deps    Automatically install/uninstall dependencies"
  puts "  --no-uninstall    Skip uninstalling old bundler packages (faster, keeps both bundlers)"
  puts "  --init-config     Create #{CUSTOM_DEPS_CONFIG} with default dependencies"
  puts "  --help, -h        Show this help message"
  puts ""
  puts "Examples:"
  puts "  # Using rails command"
  puts "  rails shakapacker:switch_bundler rspack --install-deps"
  puts "  rails shakapacker:switch_bundler webpack --install-deps --no-uninstall"
  puts "  rails shakapacker:switch_bundler --init-config"
  puts ""
  puts "  # Using rake command (note the -- separator)"
  puts "  rake shakapacker:switch_bundler rspack -- --install-deps"
  puts "  rake shakapacker:switch_bundler webpack -- --install-deps --no-uninstall"
  puts "  rake shakapacker:switch_bundler -- --init-config"
end

#switch_to(bundler, install_deps: false, no_uninstall: false) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/shakapacker/bundler_switcher.rb', line 34

def switch_to(bundler, install_deps: false, no_uninstall: false)
  unless %w[webpack rspack].include?(bundler)
    raise ArgumentError, "Invalid bundler: #{bundler}. Must be 'webpack' or 'rspack'"
  end

  current = current_bundler
  if current == bundler && !install_deps
    puts "✅ Already using #{bundler}"
    return
  end

  if current == bundler && install_deps
    puts "✅ Already using #{bundler} - reinstalling dependencies as requested"
    manage_dependencies(bundler, install_deps, switching: false, no_uninstall: no_uninstall)
    return
  end

  update_config(bundler)

  puts "✅ Switched from #{current} to #{bundler}"
  puts ""
  puts "📝 Configuration updated in #{SHAKAPACKER_CONFIG}"

  manage_dependencies(bundler, install_deps, no_uninstall: no_uninstall)

  puts ""
  puts "🎯 Next steps:"
  puts "   1. Restart your dev server: bin/dev"
  puts "   2. Verify build works: bin/shakapacker"
  puts ""
  puts "💡 Tip: Both webpack and rspack can coexist in package.json during migration"
  puts "        Use --install-deps to automatically manage dependencies, or manage manually"
  puts "        Use --no-uninstall to skip removing old bundler packages (faster switching)"
end