Guides

Rails: Webpack compile once for parallel tests

When we use gem parallel_tests our application in test environment used, for example, 8 parallel processes. But webpacker compiling the same files at the same time in each process. This is bad and can lead to unexpected errors.

Also when assets did not change, we do not want to spend time compiling them.

For solving this problem we can use next configuration module.
Place the following into features/support/webpacker.rb.


module WebpackerTest
  TS_FILE = Rails.root.join('tmp', "webpacker-#{Rails.env}-timestamp")

  def self.compile
    return unless timestamp_outdated?

    if ENV['TEST_ENV_NUMBER'].to_i < 1
      public_output_path = Webpacker.config.public_output_path
      FileUtils.rm_r(public_output_path) if File.exist?(public_output_path)

      puts "Webpack is removed from output directory #{public_output_path}"
      puts 'Compiling, please wait'

      Webpacker.compile

      File.open(TS_FILE, 'w') { |f| f.write(Time.now.utc.to_i) }
      sleep 1
    else
      loop do
        break unless timestamp_outdated?
        sleep 0.1
      end
    end
  end

  def self.timestamp_outdated?
    return true unless File.exist?(TS_FILE)

    current = current_bundle_timestamp(TS_FILE)

    return true unless current

    expected = Dir[Webpacker.config.source_path.join('**', '*')].map do |f|
      File.mtime(f).utc.to_i
    end.max

    current < expected
  end

  def self.current_bundle_timestamp(file)
    return File.read(file).to_i
  rescue StandardError
    nil
  end
end

WebpackerTest.compile