114 lines
4 KiB
Ruby
114 lines
4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'net/http'
|
|
require 'uri'
|
|
|
|
module Gitlab
|
|
module Webpack
|
|
class Manifest
|
|
# Raised if we can't read our webpack manifest for whatever reason
|
|
class ManifestLoadError < StandardError
|
|
def initialize(message, orig)
|
|
super "#{message} (original error #{orig})"
|
|
end
|
|
end
|
|
|
|
# Raised if webpack couldn't build one of your entry points
|
|
class WebpackError < StandardError
|
|
def initialize(errors)
|
|
super "Error in webpack compile, details follow below:\n#{errors.join("\n\n")}"
|
|
end
|
|
end
|
|
|
|
# Raised if a supplied entry point does not exist in the webpack manifest
|
|
AssetMissingError = Class.new(StandardError)
|
|
|
|
class << self
|
|
def entrypoint_paths(source)
|
|
raise WebpackError, manifest["errors"] unless manifest_bundled?
|
|
|
|
dll_assets = manifest.fetch("dllAssets", [])
|
|
entrypoint = manifest["entrypoints"][source]
|
|
if entrypoint && entrypoint["assets"]
|
|
# Can be either a string or an array of strings.
|
|
# Do not include source maps as they are not javascript
|
|
[dll_assets, entrypoint["assets"]].flatten.reject { |p| p =~ /.*\.map$/ }.map do |p|
|
|
"/#{::Rails.configuration.webpack.public_path}/#{p}"
|
|
end
|
|
else
|
|
raise AssetMissingError, "Can't find asset '#{source}' in webpack manifest"
|
|
end
|
|
end
|
|
|
|
def asset_paths(source)
|
|
raise WebpackError, manifest["errors"] unless manifest_bundled?
|
|
|
|
paths = manifest["assetsByChunkName"][source]
|
|
if paths
|
|
# Can be either a string or an array of strings.
|
|
# Do not include source maps as they are not javascript
|
|
[paths].flatten.reject { |p| p =~ /.*\.map$/ }.map do |p|
|
|
"/#{::Rails.configuration.webpack.public_path}/#{p}"
|
|
end
|
|
else
|
|
raise AssetMissingError, "Can't find entry point '#{source}' in webpack manifest"
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def manifest_bundled?
|
|
!manifest["errors"].any? { |error| error.include? "Module build failed" }
|
|
end
|
|
|
|
def manifest
|
|
if ::Rails.configuration.webpack.dev_server.enabled
|
|
# Don't cache if we're in dev server mode, manifest may change ...
|
|
load_manifest
|
|
else
|
|
# ... otherwise cache at class level, as JSON loading/parsing can be expensive
|
|
@manifest ||= load_manifest
|
|
end
|
|
end
|
|
|
|
def load_manifest
|
|
data = if ::Rails.configuration.webpack.dev_server.enabled
|
|
load_dev_server_manifest
|
|
else
|
|
load_static_manifest
|
|
end
|
|
|
|
Gitlab::Json.parse(data)
|
|
end
|
|
|
|
def load_dev_server_manifest
|
|
host = ::Rails.configuration.webpack.dev_server.host
|
|
port = ::Rails.configuration.webpack.dev_server.port
|
|
http = Net::HTTP.new(host, port)
|
|
http.use_ssl = ::Rails.configuration.webpack.dev_server.https
|
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
http.get(dev_server_path).body
|
|
rescue => e
|
|
raise ManifestLoadError.new("Could not load manifest from webpack-dev-server at http://#{host}:#{port}#{dev_server_path} - is it running, and is stats-webpack-plugin loaded?", e)
|
|
end
|
|
|
|
def load_static_manifest
|
|
File.read(static_manifest_path)
|
|
rescue => e
|
|
raise ManifestLoadError.new("Could not load compiled manifest from #{static_manifest_path} - have you run `rake webpack:compile`?", e)
|
|
end
|
|
|
|
def static_manifest_path
|
|
::Rails.root.join(
|
|
::Rails.configuration.webpack.output_dir,
|
|
::Rails.configuration.webpack.manifest_filename
|
|
)
|
|
end
|
|
|
|
def dev_server_path
|
|
"/#{::Rails.configuration.webpack.public_path}/#{::Rails.configuration.webpack.manifest_filename}"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|