Class: Shakapacker::Doctor

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

Defined Under Namespace

Classes: Reporter

Constant Summary collapse

CATEGORY_ACTION_REQUIRED =

Warning categories for better organization

:action_required
:recommended
CATEGORY_INFO =
:info
REQUIRED_BINSTUBS =
{
  "bin/shakapacker" => "Main Shakapacker binstub",
  "bin/shakapacker-dev-server" => "Development server binstub",
  "bin/shakapacker-config" => "Config export binstub"
}.freeze
OPTIONAL_BINSTUBS =
%w[
  bin/shakapacker-watch
  bin/diff-bundler-config
].freeze
PACKAGE_MANAGER_LOCKFILES =
{
  "bun.lockb" => "bun",
  "pnpm-lock.yaml" => "pnpm",
  "yarn.lock" => "yarn",
  "package-lock.json" => "npm"
}.freeze
SASS_IMPLEMENTATION_PACKAGES =
%w[
  sass
  sass-embedded
].freeze
SASS_IMPLEMENTATION_DEPENDENCY_MESSAGE =
(
  "Missing required dependency 'sass' or 'sass-embedded' " \
  "for Sass/SCSS implementation"
).freeze
REQUIRED_RSPACK_DEPS =
{
  "@rspack/core" => "^2.0.0",
  "@rspack/cli" => "^2.0.0",
  "rspack-manifest-plugin" => "^5.2.2"
}.freeze
RSPACK_DEV_SERVER_DEP =
{
  "@rspack/dev-server" => "^2.0.0"
}.freeze
RSPACK_V2_ONLY_DEPS =
REQUIRED_RSPACK_DEPS
.slice("@rspack/core", "@rspack/cli")
.merge(RSPACK_DEV_SERVER_DEP)
.freeze
OPTIONAL_RSPACK_V2_ONLY_DEPS =
{
  "@rspack/plugin-react-refresh" => "^2.0.0"
}.freeze
RSPACK_REACT_REFRESH_PACKAGE =
"@rspack/plugin-react-refresh".freeze
VERSION_UPPER_BOUND_OPERATORS =
%w[< <=].freeze
CUSTOM_HYBRID_LOADER_DEPS =
%w[
  babel-loader
  esbuild-loader
  ts-loader
].freeze
BUNDLER_CONFIG_EXTENSIONS =
%w[
  ts
  js
].freeze
PACKAGE_ROOT_MARKERS =
(["package.json"] + PACKAGE_MANAGER_LOCKFILES.keys + ["node_modules"]).freeze
RSPACK_SWC_OVERRIDE_HINT =

generateRspackConfig merges with plain webpack-merge merge (package/rspack/index.ts), which concatenates module.rules, so an override handed to it is appended next to the built-in rule rather than replacing it. mergeWithRules must be applied to its output.

"Apply webpack-merge's 'mergeWithRules' to the output of generateRspackConfig() in your Rspack config, " \
"matching on both 'test' and 'use.loader', and using options: 'merge' (not 'replace', which swaps the whole " \
"options object and drops the built-in parser and transform.react defaults). " \
"Keep 'test' in the match: matching on 'use.loader' alone makes webpack-merge append 'builtin:swc-loader' to " \
"every rule's 'use' chain, including the CSS and Sass rules. " \
"Override the JS (/\\.(js|jsx|mjs)$/) and TypeScript (/\\.(ts|tsx)$/) rules separately, since Shakapacker " \
"registers a 'builtin:swc-loader' rule for each. " \
"Passing an override into generateRspackConfig() cannot replace the built-in rule, because it merges with " \
"plain 'merge', which concatenates 'module.rules' and leaves the built-in 'builtin:swc-loader' rule in place " \
"alongside yours. Shakapacker re-exports 'mergeWithRules'. " \
"See: https://github.com/shakacode/shakapacker/blob/main/docs/rspack.md".freeze
RSPACK_SWC_OVERRIDE_HINT_BACKREF =
"See the Rspack 'builtin:swc-loader' override guidance above.".freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = nil, root_path = nil, options = {}) ⇒ Doctor

Returns a new instance of Doctor.



97
98
99
100
101
102
103
104
# File 'lib/shakapacker/doctor.rb', line 97

def initialize(config = nil, root_path = nil, options = {})
  @config = config || Shakapacker.config
  @root_path = root_path || (defined?(Rails) ? Rails.root : Pathname.new(Dir.pwd))
  @issues = []
  @warnings = []  # Now stores hashes: { category: :symbol, message: "..." }
  @info = []
  @options = options
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



8
9
10
# File 'lib/shakapacker/doctor.rb', line 8

def config
  @config
end

#infoObject (readonly)

Returns the value of attribute info.



8
9
10
# File 'lib/shakapacker/doctor.rb', line 8

def info
  @info
end

#issuesObject (readonly)

Returns the value of attribute issues.



8
9
10
# File 'lib/shakapacker/doctor.rb', line 8

def issues
  @issues
end

#optionsObject (readonly)

Returns the value of attribute options.



8
9
10
# File 'lib/shakapacker/doctor.rb', line 8

def options
  @options
end

#root_pathObject (readonly)

Returns the value of attribute root_path.



8
9
10
# File 'lib/shakapacker/doctor.rb', line 8

def root_path
  @root_path
end

#warningsObject (readonly)

Returns the value of attribute warnings.



8
9
10
# File 'lib/shakapacker/doctor.rb', line 8

def warnings
  @warnings
end

Instance Method Details

#runObject



106
107
108
109
110
111
112
113
114
# File 'lib/shakapacker/doctor.rb', line 106

def run
  if options[:help]
    print_help
    return
  end

  perform_checks
  report_results
end

#success?Boolean

Returns:

  • (Boolean)


116
117
118
# File 'lib/shakapacker/doctor.rb', line 116

def success?
  @issues.empty?
end