shakapacker 9.3.0 → 9.3.2

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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/update-changelog.md +232 -0
  3. data/.github/actionlint-matcher.json +17 -0
  4. data/.github/workflows/dummy.yml +9 -0
  5. data/.github/workflows/generator.yml +13 -0
  6. data/.github/workflows/node.yml +83 -0
  7. data/.github/workflows/ruby.yml +11 -0
  8. data/.github/workflows/test-bundlers.yml +10 -0
  9. data/CHANGELOG.md +24 -9
  10. data/CLAUDE.md +6 -10
  11. data/CONTRIBUTING.md +44 -0
  12. data/Gemfile.lock +1 -1
  13. data/README.md +74 -44
  14. data/docs/api-reference.md +519 -0
  15. data/docs/cdn_setup.md +3 -3
  16. data/docs/common-upgrades.md +6 -7
  17. data/docs/configuration.md +14 -8
  18. data/docs/css-modules-export-mode.md +40 -6
  19. data/docs/deployment.md +3 -3
  20. data/docs/early_hints_manual_api.md +1 -1
  21. data/docs/feature_testing.md +3 -3
  22. data/docs/optional-peer-dependencies.md +2 -2
  23. data/docs/precompile_hook.md +15 -15
  24. data/docs/react.md +1 -1
  25. data/docs/releasing.md +7 -7
  26. data/docs/rspack_migration_guide.md +8 -14
  27. data/docs/transpiler-migration.md +12 -9
  28. data/docs/troubleshooting.md +3 -3
  29. data/docs/using_swc_loader.md +13 -10
  30. data/docs/v6_upgrade.md +2 -2
  31. data/docs/v9_upgrade.md +78 -3
  32. data/eslint.config.fast.js +120 -8
  33. data/eslint.config.js +50 -31
  34. data/lib/install/config/shakapacker.yml +14 -1
  35. data/lib/shakapacker/bundler_switcher.rb +83 -18
  36. data/lib/shakapacker/configuration.rb +47 -4
  37. data/lib/shakapacker/dev_server_runner.rb +4 -0
  38. data/lib/shakapacker/doctor.rb +7 -7
  39. data/lib/shakapacker/runner.rb +1 -1
  40. data/lib/shakapacker/swc_migrator.rb +2 -2
  41. data/lib/shakapacker/version.rb +1 -1
  42. data/lib/tasks/shakapacker/binstubs.rake +4 -2
  43. data/lib/tasks/shakapacker/check_binstubs.rake +2 -2
  44. data/lib/tasks/shakapacker/doctor.rake +3 -3
  45. data/lib/tasks/shakapacker/export_bundler_config.rake +5 -9
  46. data/lib/tasks/shakapacker/install.rake +4 -2
  47. data/lib/tasks/shakapacker/switch_bundler.rake +30 -40
  48. data/package/config.ts +2 -3
  49. data/package/configExporter/cli.ts +29 -24
  50. data/package/dev_server.ts +2 -2
  51. data/package/env.ts +1 -1
  52. data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +6 -6
  53. data/package/environments/base.ts +2 -2
  54. data/package/environments/development.ts +3 -6
  55. data/package/environments/production.ts +2 -2
  56. data/package/environments/test.ts +2 -1
  57. data/package/esbuild/index.ts +0 -2
  58. data/package/index.d.ts +1 -0
  59. data/package/index.d.ts.template +1 -0
  60. data/package/index.ts +0 -1
  61. data/package/loaders.d.ts +1 -1
  62. data/package/plugins/rspack.ts +3 -1
  63. data/package/plugins/webpack.ts +5 -3
  64. data/package/rspack/index.ts +3 -3
  65. data/package/rules/file.ts +1 -1
  66. data/package/rules/raw.ts +3 -1
  67. data/package/rules/rspack.ts +0 -2
  68. data/package/rules/sass.ts +0 -2
  69. data/package/rules/webpack.ts +0 -1
  70. data/package/swc/index.ts +0 -2
  71. data/package/types.ts +8 -11
  72. data/package/utils/debug.ts +0 -4
  73. data/package/utils/getStyleRule.ts +17 -9
  74. data/package/utils/helpers.ts +8 -3
  75. data/package/utils/pathValidation.ts +10 -11
  76. data/package/utils/requireOrError.ts +4 -3
  77. data/package/webpack-types.d.ts +1 -1
  78. data/package/webpackDevServerConfig.ts +4 -4
  79. data/package.json +3 -3
  80. data/test/package/transpiler-defaults.test.js +42 -0
  81. data/yarn.lock +1 -1
  82. metadata +5 -2
@@ -302,7 +302,7 @@ module Shakapacker
302
302
  def print_config_not_found_error(bundler_type, config_path, config_dir)
303
303
  $stderr.puts "[Shakapacker] ERROR: #{bundler_type} config #{config_path} not found."
304
304
  $stderr.puts ""
305
- $stderr.puts "Please run 'bundle exec rails shakapacker:install' to install Shakapacker with default configs,"
305
+ $stderr.puts "Please run 'bundle exec rake shakapacker:install' to install Shakapacker with default configs,"
306
306
  $stderr.puts "or create the missing config file."
307
307
  $stderr.puts ""
308
308
  $stderr.puts "If your config file is in a different location, you can configure it in config/shakapacker.yml:"
@@ -101,11 +101,11 @@ module Shakapacker
101
101
  logger.info " - #{package}"
102
102
  end
103
103
  logger.info "\n To remove them, run:"
104
- logger.info " rails shakapacker:clean_babel_packages"
104
+ logger.info " bundle exec rake shakapacker:clean_babel_packages"
105
105
  end
106
106
 
107
107
  # Suggest running doctor to verify configuration
108
- logger.info "\n🩺 Run 'rails shakapacker:doctor' to verify your configuration"
108
+ logger.info "\n🩺 Run 'bundle exec rake shakapacker:doctor' to verify your configuration"
109
109
 
110
110
  # Run package manager install if packages were added
111
111
  if run_installer && results[:packages_installed].any?
@@ -1,4 +1,4 @@
1
1
  module Shakapacker
2
2
  # Change the version in package.json too, please!
3
- VERSION = "9.3.0".freeze
3
+ VERSION = "9.3.2".freeze
4
4
  end
@@ -7,9 +7,11 @@ namespace :shakapacker do
7
7
  prefix = task.name.split(/#|shakapacker:binstubs/).first
8
8
 
9
9
  if Rails::VERSION::MAJOR >= 5
10
- exec "#{RbConfig.ruby} '#{bin_path}/rails' #{prefix}app:template LOCATION='#{binstubs_template_path}'"
10
+ system "#{RbConfig.ruby} '#{bin_path}/rails' #{prefix}app:template LOCATION='#{binstubs_template_path}'" or
11
+ raise "Binstubs installation failed"
11
12
  else
12
- exec "#{RbConfig.ruby} '#{bin_path}/rake' #{prefix}rails:template LOCATION='#{binstubs_template_path}'"
13
+ system "#{RbConfig.ruby} '#{bin_path}/rake' #{prefix}rails:template LOCATION='#{binstubs_template_path}'" or
14
+ raise "Binstubs installation failed"
13
15
  end
14
16
  end
15
17
  end
@@ -11,8 +11,8 @@ def verify_file_existence(binstub_file)
11
11
  puts <<~MSG
12
12
  Couldn't find shakapacker binstubs!
13
13
  Possible solutions:
14
- - Ensure you have run `rails shakapacker:install`.
15
- - Run `rails shakapacker:binstubs` if you have already installed shakapacker.
14
+ - Ensure you have run `bundle exec rake shakapacker:install`.
15
+ - Run `bundle exec rake shakapacker:binstubs` if you have already installed shakapacker.
16
16
  - Ensure the `bin` directory, `bin/shakapacker`, and `bin/shakapacker-dev-server` are not included in .gitignore.
17
17
  MSG
18
18
  exit!
@@ -20,9 +20,9 @@ namespace :shakapacker do
20
20
  --verbose Display additional diagnostic details (paths, versions, environment)
21
21
 
22
22
  Examples:
23
- bin/rails shakapacker:doctor
24
- bin/rails shakapacker:doctor -- --verbose
25
- bin/rails shakapacker:doctor -- --help
23
+ bundle exec rake shakapacker:doctor
24
+ bundle exec rake shakapacker:doctor -- --verbose
25
+ bundle exec rake shakapacker:doctor -- --help
26
26
 
27
27
  Exit codes:
28
28
  0 - No issues found
@@ -7,7 +7,6 @@ namespace :shakapacker do
7
7
  client vs server bundle differences.
8
8
 
9
9
  Usage:
10
- rails shakapacker:export_bundler_config [OPTIONS]
11
10
  rake shakapacker:export_bundler_config -- [OPTIONS]
12
11
 
13
12
  Quick Start (Recommended):
@@ -28,22 +27,19 @@ namespace :shakapacker do
28
27
 
29
28
  Examples:
30
29
  # Export all configs for troubleshooting
31
- rails shakapacker:export_bundler_config --doctor
30
+ bundle exec rake shakapacker:export_bundler_config -- --doctor
32
31
 
33
32
  # Save production client config
34
- rails shakapacker:export_bundler_config --save --env=production --client-only
33
+ bundle exec rake shakapacker:export_bundler_config -- --save --env=production --client-only
35
34
 
36
35
  # View development config in terminal
37
- rails shakapacker:export_bundler_config
36
+ bundle exec rake shakapacker:export_bundler_config
38
37
 
39
38
  # Show detailed help
40
- rails shakapacker:export_bundler_config --help
41
-
42
- Note: When using 'rake', you must use '--' to separate rake options from task arguments.
43
- Example: rake shakapacker:export_bundler_config -- --doctor
39
+ bundle exec rake shakapacker:export_bundler_config -- --help
44
40
 
45
41
  The task automatically falls back to the gem version if bin/shakapacker-config
46
- binstub is not installed. To install all binstubs, run: rails shakapacker:binstubs
42
+ binstub is not installed. To install all binstubs, run: bundle exec rake shakapacker:binstubs
47
43
  DESC
48
44
  task :export_bundler_config do
49
45
  # Try to use the binstub if it exists, otherwise use the gem's version
@@ -19,9 +19,11 @@ namespace :shakapacker do
19
19
  prefix = task.name.split(/#|shakapacker:install/).first
20
20
 
21
21
  if Rails::VERSION::MAJOR >= 5
22
- exec "#{RbConfig.ruby} '#{bin_path}/rails' #{prefix}app:template LOCATION='#{install_template_path}'"
22
+ system "#{RbConfig.ruby} '#{bin_path}/rails' #{prefix}app:template LOCATION='#{install_template_path}'" or
23
+ raise "Installation failed"
23
24
  else
24
- exec "#{RbConfig.ruby} '#{bin_path}/rake' #{prefix}rails:template LOCATION='#{install_template_path}'"
25
+ system "#{RbConfig.ruby} '#{bin_path}/rake' #{prefix}rails:template LOCATION='#{install_template_path}'" or
26
+ raise "Installation failed"
25
27
  end
26
28
  end
27
29
  end
@@ -8,48 +8,26 @@ namespace :shakapacker do
8
8
  This task updates config/shakapacker.yml and optionally manages npm dependencies.
9
9
 
10
10
  Usage:
11
- rails shakapacker:switch_bundler [webpack|rspack] [OPTIONS]
12
- rake shakapacker:switch_bundler [webpack|rspack] -- [OPTIONS]
11
+ bin/rake shakapacker:switch_bundler [webpack|rspack] -- [OPTIONS]
13
12
 
14
13
  Options:
15
14
  --install-deps Automatically install/uninstall bundler dependencies
16
- --no-uninstall Skip uninstalling old bundler packages (faster, keeps both bundlers)
15
+ --no-uninstall Skip uninstalling old bundler packages
17
16
  --init-config Create custom dependencies configuration file
18
17
  --help, -h Show detailed help message
19
18
 
20
19
  Examples:
21
- # Switch to rspack with automatic dependency management
22
- rails shakapacker:switch_bundler rspack --install-deps
23
- rake shakapacker:switch_bundler rspack -- --install-deps
24
-
25
- # Fast switching without uninstalling (keeps both bundlers)
26
- rails shakapacker:switch_bundler webpack --install-deps --no-uninstall
27
- rake shakapacker:switch_bundler rspack -- --install-deps --no-uninstall
28
-
29
- # Switch to rspack (manual dependency management)
30
- rails shakapacker:switch_bundler rspack
31
- rake shakapacker:switch_bundler rspack
32
-
33
- # Switch back to webpack with dependency management
34
- rails shakapacker:switch_bundler webpack --install-deps
35
- rake shakapacker:switch_bundler webpack -- --install-deps
36
-
37
- # Create custom dependencies config file
38
- rails shakapacker:switch_bundler --init-config
39
- rake shakapacker:switch_bundler -- --init-config
40
-
41
- # Show current bundler and usage help
42
- rails shakapacker:switch_bundler --help
43
- rake shakapacker:switch_bundler -- --help
44
-
45
- Note: When using 'rake', you must use '--' to separate rake options from task arguments.
20
+ bin/rake shakapacker:switch_bundler rspack -- --install-deps
21
+ bin/rake shakapacker:switch_bundler webpack -- --install-deps --no-uninstall
22
+ bin/rake shakapacker:switch_bundler -- --init-config
23
+ bin/rake shakapacker:switch_bundler -- --help
46
24
 
47
25
  What it does:
48
26
  - Updates 'assets_bundler' in config/shakapacker.yml
49
27
  - Preserves YAML comments and structure
50
28
  - Updates 'javascript_transpiler' to 'swc' when switching to rspack
51
29
  - With --install-deps: installs/uninstalls npm dependencies automatically
52
- - Without --install-deps: shows manual installation commands
30
+ - Without: shows manual installation commands
53
31
 
54
32
  Custom Dependencies:
55
33
  Create .shakapacker-switch-bundler-dependencies.yml to customize which
@@ -58,22 +36,34 @@ namespace :shakapacker do
58
36
  See docs/rspack_migration_guide.md for more information.
59
37
  DESC
60
38
  task :switch_bundler do
39
+ # This task must be run with rake, not rails
40
+ # Check the actual command name, not just if the path contains "rails"
41
+ command_name = File.basename($0)
42
+ if command_name == "rails" || $0.end_with?("/rails")
43
+ puts "\nError: This task must be run with 'bin/rake', not 'bin/rails'"
44
+ puts "Usage: bin/rake shakapacker:switch_bundler [bundler] -- [options]"
45
+ puts "Run 'bin/rake shakapacker:switch_bundler -- --help' for more information"
46
+ exit 1
47
+ end
48
+
61
49
  switcher = Shakapacker::BundlerSwitcher.new
62
50
 
63
- if ARGV.empty? || ARGV.include?("--help") || ARGV.include?("-h")
51
+ # Parse command line arguments
52
+ # ARGV[0] is the task name, ARGV[1] would be the bundler name if provided
53
+ bundler = ARGV.length > 1 ? ARGV[1] : nil
54
+ install_deps = ARGV.include?("--install-deps")
55
+ no_uninstall = ARGV.include?("--no-uninstall")
56
+ init_config = ARGV.include?("--init-config")
57
+ show_help = ARGV.include?("--help") || ARGV.include?("-h")
58
+
59
+ if ARGV.empty? || show_help || (bundler.nil? && !init_config)
64
60
  switcher.show_usage
65
- elsif ARGV.include?("--init-config")
61
+ elsif init_config
66
62
  switcher.init_config
63
+ elsif bundler.nil? || bundler.start_with?("-")
64
+ switcher.show_usage
67
65
  else
68
- bundler = ARGV[1]
69
- install_deps = ARGV.include?("--install-deps")
70
- no_uninstall = ARGV.include?("--no-uninstall")
71
-
72
- if bundler.nil? || bundler.start_with?("-")
73
- switcher.show_usage
74
- else
75
- switcher.switch_to(bundler, install_deps: install_deps, no_uninstall: no_uninstall)
76
- end
66
+ switcher.switch_to(bundler, install_deps: install_deps, no_uninstall: no_uninstall)
77
67
  end
78
68
 
79
69
  # Prevent rake from trying to execute arguments as tasks
data/package/config.ts CHANGED
@@ -6,12 +6,11 @@ const { ensureTrailingSlash } = require("./utils/helpers")
6
6
  const { railsEnv } = require("./env")
7
7
  const configPath = require("./utils/configPath")
8
8
  const defaultConfigPath = require("./utils/defaultConfigPath")
9
- import { Config, YamlConfig, LegacyConfig } from "./types"
9
+ import { Config, YamlConfig } from "./types"
10
10
  const {
11
11
  isValidYamlConfig,
12
12
  createConfigValidationError,
13
- isPartialConfig,
14
- isValidConfig
13
+ isPartialConfig
15
14
  } = require("./utils/typeGuards")
16
15
  const {
17
16
  isFileNotFoundError,
@@ -309,58 +309,61 @@ QUICK START (for troubleshooting):
309
309
  description:
310
310
  "Generate only server config (fallback when no config file exists)"
311
311
  })
312
- .check((argv) => {
313
- if (argv.webpack && argv.rspack) {
312
+ .check((parsedArgs) => {
313
+ if (parsedArgs.webpack && parsedArgs.rspack) {
314
314
  throw new Error(
315
315
  "--webpack and --rspack are mutually exclusive. Please specify only one."
316
316
  )
317
317
  }
318
- if (argv["client-only"] && argv["server-only"]) {
318
+ if (parsedArgs["client-only"] && parsedArgs["server-only"]) {
319
319
  throw new Error(
320
320
  "--client-only and --server-only are mutually exclusive. Please specify only one."
321
321
  )
322
322
  }
323
- if (argv.output && argv["save-dir"]) {
323
+ if (parsedArgs.output && parsedArgs["save-dir"]) {
324
324
  throw new Error(
325
325
  "--output and --save-dir are mutually exclusive. Use one or the other."
326
326
  )
327
327
  }
328
- if (argv.stdout && argv["save-dir"]) {
328
+ if (parsedArgs.stdout && parsedArgs["save-dir"]) {
329
329
  throw new Error(
330
330
  "--stdout and --save-dir are mutually exclusive. Use one or the other."
331
331
  )
332
332
  }
333
- if (argv.build && argv["all-builds"]) {
333
+ if (parsedArgs.build && parsedArgs["all-builds"]) {
334
334
  throw new Error(
335
335
  "--build and --all-builds are mutually exclusive. Use one or the other."
336
336
  )
337
337
  }
338
- if (argv.validate && argv["validate-build"]) {
338
+ if (parsedArgs.validate && parsedArgs["validate-build"]) {
339
339
  throw new Error(
340
340
  "--validate and --validate-build are mutually exclusive. Use one or the other."
341
341
  )
342
342
  }
343
- if (argv.validate && (argv.build || argv["all-builds"])) {
343
+ if (
344
+ parsedArgs.validate &&
345
+ (parsedArgs.build || parsedArgs["all-builds"])
346
+ ) {
344
347
  throw new Error(
345
348
  "--validate cannot be used with --build or --all-builds."
346
349
  )
347
350
  }
348
- if (argv["all-builds"] && argv.output) {
351
+ if (parsedArgs["all-builds"] && parsedArgs.output) {
349
352
  throw new Error(
350
353
  "--all-builds and --output are mutually exclusive. Use --save-dir instead."
351
354
  )
352
355
  }
353
- if (argv["all-builds"] && argv.stdout) {
356
+ if (parsedArgs["all-builds"] && parsedArgs.stdout) {
354
357
  throw new Error(
355
358
  "--all-builds and --stdout are mutually exclusive. Use --save-dir instead."
356
359
  )
357
360
  }
358
- if (argv.stdout && argv.output) {
361
+ if (parsedArgs.stdout && parsedArgs.output) {
359
362
  throw new Error(
360
363
  "--stdout and --output are mutually exclusive. Use one or the other."
361
364
  )
362
365
  }
363
- if (argv.ssr && !argv.init) {
366
+ if (parsedArgs.ssr && !parsedArgs.init) {
364
367
  throw new Error(
365
368
  "--ssr can only be used with --init. Use: bin/shakapacker-config --init --ssr"
366
369
  )
@@ -539,7 +542,7 @@ end
539
542
  // Make executable
540
543
  try {
541
544
  chmodSync(binStubPath, 0o755)
542
- } catch (e) {
545
+ } catch (_e) {
543
546
  // chmod might fail on some systems, but mode in writeFileSync should handle it
544
547
  }
545
548
  }
@@ -646,6 +649,7 @@ async function runValidateCommand(options: ExportOptions): Promise<number> {
646
649
  "development"
647
650
 
648
651
  // Auto-detect bundler using the build's environment
652
+ // eslint-disable-next-line no-await-in-loop -- Sequential execution required: each build modifies shared global state (env vars, config cache) that must be cleared/restored between iterations
649
653
  const defaultBundler = await autoDetectBundler(
650
654
  buildEnv,
651
655
  appRoot,
@@ -660,6 +664,7 @@ async function runValidateCommand(options: ExportOptions): Promise<number> {
660
664
  )
661
665
 
662
666
  // Validate the build
667
+ // eslint-disable-next-line no-await-in-loop -- Sequential execution required: each build modifies shared global state (env vars, config cache) that must be cleared/restored between iterations
663
668
  const result = await validator.validateBuild(resolvedBuild, appRoot)
664
669
  results.push(result)
665
670
 
@@ -738,6 +743,7 @@ async function runAllBuildsCommand(options: ExportOptions): Promise<number> {
738
743
 
739
744
  // Create a modified options object for this build
740
745
  const buildOptions = { ...resolvedOptions, build: buildName }
746
+ // eslint-disable-next-line no-await-in-loop -- Sequential execution required: each build modifies shared global state (env vars, config cache) that must be cleared/restored between iterations
741
747
  const configs = await loadConfigsForEnv(undefined, buildOptions, appRoot)
742
748
 
743
749
  for (const { config: cfg, metadata } of configs) {
@@ -817,6 +823,7 @@ async function runDoctorMode(
817
823
  // Clear shakapacker config cache between builds
818
824
  shakapackerConfigCache = null
819
825
 
826
+ // eslint-disable-next-line no-await-in-loop -- Sequential execution required: each build modifies shared global state (env vars, config cache) that must be cleared/restored between iterations
820
827
  const configs = await loadConfigsForEnv(
821
828
  undefined,
822
829
  { ...options, build: buildName },
@@ -884,6 +891,7 @@ async function runDoctorMode(
884
891
  process.env.WEBPACK_SERVE = "true"
885
892
  }
886
893
 
894
+ // eslint-disable-next-line no-await-in-loop -- Sequential execution required: each config modifies shared global state (env vars, config cache) that must be cleared/restored between iterations
887
895
  const configs = await loadConfigsForEnv(env, options, appRoot)
888
896
 
889
897
  for (const { config, metadata } of configs) {
@@ -922,7 +930,6 @@ async function runDoctorMode(
922
930
  }
923
931
 
924
932
  const fullPath = resolve(targetDir, filename)
925
- const fileOutput: FileOutput = { filename, content: output, metadata }
926
933
  FileWriter.writeSingleFile(fullPath, output)
927
934
  createdFiles.push(fullPath)
928
935
  }
@@ -1099,19 +1106,17 @@ async function loadConfigsForEnv(
1099
1106
  console.warn(
1100
1107
  `[Config Exporter] Warning: Skipping dangerous environment variable: ${key}`
1101
1108
  )
1102
- continue
1103
- }
1104
- if (!isBuildEnvVar(key)) {
1109
+ } else if (!isBuildEnvVar(key)) {
1105
1110
  console.warn(
1106
1111
  `[Config Exporter] Warning: Skipping non-whitelisted environment variable: ${key}. ` +
1107
1112
  `Allowed variables are: ${BUILD_ENV_VARS.join(", ")}`
1108
1113
  )
1109
- continue
1110
- }
1111
- if (options.verbose) {
1112
- console.log(`[Config Exporter] ${key}=${value}`)
1114
+ } else {
1115
+ if (options.verbose) {
1116
+ console.log(`[Config Exporter] ${key}=${value}`)
1117
+ }
1118
+ process.env[key] = value
1113
1119
  }
1114
- process.env[key] = value
1115
1120
  }
1116
1121
 
1117
1122
  // Determine final env: CLI flag > build config NODE_ENV > default
@@ -1193,7 +1198,7 @@ async function loadConfigsForEnv(
1193
1198
  if (configFile.endsWith(".ts")) {
1194
1199
  try {
1195
1200
  require("ts-node/register/transpile-only")
1196
- } catch (error) {
1201
+ } catch (_error) {
1197
1202
  throw new Error(
1198
1203
  "TypeScript config detected but ts-node is not available. " +
1199
1204
  "Install ts-node as a dev dependency: npm install --save-dev ts-node"
@@ -1630,7 +1635,7 @@ function loadShakapackerConfig(
1630
1635
 
1631
1636
  return result
1632
1637
  }
1633
- } catch (error: unknown) {
1638
+ } catch (_error: unknown) {
1634
1639
  console.warn(
1635
1640
  `[Config Exporter] Error loading shakapacker config, defaulting to webpack`
1636
1641
  )
@@ -1,8 +1,8 @@
1
1
  // These are the raw shakapacker dev server config settings from the YML file with ENV overrides applied.
2
- import { DevServerConfig } from "./types"
2
+ import type { DevServerConfig, Config } from "./types"
3
3
 
4
4
  const { isBoolean } = require("./utils/helpers")
5
- const config = require("./config")
5
+ const config = require("./config") as Config
6
6
 
7
7
  const envFetch = (key: string): string | boolean | undefined => {
8
8
  const value = process.env[key]
data/package/env.ts CHANGED
@@ -51,7 +51,7 @@ try {
51
51
  // File not found, use default configuration
52
52
  try {
53
53
  config = load(readFileSync(defaultConfigPath, "utf8")) as ConfigFile
54
- } catch (defaultError) {
54
+ } catch (_defaultError) {
55
55
  throw new Error(
56
56
  `Failed to load Shakapacker configuration.\n` +
57
57
  `Neither user config (${configPath}) nor default config (${defaultConfigPath}) could be loaded.\n\n` +
@@ -9,26 +9,26 @@
9
9
  import type { RspackPlugin, RspackPluginInstance } from "../types"
10
10
 
11
11
  // Test 1: RspackPlugin should be assignable to RspackPluginInstance
12
- const testPluginToInstance = (plugin: RspackPlugin): RspackPluginInstance =>
12
+ const _testPluginToInstance = (plugin: RspackPlugin): RspackPluginInstance =>
13
13
  plugin
14
14
 
15
15
  // Test 2: RspackPluginInstance should be assignable to RspackPlugin
16
- const testInstanceToPlugin = (instance: RspackPluginInstance): RspackPlugin =>
16
+ const _testInstanceToPlugin = (instance: RspackPluginInstance): RspackPlugin =>
17
17
  instance
18
18
 
19
19
  // Test 3: Array compatibility
20
- const testArrayCompatibility = (
20
+ const _testArrayCompatibility = (
21
21
  plugins: RspackPlugin[]
22
22
  ): RspackPluginInstance[] => plugins
23
- const testArrayCompatibilityReverse = (
23
+ const _testArrayCompatibilityReverse = (
24
24
  instances: RspackPluginInstance[]
25
25
  ): RspackPlugin[] => instances
26
26
 
27
27
  // Test 4: Optional parameter compatibility
28
- const testOptionalParam = (
28
+ const _testOptionalParam = (
29
29
  plugin?: RspackPlugin
30
30
  ): RspackPluginInstance | undefined => plugin
31
- const testOptionalParamReverse = (
31
+ const _testOptionalParamReverse = (
32
32
  instance?: RspackPluginInstance
33
33
  ): RspackPlugin | undefined => instance
34
34
 
@@ -1,13 +1,13 @@
1
- /* eslint global-require: 0 */
2
1
  /* eslint import/no-dynamic-require: 0 */
3
2
 
4
3
  import { Dirent } from "fs"
5
4
  import type { Configuration, Entry } from "webpack"
5
+ import type { Config } from "../types"
6
6
 
7
7
  const { basename, dirname, join, relative, resolve } = require("path")
8
8
  const { existsSync, readdirSync } = require("fs")
9
9
  const extname = require("path-complete-extname")
10
- const config = require("../config")
10
+ const config = require("../config") as Config
11
11
  const { isProduction } = require("../env")
12
12
 
13
13
  const pluginsPath = resolve(
@@ -5,13 +5,12 @@
5
5
 
6
6
  import type {
7
7
  WebpackConfigWithDevServer,
8
- RspackConfigWithDevServer,
9
- ReactRefreshWebpackPlugin,
10
- ReactRefreshRspackPlugin
8
+ RspackConfigWithDevServer
11
9
  } from "./types"
10
+ import type { Config } from "../types"
12
11
 
13
12
  const { merge } = require("webpack-merge")
14
- const config = require("../config")
13
+ const config = require("../config") as Config
15
14
  const baseConfig = require("./base")
16
15
  const webpackDevServerConfig = require("../webpackDevServerConfig")
17
16
  const { runningWebpackDevServer } = require("../env")
@@ -41,7 +40,6 @@ const webpackDevConfig = (): WebpackConfigWithDevServer => {
41
40
  devServerConfig.hot &&
42
41
  moduleExists("@pmmmwh/react-refresh-webpack-plugin")
43
42
  ) {
44
- // eslint-disable-next-line global-require
45
43
  const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin")
46
44
  webpackConfig.plugins = [
47
45
  ...(webpackConfig.plugins || []),
@@ -74,7 +72,6 @@ const rspackDevConfig = (): RspackConfigWithDevServer => {
74
72
  devServerConfig.hot &&
75
73
  moduleExists("@rspack/plugin-react-refresh")
76
74
  ) {
77
- // eslint-disable-next-line global-require
78
75
  const ReactRefreshPlugin = require("@rspack/plugin-react-refresh")
79
76
  rspackConfig.plugins = [
80
77
  ...(rspackConfig.plugins || []),
@@ -3,7 +3,6 @@
3
3
  * @module environments/production
4
4
  */
5
5
 
6
- /* eslint global-require: 0 */
7
6
  /* eslint import/no-dynamic-require: 0 */
8
7
 
9
8
  import type {
@@ -11,12 +10,13 @@ import type {
11
10
  WebpackPluginInstance
12
11
  } from "webpack"
13
12
  import type { CompressionPluginConstructor } from "./types"
13
+ import type { Config } from "../types"
14
14
 
15
15
  const { resolve } = require("path")
16
16
  const { merge } = require("webpack-merge")
17
17
  const baseConfig = require("./base")
18
18
  const { moduleExists } = require("../utils/helpers")
19
- const config = require("../config")
19
+ const config = require("../config") as Config
20
20
 
21
21
  const optimizationPath = resolve(
22
22
  __dirname,
@@ -4,9 +4,10 @@
4
4
  */
5
5
 
6
6
  import type { Configuration as WebpackConfiguration } from "webpack"
7
+ import type { Config } from "../types"
7
8
 
8
9
  const { merge } = require("webpack-merge")
9
- const config = require("../config")
10
+ const config = require("../config") as Config
10
11
  const baseConfig = require("./base")
11
12
 
12
13
  interface TestConfig {
@@ -1,4 +1,3 @@
1
- /* eslint global-require: 0 */
2
1
  /* eslint import/no-dynamic-require: 0 */
3
2
 
4
3
  import { resolve } from "path"
@@ -21,7 +20,6 @@ const getLoaderExtension = (filename: string): string => {
21
20
  const getCustomConfig = (): Partial<RuleSetRule> => {
22
21
  const path = resolve("config", "esbuild.config.js")
23
22
  if (existsSync(path)) {
24
- // eslint-disable-next-line @typescript-eslint/no-require-imports
25
23
  return require(path)
26
24
  }
27
25
  return {}
data/package/index.d.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  * When adding/modifying exports in index.ts, update this file accordingly.
8
8
  */
9
9
 
10
+ // @ts-ignore: webpack is an optional peer dependency (using type-only import)
10
11
  import type { Configuration, RuleSetRule } from "webpack"
11
12
  import type { Config, DevServerConfig, Env } from "./types"
12
13
 
@@ -7,6 +7,7 @@
7
7
  * When adding/modifying exports in index.ts, update this file accordingly.
8
8
  */
9
9
 
10
+ // @ts-ignore: webpack is an optional peer dependency (using type-only import)
10
11
  import type { Configuration, RuleSetRule } from "webpack"
11
12
  import type { Config, DevServerConfig, Env } from "./types"
12
13
 
data/package/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint global-require: 0 */
2
1
  /* eslint import/no-dynamic-require: 0 */
3
2
 
4
3
  import * as webpackMerge from "webpack-merge"
data/package/loaders.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // @ts-expect-error: webpack is an optional peer dependency (using type-only import)
1
+ // @ts-ignore: webpack is an optional peer dependency (using type-only import)
2
2
  import type { LoaderDefinitionFunction } from "webpack"
3
3
 
4
4
  export interface ShakapackerLoaderOptions {
@@ -1,8 +1,10 @@
1
+ import type { Config } from "../types"
2
+
1
3
  const { requireOrError } = require("../utils/requireOrError")
2
4
 
3
5
  const { RspackManifestPlugin } = requireOrError("rspack-manifest-plugin")
4
6
  const rspack = requireOrError("@rspack/core")
5
- const config = require("../config")
7
+ const config = require("../config") as Config
6
8
  const { isProduction } = require("../env")
7
9
  const { moduleExists } = require("../utils/helpers")
8
10
 
@@ -1,9 +1,11 @@
1
+ import type { Config } from "../types"
2
+
1
3
  const { requireOrError } = require("../utils/requireOrError")
2
4
  // TODO: Change to `const { WebpackAssetsManifest }` when dropping 'webpack-assets-manifest < 6.0.0' (Node >=20.10.0) support
3
5
  const WebpackAssetsManifest = requireOrError("webpack-assets-manifest")
4
6
  const webpack = requireOrError("webpack")
5
- const config = require("../config")
6
- const { isProduction, isDevelopment } = require("../env")
7
+ const config = require("../config") as Config
8
+ const { isProduction } = require("../env")
7
9
  const { moduleExists } = require("../utils/helpers")
8
10
 
9
11
  const getPlugins = (): unknown[] => {
@@ -15,7 +17,7 @@ const getPlugins = (): unknown[] => {
15
17
  const plugins = [
16
18
  new webpack.EnvironmentPlugin(process.env),
17
19
  new WebpackAssetsManifestConstructor({
18
- merge: isDevelopment,
20
+ merge: true,
19
21
  entrypoints: true,
20
22
  writeToDisk: true,
21
23
  output: config.manifestPath,