sprockets 3.7.3 → 4.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +77 -259
- data/{LICENSE → MIT-LICENSE} +2 -2
- data/README.md +527 -320
- data/bin/sprockets +11 -7
- data/lib/rake/sprocketstask.rb +9 -4
- data/lib/sprockets/add_source_map_comment_to_asset_processor.rb +60 -0
- data/lib/sprockets/asset.rb +39 -27
- data/lib/sprockets/autoload/babel.rb +8 -0
- data/lib/sprockets/autoload/closure.rb +1 -0
- data/lib/sprockets/autoload/coffee_script.rb +1 -0
- data/lib/sprockets/autoload/eco.rb +1 -0
- data/lib/sprockets/autoload/ejs.rb +1 -0
- data/lib/sprockets/autoload/jsminc.rb +8 -0
- data/lib/sprockets/autoload/sass.rb +1 -0
- data/lib/sprockets/autoload/sassc.rb +8 -0
- data/lib/sprockets/autoload/uglifier.rb +1 -0
- data/lib/sprockets/autoload/yui.rb +1 -0
- data/lib/sprockets/autoload/zopfli.rb +7 -0
- data/lib/sprockets/autoload.rb +5 -0
- data/lib/sprockets/babel_processor.rb +66 -0
- data/lib/sprockets/base.rb +49 -12
- data/lib/sprockets/bower.rb +6 -3
- data/lib/sprockets/bundle.rb +41 -5
- data/lib/sprockets/cache/file_store.rb +25 -3
- data/lib/sprockets/cache/memory_store.rb +28 -10
- data/lib/sprockets/cache/null_store.rb +8 -0
- data/lib/sprockets/cache.rb +37 -2
- data/lib/sprockets/cached_environment.rb +15 -20
- data/lib/sprockets/closure_compressor.rb +1 -0
- data/lib/sprockets/coffee_script_processor.rb +19 -5
- data/lib/sprockets/compressing.rb +43 -3
- data/lib/sprockets/configuration.rb +5 -9
- data/lib/sprockets/context.rb +99 -25
- data/lib/sprockets/dependencies.rb +2 -1
- data/lib/sprockets/digest_utils.rb +35 -18
- data/lib/sprockets/directive_processor.rb +64 -38
- data/lib/sprockets/eco_processor.rb +2 -1
- data/lib/sprockets/ejs_processor.rb +2 -1
- data/lib/sprockets/encoding_utils.rb +2 -2
- data/lib/sprockets/environment.rb +9 -4
- data/lib/sprockets/erb_processor.rb +33 -32
- data/lib/sprockets/errors.rb +1 -0
- data/lib/sprockets/exporters/base.rb +71 -0
- data/lib/sprockets/exporters/file_exporter.rb +24 -0
- data/lib/sprockets/exporters/zlib_exporter.rb +33 -0
- data/lib/sprockets/exporters/zopfli_exporter.rb +14 -0
- data/lib/sprockets/exporting.rb +73 -0
- data/lib/sprockets/file_reader.rb +1 -0
- data/lib/sprockets/http_utils.rb +25 -7
- data/lib/sprockets/jsminc_compressor.rb +32 -0
- data/lib/sprockets/jst_processor.rb +11 -10
- data/lib/sprockets/loader.rb +91 -69
- data/lib/sprockets/manifest.rb +67 -64
- data/lib/sprockets/manifest_utils.rb +9 -6
- data/lib/sprockets/mime.rb +8 -62
- data/lib/sprockets/npm.rb +52 -0
- data/lib/sprockets/path_dependency_utils.rb +3 -11
- data/lib/sprockets/path_digest_utils.rb +2 -1
- data/lib/sprockets/path_utils.rb +88 -8
- data/lib/sprockets/paths.rb +1 -0
- data/lib/sprockets/preprocessors/default_source_map.rb +49 -0
- data/lib/sprockets/processing.rb +32 -62
- data/lib/sprockets/processor_utils.rb +28 -38
- data/lib/sprockets/resolve.rb +177 -93
- data/lib/sprockets/sass_cache_store.rb +2 -6
- data/lib/sprockets/sass_compressor.rb +13 -1
- data/lib/sprockets/sass_functions.rb +1 -0
- data/lib/sprockets/sass_importer.rb +1 -0
- data/lib/sprockets/sass_processor.rb +31 -10
- data/lib/sprockets/sassc_compressor.rb +56 -0
- data/lib/sprockets/sassc_processor.rb +297 -0
- data/lib/sprockets/server.rb +63 -40
- data/lib/sprockets/source_map_processor.rb +66 -0
- data/lib/sprockets/source_map_utils.rb +483 -0
- data/lib/sprockets/transformers.rb +63 -35
- data/lib/sprockets/uglifier_compressor.rb +21 -11
- data/lib/sprockets/unloaded_asset.rb +13 -11
- data/lib/sprockets/uri_tar.rb +1 -0
- data/lib/sprockets/uri_utils.rb +19 -16
- data/lib/sprockets/utils/gzip.rb +46 -14
- data/lib/sprockets/utils.rb +64 -90
- data/lib/sprockets/version.rb +2 -1
- data/lib/sprockets/yui_compressor.rb +1 -0
- data/lib/sprockets.rb +102 -39
- metadata +148 -45
- data/lib/sprockets/coffee_script_template.rb +0 -17
- data/lib/sprockets/deprecation.rb +0 -90
- data/lib/sprockets/eco_template.rb +0 -17
- data/lib/sprockets/ejs_template.rb +0 -17
- data/lib/sprockets/engines.rb +0 -92
- data/lib/sprockets/erb_template.rb +0 -11
- data/lib/sprockets/legacy.rb +0 -330
- data/lib/sprockets/legacy_proc_processor.rb +0 -35
- data/lib/sprockets/legacy_tilt_processor.rb +0 -29
- data/lib/sprockets/sass_template.rb +0 -19
@@ -1,42 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'erb'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
4
|
+
class Sprockets::ERBProcessor
|
5
|
+
# Public: Return singleton instance with default options.
|
6
|
+
#
|
7
|
+
# Returns ERBProcessor object.
|
8
|
+
def self.instance
|
9
|
+
@instance ||= new
|
10
|
+
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
def self.call(input)
|
13
|
+
instance.call(input)
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def initialize(&block)
|
17
|
+
@block = block
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
context = input[:environment].context_class.new(input)
|
28
|
-
klass = (class << context; self; end)
|
29
|
-
klass.class_eval(&@block) if @block
|
30
|
-
engine.def_method(klass, :_evaluate_template, input[:filename])
|
31
|
-
data = context._evaluate_template
|
32
|
-
context.metadata.merge(data: data)
|
20
|
+
def call(input)
|
21
|
+
if keyword_constructor? # Ruby 2.6+
|
22
|
+
engine = ::ERB.new(input[:data], trim_mode: '<>')
|
23
|
+
else
|
24
|
+
engine = ::ERB.new(input[:data], nil, '<>')
|
33
25
|
end
|
26
|
+
engine.filename = input[:filename]
|
34
27
|
|
35
|
-
|
28
|
+
context = input[:environment].context_class.new(input)
|
29
|
+
klass = (class << context; self; end)
|
30
|
+
klass.const_set(:ENV, context.env_proxy)
|
31
|
+
klass.class_eval(&@block) if @block
|
36
32
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
data = engine.result(context.instance_eval('binding'))
|
34
|
+
context.metadata.merge(data: data)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def keyword_constructor?
|
40
|
+
return @keyword_constructor if defined? @keyword_constructor
|
41
|
+
@keyword_constructor = ::ERB.instance_method(:initialize).parameters.include?([:key, :trim_mode])
|
41
42
|
end
|
42
43
|
end
|
data/lib/sprockets/errors.rb
CHANGED
@@ -0,0 +1,71 @@
|
|
1
|
+
module Sprockets
|
2
|
+
module Exporters
|
3
|
+
# Convenience class for all exporters to inherit from
|
4
|
+
#
|
5
|
+
# An exporter is responsible for exporting a Sprockets::Asset
|
6
|
+
# to a file system. For example the Exporters::File class
|
7
|
+
# writes the asset to it's destination. The Exporters::Zlib class
|
8
|
+
# writes a gzip copy of the asset to disk.
|
9
|
+
class Base
|
10
|
+
attr_reader :asset, :environment, :directory, :target
|
11
|
+
|
12
|
+
# Public: Creates new instance
|
13
|
+
#
|
14
|
+
# Initialize will be called with
|
15
|
+
# keyword arguments:
|
16
|
+
#
|
17
|
+
# - asset: An instance of Sprockets::Asset.
|
18
|
+
# - environment: An instance of Sprockets::Environment.
|
19
|
+
# - directory: String representing the target directory to write to.
|
20
|
+
#
|
21
|
+
# These will all be stored as accessible values. In addition a
|
22
|
+
# +target+ will be available which is the target directory and
|
23
|
+
# the asset's digest path combined.
|
24
|
+
def initialize(asset: nil, environment: nil, directory: nil)
|
25
|
+
@asset = asset
|
26
|
+
@environment = environment
|
27
|
+
@directory = directory
|
28
|
+
@target = ::File.join(directory, asset.digest_path)
|
29
|
+
setup
|
30
|
+
end
|
31
|
+
|
32
|
+
# Public: Callback that is executed after initialization
|
33
|
+
#
|
34
|
+
# Any setup that needs to be done can be performed in the +setup+
|
35
|
+
# method. It will be called immediately after initialization.
|
36
|
+
def setup
|
37
|
+
end
|
38
|
+
|
39
|
+
# Public: Handles logic for skipping exporter and notifying logger
|
40
|
+
#
|
41
|
+
# The `skip?` will be called before anything will be written.
|
42
|
+
# If `skip?` returns truthy it will not continue. This method
|
43
|
+
# takes a `logger` that responds to +debug+ and +info+. The `skip?`
|
44
|
+
# method is the only place expected to write to a logger, any other
|
45
|
+
# messages may produce jumbled logs.
|
46
|
+
def skip?(logger)
|
47
|
+
false
|
48
|
+
end
|
49
|
+
|
50
|
+
# Public: Contains logic for writing "exporting" asset to disk
|
51
|
+
#
|
52
|
+
# If the exporter is not skipped it then Sprockets will execute it's
|
53
|
+
# `call` method. This method takes no arguments and should only use
|
54
|
+
# elements passed in via initialize or stored in `setup`.
|
55
|
+
def call
|
56
|
+
raise "Must subclass and implement call"
|
57
|
+
end
|
58
|
+
|
59
|
+
# Public: Yields a file that can be written to with the input
|
60
|
+
#
|
61
|
+
# `filename`. Defaults to the `target`. Method
|
62
|
+
# is safe to use in forked or threaded environments.
|
63
|
+
def write(filename = target)
|
64
|
+
FileUtils.mkdir_p File.dirname(filename)
|
65
|
+
PathUtils.atomic_write(filename) do |f|
|
66
|
+
yield f
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'sprockets/exporters/base'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
module Exporters
|
5
|
+
# Writes a an asset file to disk
|
6
|
+
class FileExporter < Exporters::Base
|
7
|
+
def skip?(logger)
|
8
|
+
if ::File.exist?(target)
|
9
|
+
logger.debug "Skipping #{ target }, already exists"
|
10
|
+
true
|
11
|
+
else
|
12
|
+
logger.info "Writing #{ target }"
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
write(target) do |file|
|
19
|
+
file.write(asset.source)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'sprockets/exporters/base'
|
2
|
+
require 'sprockets/utils/gzip'
|
3
|
+
|
4
|
+
module Sprockets
|
5
|
+
module Exporters
|
6
|
+
# Generates a `.gz` file using the zlib algorithm built into
|
7
|
+
# Ruby's standard library.
|
8
|
+
class ZlibExporter < Exporters::Base
|
9
|
+
def setup
|
10
|
+
@gzip_target = "#{ target }.gz"
|
11
|
+
@gzip = Sprockets::Utils::Gzip.new(asset, archiver: Utils::Gzip::ZlibArchiver)
|
12
|
+
end
|
13
|
+
|
14
|
+
def skip?(logger)
|
15
|
+
return true if environment.skip_gzip?
|
16
|
+
return true if @gzip.cannot_compress?
|
17
|
+
if ::File.exist?(@gzip_target)
|
18
|
+
logger.debug "Skipping #{ @gzip_target }, already exists"
|
19
|
+
true
|
20
|
+
else
|
21
|
+
logger.info "Writing #{ @gzip_target }"
|
22
|
+
false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def call
|
27
|
+
write(@gzip_target) do |file|
|
28
|
+
@gzip.compress(file, target)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'sprockets/exporters/zlib_exporter'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
module Exporters
|
5
|
+
# Generates a `.gz` file using the zopfli algorithm from the
|
6
|
+
# Zopfli gem.
|
7
|
+
class ZopfliExporter < ZlibExporter
|
8
|
+
def setup
|
9
|
+
@gzip_target = "#{ target }.gz"
|
10
|
+
@gzip = Sprockets::Utils::Gzip.new(asset, archiver: Utils::Gzip::ZopfliArchiver)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Sprockets
|
2
|
+
# `Exporting` is an internal mixin whose public methods are exposed on
|
3
|
+
# the `Environment` and `CachedEnvironment` classes.
|
4
|
+
module Exporting
|
5
|
+
# Exporters are ran on the assets:precompile task
|
6
|
+
def exporters
|
7
|
+
config[:exporters]
|
8
|
+
end
|
9
|
+
|
10
|
+
# Public: Registers a new Exporter `klass` for `mime_type`.
|
11
|
+
#
|
12
|
+
# If your exporter depends on one or more other exporters you can
|
13
|
+
# specify this via the `depend_on` keyword.
|
14
|
+
#
|
15
|
+
# register_exporter '*/*', Sprockets::Exporters::ZlibExporter
|
16
|
+
#
|
17
|
+
# This ensures that `Sprockets::Exporters::File` will always execute before
|
18
|
+
# `Sprockets::Exporters::Zlib`
|
19
|
+
def register_exporter(mime_types, klass = nil)
|
20
|
+
mime_types = Array(mime_types)
|
21
|
+
|
22
|
+
mime_types.each do |mime_type|
|
23
|
+
self.config = hash_reassoc(config, :exporters, mime_type) do |_exporters|
|
24
|
+
_exporters << klass
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Public: Remove Exporting processor `klass` for `mime_type`.
|
30
|
+
#
|
31
|
+
# environment.unregister_exporter '*/*', Sprockets::Exporters::ZlibExporter
|
32
|
+
#
|
33
|
+
# Can be called without a mime type
|
34
|
+
#
|
35
|
+
# environment.unregister_exporter Sprockets::Exporters::ZlibExporter
|
36
|
+
#
|
37
|
+
# Does not remove any exporters that depend on `klass`.
|
38
|
+
def unregister_exporter(mime_types, exporter = nil)
|
39
|
+
unless mime_types.is_a? Array
|
40
|
+
if mime_types.is_a? String
|
41
|
+
mime_types = [mime_types]
|
42
|
+
else # called with no mime type
|
43
|
+
exporter = mime_types
|
44
|
+
mime_types = nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
self.config = hash_reassoc(config, :exporters) do |_exporters|
|
49
|
+
_exporters.each do |mime_type, exporters_array|
|
50
|
+
next if mime_types && !mime_types.include?(mime_type)
|
51
|
+
if exporters_array.include? exporter
|
52
|
+
_exporters[mime_type] = exporters_array.dup.delete exporter
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Public: Checks if concurrent exporting is allowed
|
59
|
+
def export_concurrent
|
60
|
+
config[:export_concurrent]
|
61
|
+
end
|
62
|
+
|
63
|
+
# Public: Enable or disable the concurrently exporting files
|
64
|
+
#
|
65
|
+
# Defaults to true.
|
66
|
+
#
|
67
|
+
# environment.export_concurrent = false
|
68
|
+
#
|
69
|
+
def export_concurrent=(export_concurrent)
|
70
|
+
self.config = config.merge(export_concurrent: export_concurrent).freeze
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/sprockets/http_utils.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Sprockets
|
2
3
|
# Internal: HTTP URI utilities. Many adapted from Rack::Utils. Mixed into
|
3
4
|
# Environment.
|
@@ -13,9 +14,9 @@ module Sprockets
|
|
13
14
|
# Returns true if the given value is a mime match for the given mime match
|
14
15
|
# specification, false otherwise.
|
15
16
|
def match_mime_type?(value, matcher)
|
16
|
-
v1, v2 = value.split('/', 2)
|
17
|
-
m1, m2 = matcher.split('/', 2)
|
18
|
-
(m1 == '*' || v1 == m1) && (m2.nil? || m2 == '*' || m2 == v2)
|
17
|
+
v1, v2 = value.split('/'.freeze, 2)
|
18
|
+
m1, m2 = matcher.split('/'.freeze, 2)
|
19
|
+
(m1 == '*'.freeze || v1 == m1) && (m2.nil? || m2 == '*'.freeze || m2 == v2)
|
19
20
|
end
|
20
21
|
|
21
22
|
# Public: Return values from Hash where the key matches the mime type.
|
@@ -36,7 +37,22 @@ module Sprockets
|
|
36
37
|
|
37
38
|
# Internal: Parse Accept header quality values.
|
38
39
|
#
|
39
|
-
#
|
40
|
+
# values - String e.g. "application/javascript"
|
41
|
+
#
|
42
|
+
# Adapted from Rack::Utils#q_values. Quality values are
|
43
|
+
# described in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
44
|
+
#
|
45
|
+
# parse_q_values("application/javascript")
|
46
|
+
# # => [["application/javascript", 1.0]]
|
47
|
+
#
|
48
|
+
# parse_q_values("*/*")
|
49
|
+
# # => [["*/*", 1.0]]
|
50
|
+
#
|
51
|
+
# parse_q_values("text/plain; q=0.5, image/*")
|
52
|
+
# # => [["text/plain", 0.5], ["image/*", 1.0]]
|
53
|
+
#
|
54
|
+
# parse_q_values("application/javascript, text/css")
|
55
|
+
# # => [["application/javascript", 1.0], ["text/css", 1.0]]
|
40
56
|
#
|
41
57
|
# Returns an Array of [String, Float].
|
42
58
|
def parse_q_values(values)
|
@@ -70,14 +86,16 @@ module Sprockets
|
|
70
86
|
raise TypeError, "unknown q_values type: #{q_values.class}"
|
71
87
|
end
|
72
88
|
|
89
|
+
i = 0
|
73
90
|
q_values.each do |accepted, quality|
|
74
91
|
if match = available.find { |option| matcher.call(option, accepted) }
|
75
|
-
|
92
|
+
i += 1
|
93
|
+
matches << [-quality, i, match]
|
76
94
|
end
|
77
95
|
end
|
78
96
|
|
79
|
-
matches.
|
80
|
-
matches.map! { |
|
97
|
+
matches.sort!
|
98
|
+
matches.map! { |_, _, match| match }
|
81
99
|
matches
|
82
100
|
end
|
83
101
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'sprockets/autoload'
|
3
|
+
require 'sprockets/digest_utils'
|
4
|
+
|
5
|
+
module Sprockets
|
6
|
+
class JSMincCompressor
|
7
|
+
VERSION = '1'
|
8
|
+
|
9
|
+
def self.instance
|
10
|
+
@instance ||= new
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.call(input)
|
14
|
+
instance.call(input)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.cache_key
|
18
|
+
instance.cache_key
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :cache_key
|
22
|
+
|
23
|
+
def initialize(options = {})
|
24
|
+
@compressor_class = Autoload::JSMinC
|
25
|
+
@cache_key = "#{self.class.name}:#{Autoload::JSMinC::VERSION}:#{VERSION}:#{DigestUtils.digest(options)}".freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
def call(input)
|
29
|
+
@compressor_class.minify(input[:data])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,21 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Sprockets
|
2
|
-
# Public:
|
3
|
+
# Public: JST transformer.
|
3
4
|
#
|
4
5
|
# Exports server side compiled templates to an object.
|
5
6
|
#
|
6
|
-
# Name your template "users/show.
|
7
|
+
# Name your template "users/show.ejs", "users/new.eco", etc.
|
7
8
|
#
|
8
9
|
# To accept the default options
|
9
10
|
#
|
10
|
-
# environment.
|
11
|
-
#
|
12
|
-
#
|
11
|
+
# environment.register_transformer
|
12
|
+
# 'application/javascript+function',
|
13
|
+
# 'application/javascript', JstProcessor
|
13
14
|
#
|
14
15
|
# Change the default namespace.
|
15
16
|
#
|
16
|
-
# environment.
|
17
|
-
#
|
18
|
-
#
|
17
|
+
# environment.register_transformer
|
18
|
+
# 'application/javascript+function',
|
19
|
+
# 'application/javascript', JstProcessor.new(namespace: 'App.templates')
|
19
20
|
#
|
20
21
|
class JstProcessor
|
21
22
|
def self.default_namespace
|
@@ -33,8 +34,8 @@ module Sprockets
|
|
33
34
|
instance.call(input)
|
34
35
|
end
|
35
36
|
|
36
|
-
def initialize(
|
37
|
-
@namespace =
|
37
|
+
def initialize(namespace: self.class.default_namespace)
|
38
|
+
@namespace = namespace
|
38
39
|
end
|
39
40
|
|
40
41
|
def call(input)
|