shakapacker 9.3.0.beta.5 → 9.3.0.beta.7
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 +34 -3
- data/ESLINT_TECHNICAL_DEBT.md +8 -2
- data/Gemfile.lock +1 -1
- data/docs/early_hints.md +7 -21
- data/docs/{early_hints_new_api.md → early_hints_manual_api.md} +53 -299
- data/lib/shakapacker/doctor.rb +125 -68
- data/lib/shakapacker/runner.rb +12 -8
- data/lib/shakapacker/swc_migrator.rb +7 -7
- data/lib/shakapacker/version.rb +1 -1
- data/package/configExporter/cli.ts +256 -82
- data/package/configExporter/fileWriter.ts +18 -9
- data/package/configExporter/types.ts +6 -1
- data/package/configExporter/yamlSerializer.ts +36 -0
- data/package/plugins/webpack.ts +2 -1
- data/package/utils/errorCodes.ts +1 -0
- data/package/utils/errorHelpers.ts +16 -12
- data/package.json +2 -2
- data/test/configExporter/integration.test.js +8 -8
- data/test/package/configExporter.test.js +48 -3
- metadata +3 -4
- data/package-lock.json +0 -13047
data/lib/shakapacker/doctor.rb
CHANGED
|
@@ -879,49 +879,81 @@ module Shakapacker
|
|
|
879
879
|
|
|
880
880
|
def print_verbose_checks
|
|
881
881
|
puts "\nVerbose diagnostics:"
|
|
882
|
+
print_environment_info
|
|
883
|
+
print_version_info
|
|
884
|
+
print_path_info
|
|
885
|
+
print_config_values
|
|
886
|
+
end
|
|
882
887
|
|
|
883
|
-
|
|
888
|
+
def print_environment_info
|
|
884
889
|
rails_env = defined?(Rails) ? Rails.env : ENV["RAILS_ENV"]
|
|
885
890
|
node_env = ENV["NODE_ENV"]
|
|
886
891
|
puts " • Rails environment: #{rails_env || 'not set'}"
|
|
887
892
|
puts " • Node environment: #{node_env || 'not set'}"
|
|
893
|
+
end
|
|
888
894
|
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
package_json = doctor.send(:read_package_json)
|
|
892
|
-
npm_version = package_json.dig("dependencies", "shakapacker") ||
|
|
893
|
-
package_json.dig("devDependencies", "shakapacker")
|
|
894
|
-
puts " • Shakapacker gem version: #{Shakapacker::VERSION}"
|
|
895
|
-
puts " • Shakapacker npm version: #{npm_version || 'not installed'}"
|
|
896
|
-
end
|
|
895
|
+
def print_version_info
|
|
896
|
+
return unless doctor.send(:package_json_exists?)
|
|
897
897
|
|
|
898
|
-
|
|
898
|
+
package_json = doctor.send(:read_package_json)
|
|
899
|
+
npm_version = package_json.dig("dependencies", "shakapacker") ||
|
|
900
|
+
package_json.dig("devDependencies", "shakapacker")
|
|
901
|
+
puts " • Shakapacker gem version: #{Shakapacker::VERSION}"
|
|
902
|
+
puts " • Shakapacker npm version: #{npm_version || 'not installed'}"
|
|
903
|
+
end
|
|
904
|
+
|
|
905
|
+
def print_path_info
|
|
899
906
|
puts " • Root path: #{doctor.root_path}"
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
907
|
+
return unless doctor.config.config_path.exist?
|
|
908
|
+
|
|
909
|
+
puts " • Cache path: #{doctor.config.cache_path}"
|
|
910
|
+
puts " • Manifest path: #{doctor.config.manifest_path}"
|
|
911
|
+
end
|
|
912
|
+
|
|
913
|
+
def print_config_values
|
|
914
|
+
return unless doctor.config.config_path.exist?
|
|
915
|
+
|
|
916
|
+
puts "\nConfiguration values for '#{doctor.config.env}' environment:"
|
|
917
|
+
config_data = doctor.config.send(:data)
|
|
918
|
+
|
|
919
|
+
if config_data.any?
|
|
920
|
+
print_config_data(config_data)
|
|
921
|
+
else
|
|
922
|
+
puts " (using bundled defaults - no environment-specific config found)"
|
|
903
923
|
end
|
|
924
|
+
end
|
|
904
925
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
926
|
+
def print_config_data(config_data)
|
|
927
|
+
config_data.each do |key, value|
|
|
928
|
+
formatted_value = format_config_value(value)
|
|
929
|
+
puts " • #{key}: #{formatted_value}"
|
|
930
|
+
end
|
|
931
|
+
end
|
|
932
|
+
|
|
933
|
+
def format_config_value(value)
|
|
934
|
+
case value
|
|
935
|
+
when Array
|
|
936
|
+
format_array_value(value)
|
|
937
|
+
when Hash
|
|
938
|
+
format_hash_value(value)
|
|
939
|
+
else
|
|
940
|
+
value.inspect
|
|
941
|
+
end
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
def format_array_value(array)
|
|
945
|
+
if array.length > 3
|
|
946
|
+
"#{array.first(3).inspect}... (#{array.length} items)"
|
|
947
|
+
else
|
|
948
|
+
array.inspect
|
|
949
|
+
end
|
|
950
|
+
end
|
|
951
|
+
|
|
952
|
+
def format_hash_value(hash)
|
|
953
|
+
if hash.length > 3
|
|
954
|
+
"{...} (#{hash.length} keys)"
|
|
955
|
+
else
|
|
956
|
+
hash.inspect
|
|
925
957
|
end
|
|
926
958
|
end
|
|
927
959
|
|
|
@@ -1033,49 +1065,61 @@ module Shakapacker
|
|
|
1033
1065
|
|
|
1034
1066
|
item_number = 0
|
|
1035
1067
|
doctor.warnings.each do |warning|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
when :info then "[INFO]"
|
|
1039
|
-
when :recommended then "[RECOMMENDED]"
|
|
1040
|
-
else ""
|
|
1041
|
-
end
|
|
1042
|
-
|
|
1043
|
-
# Sub-items start with whitespace (indented fix instructions)
|
|
1044
|
-
is_subitem = warning[:message].start_with?(" ")
|
|
1045
|
-
|
|
1046
|
-
if is_subitem
|
|
1047
|
-
# Fix instructions align at column 16 (length of "N. [RECOMMENDED] ")
|
|
1048
|
-
# This ensures all Fix lines align vertically regardless of category
|
|
1049
|
-
subitem_prefix = " " * 15
|
|
1050
|
-
wrapped = wrap_text(warning[:message], 100, subitem_prefix)
|
|
1051
|
-
puts wrapped
|
|
1068
|
+
if subitem?(warning[:message])
|
|
1069
|
+
print_subitem(warning[:message])
|
|
1052
1070
|
else
|
|
1053
1071
|
item_number += 1
|
|
1054
|
-
|
|
1055
|
-
prefix = "#{item_number}. #{category_prefix} "
|
|
1056
|
-
wrapped = wrap_text(warning[:message], 100, prefix)
|
|
1057
|
-
puts wrapped
|
|
1072
|
+
print_main_item(item_number, warning)
|
|
1058
1073
|
end
|
|
1059
1074
|
end
|
|
1060
1075
|
puts ""
|
|
1061
1076
|
end
|
|
1062
1077
|
|
|
1078
|
+
def subitem?(message)
|
|
1079
|
+
message.start_with?(" ")
|
|
1080
|
+
end
|
|
1081
|
+
|
|
1082
|
+
def print_subitem(message)
|
|
1083
|
+
# Fix instructions align at column 16 (length of "N. [RECOMMENDED] ")
|
|
1084
|
+
# This ensures all Fix lines align vertically regardless of category
|
|
1085
|
+
subitem_prefix = " " * 15
|
|
1086
|
+
wrapped = wrap_text(message, 100, subitem_prefix)
|
|
1087
|
+
puts wrapped
|
|
1088
|
+
end
|
|
1089
|
+
|
|
1090
|
+
def print_main_item(item_number, warning)
|
|
1091
|
+
category_prefix = case warning[:category]
|
|
1092
|
+
when :action_required then "[REQUIRED]"
|
|
1093
|
+
when :info then "[INFO]"
|
|
1094
|
+
when :recommended then "[RECOMMENDED]"
|
|
1095
|
+
else
|
|
1096
|
+
""
|
|
1097
|
+
end
|
|
1098
|
+
|
|
1099
|
+
# Format: N. [CATEGORY] Message
|
|
1100
|
+
prefix = "#{item_number}. #{category_prefix} "
|
|
1101
|
+
wrapped = wrap_text(warning[:message], 100, prefix)
|
|
1102
|
+
puts wrapped
|
|
1103
|
+
end
|
|
1104
|
+
|
|
1063
1105
|
def wrap_text(text, max_width, prefix)
|
|
1064
|
-
# Strip leading whitespace from sub-items
|
|
1065
1106
|
text = text.strip
|
|
1066
|
-
|
|
1067
|
-
# Calculate available width for text
|
|
1068
1107
|
available_width = max_width - prefix.length
|
|
1108
|
+
|
|
1069
1109
|
return prefix + text if text.length <= available_width
|
|
1070
1110
|
|
|
1071
|
-
|
|
1111
|
+
lines = build_wrapped_lines(text, available_width)
|
|
1112
|
+
format_wrapped_output(lines, prefix)
|
|
1113
|
+
end
|
|
1114
|
+
|
|
1115
|
+
def build_wrapped_lines(text, available_width)
|
|
1072
1116
|
words = text.split(" ")
|
|
1073
1117
|
lines = []
|
|
1074
1118
|
current_line = []
|
|
1075
1119
|
current_length = 0
|
|
1076
1120
|
|
|
1077
1121
|
words.each do |word|
|
|
1078
|
-
word_length = word.length + (current_line.empty? ? 0 : 1)
|
|
1122
|
+
word_length = word.length + (current_line.empty? ? 0 : 1)
|
|
1079
1123
|
|
|
1080
1124
|
if current_length + word_length <= available_width
|
|
1081
1125
|
current_line << word
|
|
@@ -1086,26 +1130,39 @@ module Shakapacker
|
|
|
1086
1130
|
current_length = word.length
|
|
1087
1131
|
end
|
|
1088
1132
|
end
|
|
1133
|
+
|
|
1089
1134
|
lines << current_line.join(" ") unless current_line.empty?
|
|
1135
|
+
lines
|
|
1136
|
+
end
|
|
1090
1137
|
|
|
1091
|
-
|
|
1138
|
+
def format_wrapped_output(lines, prefix)
|
|
1092
1139
|
result = prefix + lines[0]
|
|
1140
|
+
indent = " " * prefix.length
|
|
1141
|
+
|
|
1093
1142
|
lines[1..].each do |line|
|
|
1094
|
-
result += "\n"
|
|
1143
|
+
result += "\n#{indent}#{line}"
|
|
1095
1144
|
end
|
|
1145
|
+
|
|
1096
1146
|
result
|
|
1097
1147
|
end
|
|
1098
1148
|
|
|
1099
1149
|
def has_dependency_issues?
|
|
1100
|
-
# Check if any issues or warnings are about missing npm/package dependencies
|
|
1101
|
-
# Exclude optional dependencies - only show install instructions for required dependencies
|
|
1102
1150
|
all_messages = doctor.issues + doctor.warnings.map { |w| w[:message] }
|
|
1103
|
-
all_messages.any?
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1151
|
+
all_messages.any? { |msg| dependency_issue?(msg) }
|
|
1152
|
+
end
|
|
1153
|
+
|
|
1154
|
+
def dependency_issue?(message)
|
|
1155
|
+
return false if message.include?("Optional")
|
|
1156
|
+
|
|
1157
|
+
missing_dependency?(message) || not_installed?(message)
|
|
1158
|
+
end
|
|
1159
|
+
|
|
1160
|
+
def missing_dependency?(message)
|
|
1161
|
+
message.include?("Missing") && message.include?("dependency")
|
|
1162
|
+
end
|
|
1163
|
+
|
|
1164
|
+
def not_installed?(message)
|
|
1165
|
+
message.include?("not installed") || message.include?("is not installed")
|
|
1109
1166
|
end
|
|
1110
1167
|
|
|
1111
1168
|
def print_fix_instructions
|
data/lib/shakapacker/runner.rb
CHANGED
|
@@ -29,8 +29,10 @@ module Shakapacker
|
|
|
29
29
|
$stdout.sync = true
|
|
30
30
|
|
|
31
31
|
# Show Shakapacker help and exit (don't call bundler)
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
# Support --help, -h, and --help=verbose formats
|
|
33
|
+
help_verbose = argv.any? { |arg| arg == "--help=verbose" }
|
|
34
|
+
if argv.include?("--help") || argv.include?("-h") || help_verbose
|
|
35
|
+
print_help(verbose: help_verbose)
|
|
34
36
|
exit(0)
|
|
35
37
|
elsif argv.include?("--version") || argv.include?("-v")
|
|
36
38
|
print_version
|
|
@@ -310,7 +312,7 @@ module Shakapacker
|
|
|
310
312
|
$stderr.puts "Current configured path: #{config_dir}"
|
|
311
313
|
end
|
|
312
314
|
|
|
313
|
-
def self.print_help
|
|
315
|
+
def self.print_help(verbose: false)
|
|
314
316
|
puts <<~HELP
|
|
315
317
|
================================================================================
|
|
316
318
|
SHAKAPACKER - Rails Webpack/Rspack Integration
|
|
@@ -320,6 +322,7 @@ module Shakapacker
|
|
|
320
322
|
|
|
321
323
|
Shakapacker-specific options:
|
|
322
324
|
-h, --help Show this help message
|
|
325
|
+
--help=verbose Show verbose help including all bundler options
|
|
323
326
|
-v, --version Show Shakapacker version
|
|
324
327
|
--debug-shakapacker Enable Node.js debugging (--inspect-brk)
|
|
325
328
|
--trace-deprecation Show stack traces for deprecations
|
|
@@ -347,7 +350,7 @@ module Shakapacker
|
|
|
347
350
|
|
|
348
351
|
HELP
|
|
349
352
|
|
|
350
|
-
print_bundler_help
|
|
353
|
+
print_bundler_help(verbose: verbose)
|
|
351
354
|
|
|
352
355
|
puts <<~HELP
|
|
353
356
|
|
|
@@ -366,8 +369,9 @@ module Shakapacker
|
|
|
366
369
|
HELP
|
|
367
370
|
end
|
|
368
371
|
|
|
369
|
-
def self.print_bundler_help
|
|
370
|
-
|
|
372
|
+
def self.print_bundler_help(verbose: false)
|
|
373
|
+
help_flag = verbose ? "--help=verbose" : "--help"
|
|
374
|
+
bundler_type, bundler_help = get_bundler_help(help_flag)
|
|
371
375
|
|
|
372
376
|
if bundler_help
|
|
373
377
|
bundler_name = bundler_type == :rspack ? "RSPACK" : "WEBPACK"
|
|
@@ -390,8 +394,8 @@ module Shakapacker
|
|
|
390
394
|
end
|
|
391
395
|
end
|
|
392
396
|
|
|
393
|
-
def self.get_bundler_help
|
|
394
|
-
execute_bundler_command(
|
|
397
|
+
def self.get_bundler_help(help_flag = "--help")
|
|
398
|
+
execute_bundler_command(help_flag) { |stdout| stdout }
|
|
395
399
|
end
|
|
396
400
|
|
|
397
401
|
# Filter bundler help output to remove Shakapacker-managed options
|
|
@@ -61,13 +61,13 @@ module Shakapacker
|
|
|
61
61
|
keepClassNames: true,
|
|
62
62
|
transform: {
|
|
63
63
|
react: {
|
|
64
|
-
runtime:
|
|
65
|
-
refresh: env.isDevelopment && env.runningWebpackDevServer
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
64
|
+
runtime: 'automatic',
|
|
65
|
+
refresh: env.isDevelopment && env.runningWebpackDevServer,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
71
|
JS
|
|
72
72
|
|
|
73
73
|
def initialize(root_path, logger: nil)
|
data/lib/shakapacker/version.rb
CHANGED