require 'uri' module SewingKit module Webpack # Webpack manifest loading, caching & entry point retrieval 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 class << self # :nodoc: def asset_paths(source) paths = manifest[source] paths || {} end def clear_cache! @manifest = nil @manifest_expiry_time = nil end def manifest if ::Rails.env.production? # Cache at class level, as JSON loading/parsing can be expensive. @manifest ||= load_manifest else # In development, the manifest may change. # A short cache lifetime avoids time consuming node callouts. if self.instance_variable_defined?('@manifest_expiry_time') && @manifest_expiry_time && @manifest_expiry_time >= Time.now @manifest else @manifest = load_manifest @manifest_expiry_time = Time.now + 4 end end @manifest end private def manifest_bundled? !manifest["errors"].any? { |error| error.include? "Module build failed" } end def load_manifest JSON.parse(`node_modules/.bin/sewing-kit manifest --mode #{mode}`) rescue => e raise ManifestLoadError.new("Could not load compiled manifest - have you run `rake sewing_kit:build`?", e) end def mode ENV['NODE_ENV'] || Rails.env.to_s || 'production' end end end end end