shakapacker 9.3.0.beta.1 → 9.3.0.beta.4
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/.github/workflows/eslint-validation.yml +46 -0
- data/ESLINT_TECHNICAL_DEBT.md +159 -0
- data/Gemfile.lock +1 -1
- data/README.md +9 -6
- data/docs/common-upgrades.md +80 -0
- data/docs/configuration.md +101 -0
- data/docs/preventing_fouc.md +132 -0
- data/docs/troubleshooting.md +4 -0
- data/docs/v9_upgrade.md +90 -8
- data/eslint.config.js +119 -7
- data/lib/shakapacker/build_config_loader.rb +147 -0
- data/lib/shakapacker/configuration.rb +6 -2
- data/lib/shakapacker/dev_server_runner.rb +73 -0
- data/lib/shakapacker/runner.rb +263 -15
- data/lib/shakapacker/version.rb +1 -1
- data/package/configExporter/buildValidator.ts +2 -2
- data/package/configExporter/cli.ts +260 -173
- data/package/configExporter/configFile.ts +182 -46
- data/package/configExporter/fileWriter.ts +20 -13
- data/package/configExporter/types.ts +2 -0
- data/package/utils/pathValidation.ts +3 -3
- data/package-lock.json +2 -2
- data/package.json +1 -1
- data/test/configExporter/buildValidator.test.js +31 -28
- data/test/configExporter/configFile.test.js +3 -2
- data/test/configExporter/integration.test.js +14 -27
- data/test/package/configExporter.test.js +4 -8
- metadata +8 -4
- /data/bin/{export-bundler-config → shakapacker-config} +0 -0
- /data/lib/install/bin/{export-bundler-config → shakapacker-config} +0 -0
data/lib/shakapacker/runner.rb
CHANGED
|
@@ -2,6 +2,7 @@ require_relative "utils/misc"
|
|
|
2
2
|
require_relative "utils/manager"
|
|
3
3
|
require_relative "configuration"
|
|
4
4
|
require_relative "version"
|
|
5
|
+
require_relative "build_config_loader"
|
|
5
6
|
|
|
6
7
|
require "package_json"
|
|
7
8
|
require "pathname"
|
|
@@ -34,15 +35,109 @@ module Shakapacker
|
|
|
34
35
|
elsif argv.include?("--version") || argv.include?("-v")
|
|
35
36
|
print_version
|
|
36
37
|
exit(0)
|
|
38
|
+
elsif argv.include?("--init")
|
|
39
|
+
init_config_file
|
|
40
|
+
exit(0)
|
|
41
|
+
elsif argv.include?("--list-builds")
|
|
42
|
+
list_builds
|
|
43
|
+
exit(0)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Check for --bundler flag
|
|
47
|
+
bundler_override = nil
|
|
48
|
+
bundler_index = argv.index("--bundler")
|
|
49
|
+
if bundler_index
|
|
50
|
+
bundler_value = argv[bundler_index + 1]
|
|
51
|
+
unless bundler_value && %w[webpack rspack].include?(bundler_value)
|
|
52
|
+
$stderr.puts "[Shakapacker] Error: --bundler requires 'webpack' or 'rspack'"
|
|
53
|
+
$stderr.puts "Usage: bin/shakapacker --bundler <webpack|rspack>"
|
|
54
|
+
exit(1)
|
|
55
|
+
end
|
|
56
|
+
bundler_override = bundler_value
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Check for --build flag
|
|
60
|
+
build_index = argv.index("--build")
|
|
61
|
+
if build_index
|
|
62
|
+
build_name = argv[build_index + 1]
|
|
63
|
+
|
|
64
|
+
unless build_name
|
|
65
|
+
$stderr.puts "[Shakapacker] Error: --build requires a build name"
|
|
66
|
+
$stderr.puts "Usage: bin/shakapacker --build <name>"
|
|
67
|
+
exit(1)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
loader = BuildConfigLoader.new
|
|
71
|
+
|
|
72
|
+
unless loader.exists?
|
|
73
|
+
$stderr.puts "[Shakapacker] Config file not found: #{loader.config_file_path}"
|
|
74
|
+
$stderr.puts "Run 'bin/shakapacker --init' to create one"
|
|
75
|
+
exit(1)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
begin
|
|
79
|
+
# Pass bundler override to resolve_build_config
|
|
80
|
+
resolve_opts = {}
|
|
81
|
+
resolve_opts[:default_bundler] = bundler_override if bundler_override
|
|
82
|
+
build_config = loader.resolve_build_config(build_name, **resolve_opts)
|
|
83
|
+
|
|
84
|
+
# Remove --build and build name from argv
|
|
85
|
+
remaining_argv = argv.dup
|
|
86
|
+
remaining_argv.delete_at(build_index + 1)
|
|
87
|
+
remaining_argv.delete_at(build_index)
|
|
88
|
+
|
|
89
|
+
# Remove --bundler and bundler value from argv if present
|
|
90
|
+
if bundler_index
|
|
91
|
+
bundler_idx_in_remaining = remaining_argv.index("--bundler")
|
|
92
|
+
if bundler_idx_in_remaining
|
|
93
|
+
remaining_argv.delete_at(bundler_idx_in_remaining + 1)
|
|
94
|
+
remaining_argv.delete_at(bundler_idx_in_remaining)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# If this build uses dev server, delegate to DevServerRunner
|
|
99
|
+
if loader.uses_dev_server?(build_config)
|
|
100
|
+
$stdout.puts "[Shakapacker] Build '#{build_name}' requires dev server"
|
|
101
|
+
$stdout.puts "[Shakapacker] Running: bin/shakapacker-dev-server --build #{build_name}"
|
|
102
|
+
$stdout.puts ""
|
|
103
|
+
require_relative "dev_server_runner"
|
|
104
|
+
DevServerRunner.run_with_build_config(remaining_argv, build_config)
|
|
105
|
+
return
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Otherwise run with this build config
|
|
109
|
+
run_with_build_config(remaining_argv, build_config)
|
|
110
|
+
return
|
|
111
|
+
rescue ArgumentError => e
|
|
112
|
+
$stderr.puts "[Shakapacker] #{e.message}"
|
|
113
|
+
exit(1)
|
|
114
|
+
end
|
|
37
115
|
end
|
|
38
116
|
|
|
39
117
|
Shakapacker.ensure_node_env!
|
|
40
118
|
|
|
119
|
+
# Remove --bundler flag from argv if present (not using --build)
|
|
120
|
+
remaining_argv = argv.dup
|
|
121
|
+
if bundler_index
|
|
122
|
+
bundler_idx = remaining_argv.index("--bundler")
|
|
123
|
+
if bundler_idx
|
|
124
|
+
remaining_argv.delete_at(bundler_idx + 1)
|
|
125
|
+
remaining_argv.delete_at(bundler_idx)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Set SHAKAPACKER_ASSETS_BUNDLER if bundler override is specified
|
|
130
|
+
# This ensures JS/TS config files use the correct bundler
|
|
131
|
+
ENV["SHAKAPACKER_ASSETS_BUNDLER"] = bundler_override if bundler_override
|
|
132
|
+
|
|
41
133
|
# Create a single runner instance to avoid loading configuration twice.
|
|
42
134
|
# We extend it with the appropriate build command based on the bundler type.
|
|
43
|
-
runner = new(
|
|
135
|
+
runner = new(remaining_argv, nil, bundler_override)
|
|
136
|
+
|
|
137
|
+
# Determine which bundler to use (override takes precedence)
|
|
138
|
+
use_rspack = bundler_override ? (bundler_override == "rspack") : runner.config.rspack?
|
|
44
139
|
|
|
45
|
-
if
|
|
140
|
+
if use_rspack
|
|
46
141
|
require_relative "rspack_runner"
|
|
47
142
|
# Extend the runner instance with rspack-specific methods
|
|
48
143
|
# This avoids creating a new RspackRunner which would reload the configuration
|
|
@@ -69,17 +164,71 @@ module Shakapacker
|
|
|
69
164
|
end
|
|
70
165
|
end
|
|
71
166
|
|
|
72
|
-
def
|
|
167
|
+
def self.run_with_build_config(argv, build_config)
|
|
168
|
+
$stdout.sync = true
|
|
169
|
+
Shakapacker.ensure_node_env!
|
|
170
|
+
|
|
171
|
+
# Apply build config environment variables
|
|
172
|
+
build_config[:environment].each do |key, value|
|
|
173
|
+
ENV[key] = value.to_s
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Set SHAKAPACKER_ASSETS_BUNDLER so JS/TS config files use the correct bundler
|
|
177
|
+
# This ensures the bundler override (from --bundler or build config) is respected
|
|
178
|
+
ENV["SHAKAPACKER_ASSETS_BUNDLER"] = build_config[:bundler]
|
|
179
|
+
|
|
180
|
+
puts "[Shakapacker] Running build: #{build_config[:name]}"
|
|
181
|
+
puts "[Shakapacker] Description: #{build_config[:description]}" if build_config[:description]
|
|
182
|
+
puts "[Shakapacker] Bundler: #{build_config[:bundler]}"
|
|
183
|
+
puts "[Shakapacker] Config file: #{build_config[:config_file]}" if build_config[:config_file]
|
|
184
|
+
|
|
185
|
+
# Create runner with modified argv and bundler from build_config
|
|
186
|
+
# The build_config[:bundler] already has any CLI --bundler override applied
|
|
187
|
+
runner = new(argv, build_config, build_config[:bundler])
|
|
188
|
+
|
|
189
|
+
# Use bundler from build_config (which includes CLI override)
|
|
190
|
+
if build_config[:bundler] == "rspack"
|
|
191
|
+
require_relative "rspack_runner"
|
|
192
|
+
runner.extend(Module.new do
|
|
193
|
+
def build_cmd
|
|
194
|
+
package_json.manager.native_exec_command("rspack")
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def assets_bundler_commands
|
|
198
|
+
BASE_COMMANDS + %w[build watch]
|
|
199
|
+
end
|
|
200
|
+
end)
|
|
201
|
+
runner.run
|
|
202
|
+
else
|
|
203
|
+
require_relative "webpack_runner"
|
|
204
|
+
runner.extend(Module.new do
|
|
205
|
+
def build_cmd
|
|
206
|
+
package_json.manager.native_exec_command("webpack")
|
|
207
|
+
end
|
|
208
|
+
end)
|
|
209
|
+
runner.run
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def initialize(argv, build_config = nil, bundler_override = nil)
|
|
73
214
|
@argv = argv
|
|
215
|
+
@build_config = build_config
|
|
216
|
+
@bundler_override = bundler_override
|
|
217
|
+
|
|
218
|
+
@app_path = File.expand_path(".", Dir.pwd)
|
|
219
|
+
@shakapacker_config = ENV["SHAKAPACKER_CONFIG"] || File.join(@app_path, "config/shakapacker.yml")
|
|
74
220
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@config = Configuration.new(
|
|
221
|
+
# Create config with bundler override if provided
|
|
222
|
+
config_opts = {
|
|
78
223
|
root_path: Pathname.new(@app_path),
|
|
79
224
|
config_path: Pathname.new(@shakapacker_config),
|
|
80
225
|
env: ENV["RAILS_ENV"] || ENV["NODE_ENV"] || "development"
|
|
81
|
-
|
|
82
|
-
|
|
226
|
+
}
|
|
227
|
+
config_opts[:bundler_override] = bundler_override if bundler_override
|
|
228
|
+
|
|
229
|
+
@config = Configuration.new(**config_opts)
|
|
230
|
+
|
|
231
|
+
@webpack_config = find_webpack_config_from_build_or_default
|
|
83
232
|
|
|
84
233
|
Shakapacker::Utils::Manager.error_unless_package_manager_is_obvious!
|
|
85
234
|
end
|
|
@@ -175,13 +324,26 @@ module Shakapacker
|
|
|
175
324
|
--debug-shakapacker Enable Node.js debugging (--inspect-brk)
|
|
176
325
|
--trace-deprecation Show stack traces for deprecations
|
|
177
326
|
--no-deprecation Silence deprecation warnings
|
|
327
|
+
--bundler <webpack|rspack>
|
|
328
|
+
Override bundler (defaults to shakapacker.yml)
|
|
178
329
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
330
|
+
Build configurations (config/shakapacker-builds.yml):
|
|
331
|
+
--init Create config/shakapacker-builds.yml
|
|
332
|
+
--list-builds List available builds
|
|
333
|
+
--build <name> Run a specific build configuration
|
|
334
|
+
|
|
335
|
+
Examples (build configs):
|
|
336
|
+
bin/shakapacker --init # Create config file
|
|
337
|
+
bin/shakapacker --list-builds # Show available builds
|
|
338
|
+
bin/shakapacker --build dev-hmr # Run the 'dev-hmr' build
|
|
339
|
+
bin/shakapacker --build prod # Run the 'prod' build
|
|
340
|
+
bin/shakapacker --build prod --bundler rspack # Override to use rspack
|
|
341
|
+
|
|
342
|
+
Note: If a build has dev_server: true in its config, it will
|
|
343
|
+
automatically use bin/shakapacker-dev-server instead.
|
|
344
|
+
|
|
345
|
+
Advanced: Use bin/shakapacker-config for more config management options
|
|
346
|
+
(validate builds, export configs, etc.)
|
|
185
347
|
|
|
186
348
|
HELP
|
|
187
349
|
|
|
@@ -189,6 +351,14 @@ module Shakapacker
|
|
|
189
351
|
|
|
190
352
|
puts <<~HELP
|
|
191
353
|
|
|
354
|
+
Examples (passing options to webpack/rspack):
|
|
355
|
+
bin/shakapacker # Build for production
|
|
356
|
+
bin/shakapacker --bundler rspack # Build with rspack instead of webpack
|
|
357
|
+
bin/shakapacker --mode development # Build for development
|
|
358
|
+
bin/shakapacker --watch # Watch mode
|
|
359
|
+
bin/shakapacker --mode development --analyze # Development build with analysis
|
|
360
|
+
bin/shakapacker --debug-shakapacker # Debug with Node inspector
|
|
361
|
+
|
|
192
362
|
Options managed by Shakapacker (configured via config files):
|
|
193
363
|
--config Set automatically based on assets_bundler_config_path
|
|
194
364
|
(defaults to config/webpack or config/rspack)
|
|
@@ -301,6 +471,52 @@ module Shakapacker
|
|
|
301
471
|
end
|
|
302
472
|
end
|
|
303
473
|
|
|
474
|
+
def self.init_config_file
|
|
475
|
+
loader = BuildConfigLoader.new
|
|
476
|
+
config_path = loader.config_file_path
|
|
477
|
+
|
|
478
|
+
if loader.exists?
|
|
479
|
+
puts "[Shakapacker] Config file already exists: #{config_path}"
|
|
480
|
+
puts "Use --list-builds to see available builds"
|
|
481
|
+
return
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
# Delegate to bin/shakapacker-config
|
|
485
|
+
app_path = File.expand_path(".", Dir.pwd)
|
|
486
|
+
shakapacker_config_path = File.join(app_path, "bin", "shakapacker-config")
|
|
487
|
+
|
|
488
|
+
unless File.exist?(shakapacker_config_path)
|
|
489
|
+
$stderr.puts "[Shakapacker] Error: bin/shakapacker-config not found"
|
|
490
|
+
$stderr.puts "Please ensure Shakapacker is properly installed"
|
|
491
|
+
exit(1)
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
# Run the init command and check if it succeeded
|
|
495
|
+
unless system(shakapacker_config_path, "--init")
|
|
496
|
+
exit_code = $?.exitstatus || 1
|
|
497
|
+
$stderr.puts "[Shakapacker] Error: Failed to run: #{shakapacker_config_path} --init"
|
|
498
|
+
$stderr.puts "[Shakapacker] Command exited with status: #{exit_code}"
|
|
499
|
+
exit(exit_code)
|
|
500
|
+
end
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
def self.list_builds
|
|
504
|
+
loader = BuildConfigLoader.new
|
|
505
|
+
|
|
506
|
+
unless loader.exists?
|
|
507
|
+
puts "[Shakapacker] No config file found: #{loader.config_file_path}"
|
|
508
|
+
puts "Run 'bin/shakapacker --init' to create one"
|
|
509
|
+
return
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
begin
|
|
513
|
+
loader.list_builds
|
|
514
|
+
rescue ArgumentError => e
|
|
515
|
+
$stderr.puts "[Shakapacker] Error: #{e.message}"
|
|
516
|
+
exit(1)
|
|
517
|
+
end
|
|
518
|
+
end
|
|
519
|
+
|
|
304
520
|
def self.get_bundler_version
|
|
305
521
|
execute_bundler_command("--version") { |stdout| stdout.strip }
|
|
306
522
|
end
|
|
@@ -356,6 +572,15 @@ module Shakapacker
|
|
|
356
572
|
end
|
|
357
573
|
|
|
358
574
|
private
|
|
575
|
+
|
|
576
|
+
def find_webpack_config_from_build_or_default
|
|
577
|
+
if @build_config && @build_config[:config_file]
|
|
578
|
+
File.join(@app_path, @build_config[:config_file])
|
|
579
|
+
else
|
|
580
|
+
find_assets_bundler_config
|
|
581
|
+
end
|
|
582
|
+
end
|
|
583
|
+
|
|
359
584
|
def find_assets_bundler_config
|
|
360
585
|
if @config.rspack?
|
|
361
586
|
find_rspack_config_with_fallback
|
|
@@ -379,7 +604,7 @@ module Shakapacker
|
|
|
379
604
|
return rspack_path
|
|
380
605
|
end
|
|
381
606
|
|
|
382
|
-
# Fallback to webpack config
|
|
607
|
+
# Fallback to webpack config in the configured directory
|
|
383
608
|
webpack_paths = %w[ts js].map do |ext|
|
|
384
609
|
File.join(@app_path, config_dir, "webpack.config.#{ext}")
|
|
385
610
|
end
|
|
@@ -393,6 +618,29 @@ module Shakapacker
|
|
|
393
618
|
return webpack_path
|
|
394
619
|
end
|
|
395
620
|
|
|
621
|
+
# Backward compatibility: Check config/webpack/ if we were looking in config/rspack/
|
|
622
|
+
# This supports upgrades from versions where rspack used config/webpack/
|
|
623
|
+
if config_dir == "config/rspack"
|
|
624
|
+
webpack_dir_paths = %w[ts js].map do |ext|
|
|
625
|
+
File.join(@app_path, "config/webpack", "webpack.config.#{ext}")
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
puts "[Shakapacker] Checking config/webpack/ for backward compatibility..."
|
|
629
|
+
webpack_dir_path = webpack_dir_paths.find { |f| File.exist?(f) }
|
|
630
|
+
if webpack_dir_path
|
|
631
|
+
$stderr.puts "⚠️ DEPRECATION WARNING: Found webpack config in config/webpack/ but assets_bundler is set to 'rspack'."
|
|
632
|
+
$stderr.puts " For rspack, configs should be in config/rspack/ directory."
|
|
633
|
+
$stderr.puts " "
|
|
634
|
+
$stderr.puts " To fix this, either:"
|
|
635
|
+
$stderr.puts " 1. Move your config: mv config/webpack config/rspack"
|
|
636
|
+
$stderr.puts " 2. Set assets_bundler_config_path in config/shakapacker.yml:"
|
|
637
|
+
$stderr.puts " assets_bundler_config_path: config/webpack"
|
|
638
|
+
$stderr.puts " "
|
|
639
|
+
$stderr.puts " Using: #{webpack_dir_path}"
|
|
640
|
+
return webpack_dir_path
|
|
641
|
+
end
|
|
642
|
+
end
|
|
643
|
+
|
|
396
644
|
# No config found
|
|
397
645
|
print_config_not_found_error("rspack", rspack_paths.last, config_dir)
|
|
398
646
|
exit(1)
|
data/lib/shakapacker/version.rb
CHANGED
|
@@ -865,13 +865,13 @@ export class BuildValidator {
|
|
|
865
865
|
const failedBuilds = results.filter((r) => !r.success)
|
|
866
866
|
failedBuilds.forEach((result) => {
|
|
867
867
|
lines.push(
|
|
868
|
-
` bin/
|
|
868
|
+
` bin/shakapacker-config --validate-build ${result.buildName} --verbose`
|
|
869
869
|
)
|
|
870
870
|
})
|
|
871
871
|
|
|
872
872
|
lines.push("")
|
|
873
873
|
lines.push(
|
|
874
|
-
" Or validate all builds with full output: bin/
|
|
874
|
+
" Or validate all builds with full output: bin/shakapacker-config --validate --verbose"
|
|
875
875
|
)
|
|
876
876
|
lines.push("=".repeat(80))
|
|
877
877
|
}
|