class Webpacker::Compiler

Attributes

webpacker[R]

Public Class Methods

new(webpacker) click to toggle source
# File lib/webpacker/compiler.rb, line 17
def initialize(webpacker)
  @webpacker = webpacker
end

Public Instance Methods

compile() click to toggle source
# File lib/webpacker/compiler.rb, line 21
def compile
  if stale?
    run_webpack.tap do |success|
      # We used to only record the digest on success
      # However, the output file is still written on error, meaning that the digest should still be updated.
      # If it's not, you can end up in a situation where a recompile doesn't take place when it should.
      # See https://github.com/rails/webpacker/issues/2113
      record_compilation_digest
    end
  else
    logger.debug "Everything's up-to-date. Nothing to do"
    true
  end
end
fresh?() click to toggle source

Returns true if all the compiled packs are up to date with the underlying asset files.

# File lib/webpacker/compiler.rb, line 37
def fresh?
  last_compilation_digest&.== watched_files_digest
end
stale?() click to toggle source

Returns true if the compiled packs are out of date with the underlying asset files.

# File lib/webpacker/compiler.rb, line 42
def stale?
  !fresh?
end

Private Instance Methods

compilation_digest_path() click to toggle source
# File lib/webpacker/compiler.rb, line 119
def compilation_digest_path
  config.cache_path.join("last-compilation-digest-#{webpacker.env}")
end
default_watched_paths() click to toggle source
# File lib/webpacker/compiler.rb, line 110
def default_watched_paths
  [
    *config.additional_paths.map { |path| "#{path}/**/*" },
    "#{config.source_path}/**/*",
    "yarn.lock", "package.json",
    "config/webpack/**/*"
  ].freeze
end
last_compilation_digest() click to toggle source
# File lib/webpacker/compiler.rb, line 49
def last_compilation_digest
  compilation_digest_path.read if compilation_digest_path.exist? && config.manifest_path.exist?
rescue Errno::ENOENT, Errno::ENOTDIR
end
optionalRubyRunner() click to toggle source
# File lib/webpacker/compiler.rb, line 80
def optionalRubyRunner
  bin_webpack_path = config.root_path.join("bin/webpacker")
  first_line = File.readlines(bin_webpack_path).first.chomp
  /ruby/.match?(first_line) ? RbConfig.ruby : ""
end
record_compilation_digest() click to toggle source
# File lib/webpacker/compiler.rb, line 75
def record_compilation_digest
  config.cache_path.mkpath
  compilation_digest_path.write(watched_files_digest)
end
run_webpack() click to toggle source
# File lib/webpacker/compiler.rb, line 86
def run_webpack
  logger.info "Compiling..."

  stdout, stderr, status = Open3.capture3(
    webpack_env,
    "#{optionalRubyRunner} ./bin/webpacker",
    chdir: File.expand_path(config.root_path)
  )

  if status.success?
    logger.info "Compiled all packs in #{config.public_output_path}"
    logger.error "#{stderr}" unless stderr.empty?

    if config.webpack_compile_output?
      logger.info stdout
    end
  else
    non_empty_streams = [stdout, stderr].delete_if(&:empty?)
    logger.error "\nCOMPILATION FAILED:\nEXIT STATUS: #{status}\nOUTPUTS:\n#{non_empty_streams.join("\n\n")}"
  end

  status.success?
end
watched_files_digest() click to toggle source
# File lib/webpacker/compiler.rb, line 54
    def watched_files_digest
      if Rails.env.development?
        warn <<~MSG.strip
          Webpacker::Compiler - Slow setup for development

          Prepare JS assets with either:
          1. Running `bin/webpacker-dev-server`
          2. Set `compile` to false in webpacker.yml and run `bin/webpacker -w`
        MSG
      end

      warn "Webpacker::Compiler.watched_paths has been deprecated. Set additional_paths in webpacker.yml instead." unless watched_paths.empty?
      root_path = Pathname.new(File.expand_path(config.root_path))
      expanded_paths = [*default_watched_paths, *watched_paths].map do |path|
        root_path.join(path)
      end
      files = Dir[*expanded_paths].reject { |f| File.directory?(f) }
      file_ids = files.sort.map { |f| "#{File.basename(f)}/#{Digest::SHA1.file(f).hexdigest}" }
      Digest::SHA1.hexdigest(file_ids.join("/"))
    end
webpack_env() click to toggle source
# File lib/webpacker/compiler.rb, line 123
def webpack_env
  return env unless defined?(ActionController::Base)

  env.merge("WEBPACKER_ASSET_HOST"        => ENV.fetch("WEBPACKER_ASSET_HOST", ActionController::Base.helpers.compute_asset_host),
            "WEBPACKER_RELATIVE_URL_ROOT" => ENV.fetch("WEBPACKER_RELATIVE_URL_ROOT", ActionController::Base.relative_url_root),
            "WEBPACKER_CONFIG" => webpacker.config_path.to_s)
end