lib/sewing_kit/webpack/manifest.rb in sewing_kit-0.7.1 vs lib/sewing_kit/webpack/manifest.rb in sewing_kit-0.8.0
- old
+ new
@@ -1,73 +1,76 @@
+# frozen_string_literal: true
+require 'open3'
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
+ # Raised if the node sewing-kit isn't installed/runnable.
+ class NodeSewingKitNotRunnable < StandardError
+ def initialize(mode, cause)
+ env_message = if 'production' == mode
+ "\nIf this is a container build, try:\n" \
+ " - Adding `YARN_PRODUCTION=false` to your pipeline's environment variables\n" \
+ " - Adding the node buildpack: https://github.com/heroku/heroku-buildpack-nodejs"
+ else
+ "Try `yarn add --dev @shopify/sewing-kit`"
+ end
+
+ super(
+ "Could not fetch manifest because node sewing-kit is not runnable. " \
+ "#{env_message}\n" \
+ "Original error #{cause}"
+ )
+ end
+ end
+
+ # Raised if the node-generated manifest cannot be read from the filesystem.
class ManifestLoadError < StandardError
- def initialize(message, orig)
- super "#{message} (original error #{orig})"
+ def initialize(path, cause)
+ super "Could not load manifest from #{path} (original error #{cause})"
end
end
+ # Raised if the node-generated manifest returns unparseable JSON.
+ class ManifestParseError < StandardError
+ def initialize(cause)
+ super "Could not parse manifest JSON (original error #{cause})"
+ end
+ end
+
class LegacyManifestError < StandardError
def initialize(manifest)
super "manifest must contain 'entrypoints' key (found: #{manifest})"
end
end
class << self
# :nodoc:
- def asset_paths(entrypointName)
- metadata['entrypoints'][entrypointName]
+ def asset_paths(entrypoint_name)
+ instance.asset_paths(entrypoint_name)
end
def clear_cache!
- @metadata = nil
- @metadata_expiry_time = nil
+ @instance = nil
end
def manifest
- metadata['assets']
+ instance.manifest
end
- private
-
- def metadata
- if ::Rails.env.production?
- # Cache at class level, as JSON loading/parsing can be expensive.
- @metadata ||= load_metadata
+ def instance
+ return @instance if @instance
+ @instance = if Rails.env.development? && ENV['SK_SIMULATE_PRODUCTION'] != '1'
+ Development.new
else
- # In development, the manifest may change.
- # A short cache lifetime avoids time consuming node callouts.
- if self.instance_variable_defined?('@metadata_expiry_time') && @metadata_expiry_time && @metadata_expiry_time >= Time.now
- @metadata
- else
- @metadata = load_metadata
- @metadata_expiry_time = Time.now + 4
- end
+ Production.new
end
-
- raise LegacyManifestError.new(@metadata) if !@metadata['entrypoints']
-
- @metadata
end
-
- def manifest_bundled?
- !manifest["errors"].any? { |error| error.include? "Module build failed" }
- end
-
- def load_metadata
- 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
+
+require 'sewing_kit/webpack/manifest/development'
+require 'sewing_kit/webpack/manifest/production'