shakapacker 8.4.0 → 9.7.0
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/.claude/commands/address-review.md +206 -0
- data/.claude/commands/update-changelog.md +354 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +6 -9
- data/.github/ISSUE_TEMPLATE/feature_request.md +6 -8
- data/.github/STATUS.md +1 -0
- data/.github/actionlint-matcher.json +17 -0
- data/.github/workflows/claude-code-review.yml +45 -0
- data/.github/workflows/claude.yml +55 -0
- data/.github/workflows/dummy.yml +18 -5
- data/.github/workflows/eslint-validation.yml +46 -0
- data/.github/workflows/generator.yml +38 -22
- data/.github/workflows/node.yml +116 -2
- data/.github/workflows/ruby.yml +57 -15
- data/.github/workflows/test-bundlers.yml +180 -0
- data/.gitignore +27 -0
- data/.husky/pre-commit +2 -0
- data/.npmignore +56 -0
- data/.prettierignore +7 -0
- data/.rubocop.yml +2 -0
- data/.yalcignore +26 -0
- data/CHANGELOG.md +487 -19
- data/CLAUDE.md +63 -0
- data/CONTRIBUTING.md +268 -21
- data/ESLINT_TECHNICAL_DEBT.md +165 -0
- data/README.md +497 -137
- data/Rakefile +44 -4
- data/TODO.md +58 -0
- data/TODO_v9.md +97 -0
- data/bin/conductor-exec +24 -0
- data/bin/shakapacker-config +11 -0
- data/conductor-setup.sh +147 -0
- data/conductor.json +9 -0
- data/docs/api-reference.md +519 -0
- data/docs/cdn_setup.md +384 -0
- data/docs/common-upgrades.md +695 -0
- data/docs/configuration.md +845 -0
- data/docs/css-modules-export-mode.md +566 -0
- data/docs/customizing_babel_config.md +16 -16
- data/docs/deployment.md +78 -7
- data/docs/developing_shakapacker.md +6 -0
- data/docs/early_hints.md +433 -0
- data/docs/early_hints_manual_api.md +454 -0
- data/docs/feature_testing.md +492 -0
- data/docs/node_package_api.md +70 -0
- data/docs/optional-peer-dependencies.md +203 -0
- data/docs/peer-dependencies.md +71 -0
- data/docs/precompile_hook.md +486 -0
- data/docs/preventing_fouc.md +132 -0
- data/docs/react.md +58 -48
- data/docs/releasing.md +288 -0
- data/docs/rspack.md +218 -0
- data/docs/rspack_migration_guide.md +862 -0
- data/docs/sprockets.md +1 -0
- data/docs/style_loader_vs_mini_css.md +12 -12
- data/docs/subresource_integrity.md +13 -7
- data/docs/transpiler-migration.md +212 -0
- data/docs/transpiler-performance.md +200 -0
- data/docs/troubleshooting.md +272 -24
- data/docs/typescript-migration.md +388 -0
- data/docs/typescript.md +103 -0
- data/docs/using_esbuild_loader.md +12 -12
- data/docs/using_swc_loader.md +121 -16
- data/docs/v6_upgrade.md +42 -19
- data/docs/v7_upgrade.md +8 -6
- data/docs/v8_upgrade.md +13 -12
- data/docs/v9_upgrade.md +616 -0
- data/eslint.config.fast.js +254 -0
- data/eslint.config.js +309 -0
- data/jest.config.js +8 -1
- data/knip.ts +61 -0
- data/lib/install/bin/shakapacker +4 -6
- data/lib/install/bin/shakapacker-config +11 -0
- data/lib/install/bin/shakapacker-dev-server +1 -1
- data/lib/install/binstubs.rb +6 -2
- data/lib/install/config/rspack/rspack.config.js +6 -0
- data/lib/install/config/rspack/rspack.config.ts +7 -0
- data/lib/install/config/shakapacker.yml +75 -12
- data/lib/install/config/webpack/webpack.config.ts +7 -0
- data/lib/install/package.json +38 -0
- data/lib/install/template.rb +207 -45
- data/lib/shakapacker/build_config_loader.rb +147 -0
- data/lib/shakapacker/bundler_switcher.rb +415 -0
- data/lib/shakapacker/compiler.rb +87 -0
- data/lib/shakapacker/configuration.rb +475 -6
- data/lib/shakapacker/dev_server.rb +88 -1
- data/lib/shakapacker/dev_server_runner.rb +240 -6
- data/lib/shakapacker/doctor.rb +1191 -0
- data/lib/shakapacker/env.rb +19 -3
- data/lib/shakapacker/helper.rb +411 -14
- data/lib/shakapacker/install/env.rb +33 -0
- data/lib/shakapacker/instance.rb +93 -4
- data/lib/shakapacker/manifest.rb +167 -30
- data/lib/shakapacker/railtie.rb +4 -0
- data/lib/shakapacker/rspack_runner.rb +19 -0
- data/lib/shakapacker/runner.rb +668 -9
- data/lib/shakapacker/swc_migrator.rb +384 -0
- data/lib/shakapacker/utils/manager.rb +2 -0
- data/lib/shakapacker/utils/version_syntax_converter.rb +1 -1
- data/lib/shakapacker/version.rb +1 -1
- data/lib/shakapacker/version_checker.rb +1 -1
- data/lib/shakapacker/webpack_runner.rb +4 -42
- data/lib/shakapacker.rb +159 -1
- data/lib/tasks/shakapacker/binstubs.rake +4 -2
- data/lib/tasks/shakapacker/check_binstubs.rake +2 -2
- data/lib/tasks/shakapacker/doctor.rake +48 -0
- data/lib/tasks/shakapacker/export_bundler_config.rake +68 -0
- data/lib/tasks/shakapacker/install.rake +16 -4
- data/lib/tasks/shakapacker/migrate_to_swc.rake +13 -0
- data/lib/tasks/shakapacker/switch_bundler.rake +72 -0
- data/lib/tasks/shakapacker.rake +2 -0
- data/package/.npmignore +4 -0
- data/package/babel/preset.ts +59 -0
- data/package/config.ts +189 -0
- data/package/configExporter/buildValidator.ts +906 -0
- data/package/configExporter/cli.ts +1748 -0
- data/package/configExporter/configDocs.ts +102 -0
- data/package/configExporter/configFile.ts +663 -0
- data/package/configExporter/fileWriter.ts +112 -0
- data/package/configExporter/index.ts +15 -0
- data/package/configExporter/types.ts +159 -0
- data/package/configExporter/yamlSerializer.ts +391 -0
- data/package/dev_server.ts +27 -0
- data/package/env.ts +92 -0
- data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +36 -0
- data/package/environments/base.ts +147 -0
- data/package/environments/development.ts +88 -0
- data/package/environments/production.ts +82 -0
- data/package/environments/test.ts +55 -0
- data/package/environments/types.ts +98 -0
- data/package/esbuild/index.ts +40 -0
- data/package/index.d.ts +68 -93
- data/package/index.d.ts.template +72 -0
- data/package/index.ts +104 -0
- data/package/loaders.d.ts +28 -0
- data/package/optimization/rspack.ts +36 -0
- data/package/optimization/webpack.ts +55 -0
- data/package/plugins/envFilter.ts +82 -0
- data/package/plugins/rspack.ts +119 -0
- data/package/plugins/webpack.ts +82 -0
- data/package/rspack/index.ts +91 -0
- data/package/rules/{babel.js → babel.ts} +2 -2
- data/package/rules/{coffee.js → coffee.ts} +1 -1
- data/package/rules/css.ts +3 -0
- data/package/rules/{erb.js → erb.ts} +1 -1
- data/package/rules/esbuild.ts +10 -0
- data/package/rules/file.ts +41 -0
- data/package/rules/{jscommon.js → jscommon.ts} +5 -4
- data/package/rules/{less.js → less.ts} +4 -4
- data/package/rules/raw.ts +28 -0
- data/package/rules/rspack.ts +174 -0
- data/package/rules/sass.ts +21 -0
- data/package/rules/{stylus.js → stylus.ts} +4 -8
- data/package/rules/swc.ts +10 -0
- data/package/rules/{index.js → webpack.ts} +1 -2
- data/package/swc/index.ts +54 -0
- data/package/types/README.md +90 -0
- data/package/types/index.ts +69 -0
- data/package/types.ts +105 -0
- data/package/utils/bundlerUtils.ts +232 -0
- data/package/utils/configPath.ts +6 -0
- data/package/utils/debug.ts +45 -0
- data/package/utils/defaultConfigPath.ts +7 -0
- data/package/utils/ensureManifestExists.ts +17 -0
- data/package/utils/errorCodes.ts +249 -0
- data/package/utils/errorHelpers.ts +152 -0
- data/package/utils/getStyleRule.ts +75 -0
- data/package/utils/helpers.ts +99 -0
- data/package/utils/{inliningCss.js → inliningCss.ts} +3 -3
- data/package/utils/pathValidation.ts +207 -0
- data/package/utils/requireOrError.ts +24 -0
- data/package/utils/snakeToCamelCase.ts +5 -0
- data/package/utils/typeGuards.ts +388 -0
- data/package/utils/validateDependencies.ts +61 -0
- data/package/webpack-types.d.ts +33 -0
- data/package/webpackDevServerConfig.ts +130 -0
- data/package.json +157 -18
- data/scripts/remove-use-strict.js +44 -0
- data/scripts/type-check-no-emit.js +27 -0
- data/shakapacker.gemspec +4 -2
- data/sig/shakapacker/commands.rbs +35 -0
- data/sig/shakapacker/compiler.rbs +65 -0
- data/sig/shakapacker/compiler_strategy.rbs +41 -0
- data/sig/shakapacker/configuration.rbs +140 -0
- data/sig/shakapacker/dev_server.rbs +56 -0
- data/sig/shakapacker/env.rbs +25 -0
- data/sig/shakapacker/helper.rbs +98 -0
- data/sig/shakapacker/instance.rbs +46 -0
- data/sig/shakapacker/manifest.rbs +69 -0
- data/sig/shakapacker/version.rbs +4 -0
- data/sig/shakapacker.rbs +66 -0
- data/test/configExporter/buildValidator.test.js +1295 -0
- data/test/configExporter/configFile.test.js +393 -0
- data/test/configExporter/integration.test.js +262 -0
- data/test/helpers.js +1 -1
- data/test/package/bundlerUtils.rspack.test.js +145 -0
- data/test/package/bundlerUtils.test.js +97 -0
- data/test/package/config.test.js +14 -0
- data/test/package/configExporter/cli.test.js +440 -0
- data/test/package/configExporter/types.test.js +163 -0
- data/test/package/configExporter.test.js +491 -0
- data/test/package/env.test.js +42 -7
- data/test/package/environments/base.test.js +14 -4
- data/test/package/helpers.test.js +2 -2
- data/test/package/plugins/envFiltering.test.js +453 -0
- data/test/package/plugins/webpackSubresourceIntegrity.test.js +89 -0
- data/test/package/rspack/index.test.js +293 -0
- data/test/package/rspack/optimization.test.js +86 -0
- data/test/package/rspack/plugins.test.js +185 -0
- data/test/package/rspack/rules.test.js +229 -0
- data/test/package/rules/babel.test.js +65 -38
- data/test/package/rules/esbuild.test.js +13 -4
- data/test/package/rules/file.test.js +7 -1
- data/test/package/rules/raw.test.js +40 -7
- data/test/package/rules/sass-version-parsing.test.js +71 -0
- data/test/package/rules/sass.test.js +11 -6
- data/test/package/rules/sass1.test.js +8 -5
- data/test/package/rules/sass16.test.js +24 -0
- data/test/package/rules/swc.test.js +50 -39
- data/test/package/rules/webpack.test.js +35 -0
- data/test/package/staging.test.js +4 -3
- data/test/package/transpiler-defaults.test.js +169 -0
- data/test/package/utils/ensureManifestExists.test.js +51 -0
- data/test/package/yamlSerializer.test.js +204 -0
- data/test/peer-dependencies.sh +85 -0
- data/test/resolver.js +34 -3
- data/test/scripts/remove-use-strict.test.js +125 -0
- data/test/typescript/build.test.js +118 -0
- data/test/typescript/environments.test.js +107 -0
- data/test/typescript/pathValidation.test.js +186 -0
- data/test/typescript/requireOrError.test.js +49 -0
- data/test/typescript/securityValidation.test.js +182 -0
- data/tools/README.md +134 -0
- data/tools/css-modules-v9-codemod.js +179 -0
- data/tsconfig.eslint.json +9 -0
- data/tsconfig.json +38 -0
- data/yarn.lock +3202 -1097
- metadata +212 -44
- data/.eslintignore +0 -4
- data/.eslintrc.js +0 -36
- data/Gemfile.lock +0 -251
- data/package/babel/preset.js +0 -48
- data/package/config.js +0 -56
- data/package/dev_server.js +0 -23
- data/package/env.js +0 -48
- data/package/environments/base.js +0 -171
- data/package/environments/development.js +0 -13
- data/package/environments/production.js +0 -88
- data/package/environments/test.js +0 -3
- data/package/esbuild/index.js +0 -40
- data/package/index.js +0 -40
- data/package/rules/css.js +0 -3
- data/package/rules/esbuild.js +0 -10
- data/package/rules/file.js +0 -29
- data/package/rules/raw.js +0 -5
- data/package/rules/sass.js +0 -18
- data/package/rules/swc.js +0 -10
- data/package/swc/index.js +0 -50
- data/package/utils/configPath.js +0 -4
- data/package/utils/defaultConfigPath.js +0 -2
- data/package/utils/getStyleRule.js +0 -40
- data/package/utils/helpers.js +0 -62
- data/package/utils/snakeToCamelCase.js +0 -5
- data/package/webpackDevServerConfig.js +0 -71
- data/test/package/rules/index.test.js +0 -16
|
@@ -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 `
|
|
15
|
-
- Run `
|
|
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!
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require "shakapacker/doctor"
|
|
2
|
+
|
|
3
|
+
namespace :shakapacker do
|
|
4
|
+
desc <<~DESC
|
|
5
|
+
Checks for common Shakapacker configuration issues and missing dependencies
|
|
6
|
+
|
|
7
|
+
Performs comprehensive diagnostics including:
|
|
8
|
+
• Configuration file validity and deprecated settings
|
|
9
|
+
• Entry points, output paths, and asset compilation status
|
|
10
|
+
• Node.js and package manager installation
|
|
11
|
+
• Required and optional npm dependencies
|
|
12
|
+
• JavaScript transpiler (Babel, SWC, esbuild) configuration
|
|
13
|
+
• CSS, CSS Modules, and stylesheet preprocessor setup
|
|
14
|
+
• Binstubs presence (shakapacker, shakapacker-dev-server, shakapacker-config)
|
|
15
|
+
• Version consistency between gem and npm package
|
|
16
|
+
• Legacy Webpacker file detection
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
--help Show detailed help and usage information
|
|
20
|
+
--verbose Display additional diagnostic details (paths, versions, environment)
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
bundle exec rake shakapacker:doctor
|
|
24
|
+
bundle exec rake shakapacker:doctor -- --verbose
|
|
25
|
+
bundle exec rake shakapacker:doctor -- --help
|
|
26
|
+
|
|
27
|
+
Exit codes:
|
|
28
|
+
0 - No issues found
|
|
29
|
+
1 - Issues or warnings detected (see output for details)
|
|
30
|
+
DESC
|
|
31
|
+
task doctor: :environment do
|
|
32
|
+
# Parse command-line options
|
|
33
|
+
options = {}
|
|
34
|
+
ARGV.each do |arg|
|
|
35
|
+
case arg
|
|
36
|
+
when "--help", "-h"
|
|
37
|
+
options[:help] = true
|
|
38
|
+
when "--verbose", "-v"
|
|
39
|
+
options[:verbose] = true
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
Shakapacker::Doctor.new(nil, nil, options).run
|
|
44
|
+
|
|
45
|
+
# Prevent rake from treating options as task names
|
|
46
|
+
ARGV.each { |arg| task arg.to_sym do; end if arg.start_with?("--", "-") }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
namespace :shakapacker do
|
|
2
|
+
desc <<~DESC
|
|
3
|
+
Export webpack or rspack configuration for debugging and analysis
|
|
4
|
+
|
|
5
|
+
Exports your resolved webpack/rspack configuration in human-readable formats.
|
|
6
|
+
Use this to debug configuration issues, compare environments, or analyze
|
|
7
|
+
client vs server bundle differences.
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
rake shakapacker:export_bundler_config -- [OPTIONS]
|
|
11
|
+
|
|
12
|
+
Quick Start (Recommended):
|
|
13
|
+
rails shakapacker:export_bundler_config --doctor
|
|
14
|
+
|
|
15
|
+
This exports all configs (dev + prod, client + server) to shakapacker-config-exports/
|
|
16
|
+
directory in annotated YAML format - perfect for troubleshooting.
|
|
17
|
+
|
|
18
|
+
Common Options:
|
|
19
|
+
--doctor Export everything for troubleshooting (recommended)
|
|
20
|
+
--save Save current environment configs to files
|
|
21
|
+
--save-dir=<dir> Custom output directory (requires --save)
|
|
22
|
+
--env=development|production|test Specify environment
|
|
23
|
+
--client-only Export only client config
|
|
24
|
+
--server-only Export only server config
|
|
25
|
+
--format=yaml|json|inspect Output format
|
|
26
|
+
--help, -h Show detailed help
|
|
27
|
+
|
|
28
|
+
Examples:
|
|
29
|
+
# Export all configs for troubleshooting
|
|
30
|
+
bundle exec rake shakapacker:export_bundler_config -- --doctor
|
|
31
|
+
|
|
32
|
+
# Save production client config
|
|
33
|
+
bundle exec rake shakapacker:export_bundler_config -- --save --env=production --client-only
|
|
34
|
+
|
|
35
|
+
# View development config in terminal
|
|
36
|
+
bundle exec rake shakapacker:export_bundler_config
|
|
37
|
+
|
|
38
|
+
# Show detailed help
|
|
39
|
+
bundle exec rake shakapacker:export_bundler_config -- --help
|
|
40
|
+
|
|
41
|
+
The task automatically falls back to the gem version if bin/shakapacker-config
|
|
42
|
+
binstub is not installed. To install all binstubs, run: bundle exec rake shakapacker:binstubs
|
|
43
|
+
DESC
|
|
44
|
+
task :export_bundler_config do
|
|
45
|
+
# Try to use the binstub if it exists, otherwise use the gem's version
|
|
46
|
+
bin_path = Rails.root.join("bin/shakapacker-config")
|
|
47
|
+
|
|
48
|
+
unless File.exist?(bin_path)
|
|
49
|
+
# Binstub not installed, use the gem's version directly
|
|
50
|
+
gem_bin_path = File.expand_path("../../install/bin/shakapacker-config", __dir__)
|
|
51
|
+
|
|
52
|
+
$stderr.puts "Note: bin/shakapacker-config binstub not found."
|
|
53
|
+
$stderr.puts "Using gem version directly. To install the binstub, run: rake shakapacker:binstubs"
|
|
54
|
+
$stderr.puts ""
|
|
55
|
+
|
|
56
|
+
Dir.chdir(Rails.root) do
|
|
57
|
+
exec("node", gem_bin_path, *ARGV[1..])
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
# Pass through command-line arguments after the task name
|
|
61
|
+
# Use exec to replace the rake process with the export script
|
|
62
|
+
# This ensures proper exit codes and signal handling
|
|
63
|
+
Dir.chdir(Rails.root) do
|
|
64
|
+
exec(bin_path.to_s, *ARGV[1..])
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -2,16 +2,28 @@ install_template_path = File.expand_path("../../install/template.rb", __dir__).f
|
|
|
2
2
|
bin_path = ENV["BUNDLE_BIN"] || Rails.root.join("bin")
|
|
3
3
|
|
|
4
4
|
namespace :shakapacker do
|
|
5
|
-
desc "Install Shakapacker in this application"
|
|
6
|
-
task install: [:check_node] do |task|
|
|
5
|
+
desc "Install Shakapacker in this application (use SHAKAPACKER_ASSETS_BUNDLER=rspack for Rspack, --typescript for TypeScript)"
|
|
6
|
+
task :install, [:bundler, :typescript] => [:check_node] do |task, args|
|
|
7
7
|
Shakapacker::Configuration.installing = true
|
|
8
8
|
|
|
9
|
+
if args[:bundler] == "rspack" || ENV["SHAKAPACKER_ASSETS_BUNDLER"] == "rspack"
|
|
10
|
+
ENV["SHAKAPACKER_ASSETS_BUNDLER"] = "rspack"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Set typescript flag if passed as argument
|
|
14
|
+
# Accepts: typescript, true, or any truthy value
|
|
15
|
+
if args[:typescript] && args[:typescript] != "false"
|
|
16
|
+
ENV["SHAKAPACKER_USE_TYPESCRIPT"] = "true"
|
|
17
|
+
end
|
|
18
|
+
|
|
9
19
|
prefix = task.name.split(/#|shakapacker:install/).first
|
|
10
20
|
|
|
11
21
|
if Rails::VERSION::MAJOR >= 5
|
|
12
|
-
|
|
22
|
+
system "#{RbConfig.ruby} '#{bin_path}/rails' #{prefix}app:template LOCATION='#{install_template_path}'" or
|
|
23
|
+
raise "Installation failed"
|
|
13
24
|
else
|
|
14
|
-
|
|
25
|
+
system "#{RbConfig.ruby} '#{bin_path}/rake' #{prefix}rails:template LOCATION='#{install_template_path}'" or
|
|
26
|
+
raise "Installation failed"
|
|
15
27
|
end
|
|
16
28
|
end
|
|
17
29
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "shakapacker/swc_migrator"
|
|
2
|
+
|
|
3
|
+
namespace :shakapacker do
|
|
4
|
+
desc "Migrate from Babel to SWC transpiler"
|
|
5
|
+
task :migrate_to_swc do
|
|
6
|
+
Shakapacker::SwcMigrator.new(Rails.root).migrate_to_swc
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
desc "Remove Babel packages after migrating to SWC"
|
|
10
|
+
task :clean_babel_packages do
|
|
11
|
+
Shakapacker::SwcMigrator.new(Rails.root).clean_babel_packages
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require "shakapacker/bundler_switcher"
|
|
2
|
+
|
|
3
|
+
namespace :shakapacker do
|
|
4
|
+
desc <<~DESC
|
|
5
|
+
Switch between webpack and rspack bundlers
|
|
6
|
+
|
|
7
|
+
Easily switch your Shakapacker configuration between webpack and rspack bundlers.
|
|
8
|
+
This task updates config/shakapacker.yml and optionally manages npm dependencies.
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
bin/rake shakapacker:switch_bundler [webpack|rspack] -- [OPTIONS]
|
|
12
|
+
|
|
13
|
+
Options:
|
|
14
|
+
--install-deps Automatically install/uninstall bundler dependencies
|
|
15
|
+
--no-uninstall Skip uninstalling old bundler packages
|
|
16
|
+
--init-config Create custom dependencies configuration file
|
|
17
|
+
--help, -h Show detailed help message
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
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
|
|
24
|
+
|
|
25
|
+
What it does:
|
|
26
|
+
- Updates 'assets_bundler' in config/shakapacker.yml
|
|
27
|
+
- Preserves YAML comments and structure
|
|
28
|
+
- Updates 'javascript_transpiler' to 'swc' when switching to rspack
|
|
29
|
+
- With --install-deps: installs/uninstalls npm dependencies automatically
|
|
30
|
+
- Without: shows manual installation commands
|
|
31
|
+
|
|
32
|
+
Custom Dependencies:
|
|
33
|
+
Create .shakapacker-switch-bundler-dependencies.yml to customize which
|
|
34
|
+
npm packages are installed/uninstalled during bundler switching.
|
|
35
|
+
|
|
36
|
+
See docs/rspack_migration_guide.md for more information.
|
|
37
|
+
DESC
|
|
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
|
+
|
|
49
|
+
switcher = Shakapacker::BundlerSwitcher.new
|
|
50
|
+
|
|
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)
|
|
60
|
+
switcher.show_usage
|
|
61
|
+
elsif init_config
|
|
62
|
+
switcher.init_config
|
|
63
|
+
elsif bundler.nil? || bundler.start_with?("-")
|
|
64
|
+
switcher.show_usage
|
|
65
|
+
else
|
|
66
|
+
switcher.switch_to(bundler, install_deps: install_deps, no_uninstall: no_uninstall)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Prevent rake from trying to execute arguments as tasks
|
|
70
|
+
ARGV.each { |arg| task arg.to_sym {} }
|
|
71
|
+
end
|
|
72
|
+
end
|
data/lib/tasks/shakapacker.rake
CHANGED
|
@@ -9,6 +9,8 @@ tasks = {
|
|
|
9
9
|
"shakapacker:check_binstubs" => "Verifies that bin/shakapacker is present",
|
|
10
10
|
"shakapacker:binstubs" => "Installs Shakapacker binstubs in this application",
|
|
11
11
|
"shakapacker:verify_install" => "Verifies if Shakapacker is installed",
|
|
12
|
+
"shakapacker:doctor" => "Checks for configuration issues and missing dependencies",
|
|
13
|
+
"shakapacker:switch_bundler" => "Switch between webpack and rspack bundlers"
|
|
12
14
|
}.freeze
|
|
13
15
|
|
|
14
16
|
desc "Lists all available tasks in Shakapacker"
|
data/package/.npmignore
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { moduleExists, packageFullVersion } from "../utils/helpers"
|
|
2
|
+
import type { ConfigAPI, PluginItem } from "@babel/core"
|
|
3
|
+
|
|
4
|
+
const CORE_JS_VERSION_REGEX = /^\d+\.\d+/
|
|
5
|
+
|
|
6
|
+
const coreJsVersion = (): string => {
|
|
7
|
+
try {
|
|
8
|
+
const version = packageFullVersion("core-js").match(CORE_JS_VERSION_REGEX)
|
|
9
|
+
return version?.[0] ?? "3.8"
|
|
10
|
+
} catch (e) {
|
|
11
|
+
const error = e as NodeJS.ErrnoException
|
|
12
|
+
if (error.code !== "MODULE_NOT_FOUND") {
|
|
13
|
+
throw e
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return "3.8"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export = function config(api: ConfigAPI): {
|
|
21
|
+
presets: PluginItem[]
|
|
22
|
+
plugins: PluginItem[]
|
|
23
|
+
} {
|
|
24
|
+
const validEnv = ["development", "test", "production"]
|
|
25
|
+
const currentEnv = api.env()
|
|
26
|
+
const isDevelopmentEnv = api.env("development")
|
|
27
|
+
const isProductionEnv = api.env("production")
|
|
28
|
+
const isTestEnv = api.env("test")
|
|
29
|
+
|
|
30
|
+
if (!validEnv.includes(currentEnv)) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Please specify a valid NODE_ENV or BABEL_ENV environment variable. Valid values are "development", "test", and "production". Instead, received: "${currentEnv}".`
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const presets: PluginItem[] = [
|
|
37
|
+
isTestEnv && ["@babel/preset-env", { targets: { node: "current" } }],
|
|
38
|
+
(isProductionEnv || isDevelopmentEnv) && [
|
|
39
|
+
"@babel/preset-env",
|
|
40
|
+
{
|
|
41
|
+
useBuiltIns: "entry",
|
|
42
|
+
corejs: coreJsVersion(),
|
|
43
|
+
modules: "auto",
|
|
44
|
+
bugfixes: true,
|
|
45
|
+
exclude: ["transform-typeof-symbol"]
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
moduleExists("@babel/preset-typescript") && "@babel/preset-typescript"
|
|
49
|
+
].filter(Boolean) as PluginItem[]
|
|
50
|
+
|
|
51
|
+
const plugins: PluginItem[] = [
|
|
52
|
+
["@babel/plugin-transform-runtime", { helpers: false }]
|
|
53
|
+
].filter(Boolean) as PluginItem[]
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
presets,
|
|
57
|
+
plugins
|
|
58
|
+
}
|
|
59
|
+
}
|
data/package/config.ts
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { resolve } from "path"
|
|
2
|
+
import { load } from "js-yaml"
|
|
3
|
+
import { existsSync, readFileSync } from "fs"
|
|
4
|
+
import { merge } from "webpack-merge"
|
|
5
|
+
const { ensureTrailingSlash } = require("./utils/helpers")
|
|
6
|
+
const { railsEnv } = require("./env")
|
|
7
|
+
const configPath = require("./utils/configPath")
|
|
8
|
+
const defaultConfigPath = require("./utils/defaultConfigPath")
|
|
9
|
+
import { Config, YamlConfig } from "./types"
|
|
10
|
+
const {
|
|
11
|
+
isValidYamlConfig,
|
|
12
|
+
createConfigValidationError,
|
|
13
|
+
isPartialConfig
|
|
14
|
+
} = require("./utils/typeGuards")
|
|
15
|
+
const {
|
|
16
|
+
isFileNotFoundError,
|
|
17
|
+
createFileOperationError
|
|
18
|
+
} = require("./utils/errorHelpers")
|
|
19
|
+
|
|
20
|
+
const loadAndValidateYaml = (path: string): YamlConfig => {
|
|
21
|
+
const fileContent = readFileSync(path, "utf8")
|
|
22
|
+
const yamlContent = load(fileContent)
|
|
23
|
+
|
|
24
|
+
if (!isValidYamlConfig(yamlContent)) {
|
|
25
|
+
throw createConfigValidationError(path, railsEnv, "Invalid YAML structure")
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return yamlContent as YamlConfig
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const getDefaultConfig = (): Partial<Config> => {
|
|
32
|
+
try {
|
|
33
|
+
const defaultConfig = loadAndValidateYaml(defaultConfigPath)
|
|
34
|
+
return defaultConfig[railsEnv] || defaultConfig.production || {}
|
|
35
|
+
} catch (error) {
|
|
36
|
+
if (isFileNotFoundError(error)) {
|
|
37
|
+
throw createFileOperationError(
|
|
38
|
+
"read",
|
|
39
|
+
defaultConfigPath,
|
|
40
|
+
`Default configuration not found at ${defaultConfigPath}. Please ensure Shakapacker is properly installed. You may need to run 'yarn add shakapacker' or 'npm install shakapacker'.`
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
throw error
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const defaults = getDefaultConfig()
|
|
48
|
+
let config: Config
|
|
49
|
+
|
|
50
|
+
if (existsSync(configPath)) {
|
|
51
|
+
try {
|
|
52
|
+
const appYmlObject = loadAndValidateYaml(configPath)
|
|
53
|
+
|
|
54
|
+
const envAppConfig = appYmlObject[railsEnv]
|
|
55
|
+
|
|
56
|
+
if (!envAppConfig) {
|
|
57
|
+
console.warn(
|
|
58
|
+
`[SHAKAPACKER WARNING] Environment '${railsEnv}' not found in ${configPath}\n` +
|
|
59
|
+
`Available environments: ${Object.keys(appYmlObject).join(", ")}\n` +
|
|
60
|
+
`Using 'production' configuration as fallback.\n\n` +
|
|
61
|
+
`To fix this, either:\n` +
|
|
62
|
+
` - Add a '${railsEnv}' section to your shakapacker.yml\n` +
|
|
63
|
+
` - Set RAILS_ENV to one of the available environments\n` +
|
|
64
|
+
` - Copy settings from another environment as a starting point`
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Merge returns the merged type
|
|
69
|
+
const mergedConfig = merge(defaults, envAppConfig || {})
|
|
70
|
+
|
|
71
|
+
// Validate merged config before type assertion
|
|
72
|
+
if (!isPartialConfig(mergedConfig)) {
|
|
73
|
+
throw createConfigValidationError(
|
|
74
|
+
configPath,
|
|
75
|
+
railsEnv,
|
|
76
|
+
`Invalid configuration structure in ${configPath}. Please check your shakapacker.yml syntax and ensure all required fields are properly defined.`
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// After merging with defaults, config should be complete
|
|
81
|
+
// Use type assertion only after validation
|
|
82
|
+
config = mergedConfig as Config
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (isFileNotFoundError(error)) {
|
|
85
|
+
// File not found is OK, use defaults
|
|
86
|
+
if (!isPartialConfig(defaults)) {
|
|
87
|
+
throw createConfigValidationError(
|
|
88
|
+
defaultConfigPath,
|
|
89
|
+
railsEnv,
|
|
90
|
+
`Invalid default configuration. This may indicate a corrupted Shakapacker installation. Try reinstalling with 'yarn add shakapacker --force'.`
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
// Using defaults only, might be partial
|
|
94
|
+
config = defaults as Config
|
|
95
|
+
} else {
|
|
96
|
+
throw error
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
// No user config, use defaults
|
|
101
|
+
if (!isPartialConfig(defaults)) {
|
|
102
|
+
throw createConfigValidationError(
|
|
103
|
+
defaultConfigPath,
|
|
104
|
+
railsEnv,
|
|
105
|
+
`Invalid default configuration. This may indicate a corrupted Shakapacker installation. Try reinstalling with 'yarn add shakapacker --force'.`
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
// Using defaults only, might be partial
|
|
109
|
+
config = defaults as Config
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
config.outputPath = resolve(config.public_root_path, config.public_output_path)
|
|
113
|
+
|
|
114
|
+
if (config.private_output_path) {
|
|
115
|
+
config.privateOutputPath = resolve(config.private_output_path)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Ensure that the publicPath includes our asset host so dynamic imports
|
|
119
|
+
// (code-splitting chunks and static assets) load from the CDN instead of a relative path.
|
|
120
|
+
const getPublicPath = (): string => {
|
|
121
|
+
const rootUrl = ensureTrailingSlash(process.env.SHAKAPACKER_ASSET_HOST || "/")
|
|
122
|
+
return `${rootUrl}${config.public_output_path}/`
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
config.publicPath = getPublicPath()
|
|
126
|
+
config.publicPathWithoutCDN = `/${config.public_output_path}/`
|
|
127
|
+
|
|
128
|
+
if (config.manifest_path) {
|
|
129
|
+
config.manifestPath = resolve(config.manifest_path)
|
|
130
|
+
} else {
|
|
131
|
+
config.manifestPath = resolve(config.outputPath, "manifest.json")
|
|
132
|
+
}
|
|
133
|
+
// Ensure no duplicate hash functions exist in the returned config object
|
|
134
|
+
if (config.integrity?.hash_functions) {
|
|
135
|
+
config.integrity.hash_functions = [
|
|
136
|
+
...new Set(config.integrity.hash_functions)
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Ensure assets_bundler has a default value
|
|
141
|
+
if (!config.assets_bundler) {
|
|
142
|
+
config.assets_bundler = "webpack"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Allow ENV variable to override assets_bundler
|
|
146
|
+
if (process.env.SHAKAPACKER_ASSETS_BUNDLER) {
|
|
147
|
+
config.assets_bundler = process.env.SHAKAPACKER_ASSETS_BUNDLER
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Define clear defaults
|
|
151
|
+
// Keep Babel as default for webpack to maintain backward compatibility
|
|
152
|
+
// Use SWC for rspack as it's a newer bundler where we can set modern defaults
|
|
153
|
+
const DEFAULT_JAVASCRIPT_TRANSPILER =
|
|
154
|
+
config.assets_bundler === "rspack" ? "swc" : "babel"
|
|
155
|
+
|
|
156
|
+
// Backward compatibility: Check for webpack_loader using proper type guard
|
|
157
|
+
function hasWebpackLoader(
|
|
158
|
+
obj: unknown
|
|
159
|
+
): obj is Config & { webpack_loader: string } {
|
|
160
|
+
return (
|
|
161
|
+
typeof obj === "object" &&
|
|
162
|
+
obj !== null &&
|
|
163
|
+
"webpack_loader" in obj &&
|
|
164
|
+
typeof (obj as Record<string, unknown>).webpack_loader === "string"
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Allow environment variable to override javascript_transpiler
|
|
169
|
+
if (process.env.SHAKAPACKER_JAVASCRIPT_TRANSPILER) {
|
|
170
|
+
config.javascript_transpiler = process.env.SHAKAPACKER_JAVASCRIPT_TRANSPILER
|
|
171
|
+
} else if (hasWebpackLoader(config) && !config.javascript_transpiler) {
|
|
172
|
+
console.warn(
|
|
173
|
+
"[SHAKAPACKER DEPRECATION] The 'webpack_loader' configuration option is deprecated.\n" +
|
|
174
|
+
"Please use 'javascript_transpiler' instead as it better reflects its purpose of configuring JavaScript transpilation regardless of the bundler used."
|
|
175
|
+
)
|
|
176
|
+
config.javascript_transpiler = config.webpack_loader
|
|
177
|
+
} else if (!config.javascript_transpiler) {
|
|
178
|
+
config.javascript_transpiler = DEFAULT_JAVASCRIPT_TRANSPILER
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Ensure webpack_loader is always available for backward compatibility
|
|
182
|
+
Object.defineProperty(config, "webpack_loader", {
|
|
183
|
+
value: config.javascript_transpiler,
|
|
184
|
+
writable: true,
|
|
185
|
+
enumerable: true,
|
|
186
|
+
configurable: true
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
export = config
|