Class: ReactOnRailsPro::AssetsPrecompile

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/react_on_rails_pro/assets_precompile.rb

Overview

rubocop:disable Metrics/ClassLength

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.callObject



63
64
65
66
67
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 63

def self.call
  instance.build_or_fetch_bundles

  ReactOnRailsPro::PrepareNodeRenderBundles.call if ReactOnRailsPro.configuration.node_renderer?
end

Instance Method Details

#build_bundlesObject



56
57
58
59
60
61
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 56

def build_bundles
  remote_bundle_cache_adapter.build
rescue RuntimeError
  ReactOnRailsPro::Utils.rorp_puts "The custom config.remote_bundle_cache_adapter 'build' method raised an error:"
  raise
end

#build_or_fetch_bundlesObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 69

def build_or_fetch_bundles
  if disable_precompile_cache?
    build_bundles
    return
  end

  begin
    bundles_fetched = fetch_and_unzip_cached_bundles
  rescue RuntimeError => e
    ReactOnRailsPro::Utils.rorp_puts "An error occurred while attempting to fetch cached bundles."
    ReactOnRailsPro::Utils.rorp_puts "This will be evaluated as a bundle cache miss."
    ReactOnRailsPro::Utils.rorp_puts e.message
    puts e.backtrace.join('\n')
    bundles_fetched = false
  end

  return if bundles_fetched

  build_bundles

  begin
    cache_bundles
  rescue RuntimeError => e
    ReactOnRailsPro::Utils.rorp_puts "An error occurred while attempting to cache the built bundles."
    ReactOnRailsPro::Utils.rorp_puts e.message
    puts e.backtrace.join('\n')
  end
end

#bundles_cache_keyObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 27

def bundles_cache_key
  @bundles_cache_key ||=
    begin
      ReactOnRailsPro::Utils.rorp_puts "Calculating digest of bundle dependencies."
      starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      cache_dependencies = [Shakapacker.config.source_path.join("**", "*")]
                           .union(ReactOnRailsPro.configuration.dependency_globs)
      # Note, digest_of_globs removes excluded globs
      digest = ReactOnRailsPro::Utils.digest_of_globs(cache_dependencies)
      # Include the NODE_ENV in the digest
      env_cache_keys = [
        ReactOnRailsPro::VERSION,
        ENV.fetch("RAILS_ENV", nil),
        ENV.fetch("NODE_ENV", nil)
      ]

      if remote_bundle_cache_adapter.respond_to?(:cache_keys)
        env_cache_keys += remote_bundle_cache_adapter.cache_keys
      end
      env_cache_keys.compact.each { |value| digest.update(value) }

      result = digest.hexdigest
      ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      elapsed = (ending - starting).round(2)
      ReactOnRailsPro::Utils.rorp_puts "Completed calculating digest of bundle dependencies in #{elapsed} seconds."
      result
    end
end

#cache_bundlesObject



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 196

def cache_bundles
  begin
    copy_extra_files_to_cache_dir
    public_output_path = Shakapacker.config.public_output_path
    ReactOnRailsPro::Utils.rorp_puts "Gzipping built bundles to #{zipped_bundles_filepath} with " \
                                     "files in #{public_output_path}"
    Dir.chdir(public_output_path) do
      Rake.sh "tar -czf #{zipped_bundles_filepath} --auto-compress -C " \
              "#{Shakapacker.config.public_output_path} ."
    end
  rescue StandardError => e
    ReactOnRailsPro::Utils.rorp_puts "An error occurred while attempting to zip the built bundles."
    ReactOnRailsPro::Utils.rorp_puts e.message
    puts e.backtrace.join('\n')
  ensure
    remove_extra_files_cache_dir
  end

  ReactOnRailsPro::Utils.rorp_puts "Bundles will be uploaded to remote bundle cache as #{zipped_bundles_filename}"

  begin
    remote_bundle_cache_adapter.upload(zipped_bundles_filepath)
  rescue RuntimeError
    message = "An error was raised by the custom config.remote_bundle_cache_adapter 'upload' " \
              "method when called with zipped_bundles_filepath: #{zipped_bundles_filepath}"
    ReactOnRailsPro::Utils.rorp_puts message
    raise
  end
end

#convert_to_destination(source) ⇒ Object



174
175
176
177
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 174

def convert_to_destination(source)
  new_file_name = source.relative_path_from(Rails.root).each_filename.to_a.join("---")
  extra_files_path.join(new_file_name)
end

#copy_extra_files_to_cache_dirObject



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 150

def copy_extra_files_to_cache_dir
  return unless remote_bundle_cache_adapter.respond_to?(:extra_files_to_cache)

  FileUtils.mkdir_p(extra_files_path)
  copied_extra_files_paths = []

  remote_bundle_cache_adapter.extra_files_to_cache.each do |file_path|
    if file_path.file?
      copy_file_to_extra_files_cache_dir(file_path)
      copied_extra_files_paths.push(file_path.relative_path_from(Rails.root).to_s)
    else
      ReactOnRailsPro::Utils.rorp_puts "Extra file: #{file_path}, doesn't exist. Skipping"
    end
  end

  ReactOnRailsPro::Utils.rorp_puts "Copied extra files: #{copied_extra_files_paths.join(', ')} " \
                                   "to extra_files cache dir"
end

#copy_file_to_extra_files_cache_dir(source_path) ⇒ Object



169
170
171
172
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 169

def copy_file_to_extra_files_cache_dir(source_path)
  destination_file_path = convert_to_destination(source_path)
  FileUtils.cp(source_path, destination_file_path)
end

#disable_precompile_cache?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 98

def disable_precompile_cache?
  ENV["DISABLE_PRECOMPILE_CACHE"] == "true"
end

#extra_files_pathObject



146
147
148
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 146

def extra_files_path
  Rails.root.join(Shakapacker.config.public_output_path, "extra_files")
end

#extract_extra_files_from_cache_dirObject



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 179

def extract_extra_files_from_cache_dir
  return unless File.exist?(extra_files_path)

  extracted_extra_files_paths = []
  Dir.each_child(extra_files_path) do |file_name|
    file_path_parts = file_name.split("---")
    source_file_path = extra_files_path.join(file_name)
    destination_file_path = Rails.root.join(*file_path_parts)
    FileUtils.mv(source_file_path, destination_file_path)
    extracted_extra_files_paths.push(destination_file_path.relative_path_from(Rails.root).to_s)
  end

  ReactOnRailsPro::Utils.rorp_puts "Extracted extra files: #{extracted_extra_files_paths.join(', ')} " \
                                   "from extra_files cache dir"
  remove_extra_files_cache_dir
end

#fetch_and_unzip_cached_bundlesObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 123

def fetch_and_unzip_cached_bundles
  if File.exist?(zipped_bundles_filepath)
    ReactOnRailsPro::Utils.rorp_puts "Found a local cache of bundles: #{zipped_bundles_filepath}"
    result = true
  else
    result = fetch_bundles
  end

  if File.exist?(zipped_bundles_filepath)
    ReactOnRailsPro::Utils.rorp_puts "gunzipping bundle cache: #{zipped_bundles_filepath}"
    public_output_path = Shakapacker.config.public_output_path
    FileUtils.mkdir_p(public_output_path)
    Dir.chdir(public_output_path) do
      Rake.sh "tar -xzf #{zipped_bundles_filepath}"
    end

    ReactOnRailsPro::Utils.rorp_puts "gunzipped bundle cache: #{zipped_bundles_filepath} to #{public_output_path}"

    extract_extra_files_from_cache_dir
  end
  result
end

#fetch_bundlesObject



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 102

def fetch_bundles
  ReactOnRailsPro::Utils.rorp_puts "Checking for a cached bundle: #{zipped_bundles_filename}"
  begin
    fetch_result = remote_bundle_cache_adapter.fetch(zipped_bundles_filename)
  rescue RuntimeError
    message = "An error was raised by the custom config.remote_bundle_cache_adapter 'fetch' " \
              "method when called with { zipped_bundles_filename: #{zipped_bundles_filename} }"
    ReactOnRailsPro::Utils.rorp_puts message
    raise
  end

  if fetch_result
    ReactOnRailsPro::Utils.rorp_puts "Remote bundle cache detected. Bundles will be restored to local cache."
    File.binwrite(zipped_bundles_filepath, fetch_result)
    true
  else
    ReactOnRailsPro::Utils.rorp_puts "Remote bundle cache not found."
    false
  end
end

#remote_bundle_cache_adapterObject



7
8
9
10
11
12
13
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 7

def remote_bundle_cache_adapter
  unless ReactOnRailsPro.configuration.remote_bundle_cache_adapter.is_a?(Module)
    raise ReactOnRailsPro::Error, "config.remote_bundle_cache_adapter must have a module assigned"
  end

  ReactOnRailsPro.configuration.remote_bundle_cache_adapter
end

#remove_extra_files_cache_dirObject



226
227
228
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 226

def remove_extra_files_cache_dir
  FileUtils.rm_f(extra_files_path)
end

#zipped_bundles_filenameObject



15
16
17
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 15

def zipped_bundles_filename
  "precompile-cache.#{bundles_cache_key}.production.gz"
end

#zipped_bundles_filepathObject



19
20
21
22
23
24
25
# File 'lib/react_on_rails_pro/assets_precompile.rb', line 19

def zipped_bundles_filepath
  @zipped_bundles_filepath ||=
    begin
      FileUtils.mkdir_p(Rails.root.join("tmp", "bundle_cache"))
      Rails.root.join("tmp", "bundle_cache", zipped_bundles_filename)
    end
end