sprockets 3.7.2 → 4.2.0

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.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -261
  3. data/{LICENSE → MIT-LICENSE} +2 -2
  4. data/README.md +527 -320
  5. data/bin/sprockets +11 -7
  6. data/lib/rake/sprocketstask.rb +9 -4
  7. data/lib/sprockets/add_source_map_comment_to_asset_processor.rb +60 -0
  8. data/lib/sprockets/asset.rb +39 -27
  9. data/lib/sprockets/autoload/babel.rb +8 -0
  10. data/lib/sprockets/autoload/closure.rb +1 -0
  11. data/lib/sprockets/autoload/coffee_script.rb +1 -0
  12. data/lib/sprockets/autoload/eco.rb +1 -0
  13. data/lib/sprockets/autoload/ejs.rb +1 -0
  14. data/lib/sprockets/autoload/jsminc.rb +8 -0
  15. data/lib/sprockets/autoload/sass.rb +1 -0
  16. data/lib/sprockets/autoload/sassc.rb +8 -0
  17. data/lib/sprockets/autoload/uglifier.rb +1 -0
  18. data/lib/sprockets/autoload/yui.rb +1 -0
  19. data/lib/sprockets/autoload/zopfli.rb +7 -0
  20. data/lib/sprockets/autoload.rb +5 -0
  21. data/lib/sprockets/babel_processor.rb +66 -0
  22. data/lib/sprockets/base.rb +49 -12
  23. data/lib/sprockets/bower.rb +6 -3
  24. data/lib/sprockets/bundle.rb +41 -5
  25. data/lib/sprockets/cache/file_store.rb +25 -3
  26. data/lib/sprockets/cache/memory_store.rb +28 -10
  27. data/lib/sprockets/cache/null_store.rb +8 -0
  28. data/lib/sprockets/cache.rb +37 -2
  29. data/lib/sprockets/cached_environment.rb +15 -20
  30. data/lib/sprockets/closure_compressor.rb +1 -0
  31. data/lib/sprockets/coffee_script_processor.rb +19 -5
  32. data/lib/sprockets/compressing.rb +43 -3
  33. data/lib/sprockets/configuration.rb +5 -9
  34. data/lib/sprockets/context.rb +99 -25
  35. data/lib/sprockets/dependencies.rb +2 -1
  36. data/lib/sprockets/digest_utils.rb +35 -18
  37. data/lib/sprockets/directive_processor.rb +64 -36
  38. data/lib/sprockets/eco_processor.rb +2 -1
  39. data/lib/sprockets/ejs_processor.rb +2 -1
  40. data/lib/sprockets/encoding_utils.rb +1 -0
  41. data/lib/sprockets/environment.rb +9 -4
  42. data/lib/sprockets/erb_processor.rb +34 -21
  43. data/lib/sprockets/errors.rb +1 -0
  44. data/lib/sprockets/exporters/base.rb +71 -0
  45. data/lib/sprockets/exporters/file_exporter.rb +24 -0
  46. data/lib/sprockets/exporters/zlib_exporter.rb +33 -0
  47. data/lib/sprockets/exporters/zopfli_exporter.rb +14 -0
  48. data/lib/sprockets/exporting.rb +73 -0
  49. data/lib/sprockets/file_reader.rb +1 -0
  50. data/lib/sprockets/http_utils.rb +25 -7
  51. data/lib/sprockets/jsminc_compressor.rb +32 -0
  52. data/lib/sprockets/jst_processor.rb +11 -10
  53. data/lib/sprockets/loader.rb +88 -68
  54. data/lib/sprockets/manifest.rb +67 -64
  55. data/lib/sprockets/manifest_utils.rb +9 -6
  56. data/lib/sprockets/mime.rb +8 -42
  57. data/lib/sprockets/npm.rb +52 -0
  58. data/lib/sprockets/path_dependency_utils.rb +3 -11
  59. data/lib/sprockets/path_digest_utils.rb +2 -1
  60. data/lib/sprockets/path_utils.rb +88 -8
  61. data/lib/sprockets/paths.rb +1 -0
  62. data/lib/sprockets/preprocessors/default_source_map.rb +49 -0
  63. data/lib/sprockets/processing.rb +32 -62
  64. data/lib/sprockets/processor_utils.rb +28 -38
  65. data/lib/sprockets/resolve.rb +177 -93
  66. data/lib/sprockets/sass_cache_store.rb +2 -6
  67. data/lib/sprockets/sass_compressor.rb +13 -1
  68. data/lib/sprockets/sass_functions.rb +1 -0
  69. data/lib/sprockets/sass_importer.rb +1 -0
  70. data/lib/sprockets/sass_processor.rb +31 -10
  71. data/lib/sprockets/sassc_compressor.rb +56 -0
  72. data/lib/sprockets/sassc_processor.rb +297 -0
  73. data/lib/sprockets/server.rb +52 -39
  74. data/lib/sprockets/source_map_processor.rb +66 -0
  75. data/lib/sprockets/source_map_utils.rb +483 -0
  76. data/lib/sprockets/transformers.rb +63 -35
  77. data/lib/sprockets/uglifier_compressor.rb +21 -11
  78. data/lib/sprockets/unloaded_asset.rb +13 -11
  79. data/lib/sprockets/uri_tar.rb +1 -0
  80. data/lib/sprockets/uri_utils.rb +12 -9
  81. data/lib/sprockets/utils/gzip.rb +46 -14
  82. data/lib/sprockets/utils.rb +64 -89
  83. data/lib/sprockets/version.rb +2 -1
  84. data/lib/sprockets/yui_compressor.rb +1 -0
  85. data/lib/sprockets.rb +102 -39
  86. metadata +139 -34
  87. data/lib/sprockets/coffee_script_template.rb +0 -17
  88. data/lib/sprockets/deprecation.rb +0 -90
  89. data/lib/sprockets/eco_template.rb +0 -17
  90. data/lib/sprockets/ejs_template.rb +0 -17
  91. data/lib/sprockets/engines.rb +0 -92
  92. data/lib/sprockets/erb_template.rb +0 -11
  93. data/lib/sprockets/legacy.rb +0 -330
  94. data/lib/sprockets/legacy_proc_processor.rb +0 -35
  95. data/lib/sprockets/legacy_tilt_processor.rb +0 -29
  96. data/lib/sprockets/sass_template.rb +0 -19
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'sprockets/uri_utils'
2
3
  require 'sprockets/uri_tar'
3
4
 
@@ -12,8 +13,8 @@ module Sprockets
12
13
  # and full path such as
13
14
  # "file:///Path/app/assets/js/app.js?type=application/javascript"
14
15
  # env - The current "environment" that assets are being loaded into.
15
- # We need it so we know where the +root+ (directory where sprockets
16
- # is being invoked). We also need for the `file_digest` method,
16
+ # We need it so we know where the +root+ (directory where Sprockets
17
+ # is being invoked). We also need it for the `file_digest` method,
17
18
  # since, for some strange reason, memoization is provided by
18
19
  # overriding methods such as `stat` in the `PathUtils` module.
19
20
  #
@@ -30,7 +31,7 @@ module Sprockets
30
31
  # Internal: Full file path without schema
31
32
  #
32
33
  # This returns a string containing the full path to the asset without the schema.
33
- # Information is loaded lazilly since we want `UnloadedAsset.new(dep, self).relative_path`
34
+ # Information is loaded lazily since we want `UnloadedAsset.new(dep, self).relative_path`
34
35
  # to be fast. Calling this method the first time allocates an array and a hash.
35
36
  #
36
37
  # Example
@@ -48,8 +49,8 @@ module Sprockets
48
49
 
49
50
  # Internal: Hash of param values
50
51
  #
51
- # This information is generated and used internally by sprockets.
52
- # Known keys include `:type` which store the asset's mime-type, `:id` which is a fully resolved
52
+ # This information is generated and used internally by Sprockets.
53
+ # Known keys include `:type` which stores the asset's mime-type, `:id` which is a fully resolved
53
54
  # digest for the asset (includes dependency digest as opposed to a digest of only file contents)
54
55
  # and `:pipeline`. Hash may be empty.
55
56
  #
@@ -79,12 +80,12 @@ module Sprockets
79
80
 
80
81
  # Public: Dependency History key
81
82
  #
82
- # Used to retrieve an array of "histories" each of which contain a set of stored dependencies
83
+ # Used to retrieve an array of "histories" each of which contains a set of stored dependencies
83
84
  # for a given asset path and filename digest.
84
85
  #
85
- # A dependency can refer to either an asset i.e. index.js
86
+ # A dependency can refer to either an asset e.g. index.js
86
87
  # may rely on jquery.js (so jquery.js is a dependency), or other factors that may affect
87
- # compilation, such as the VERSION of sprockets (i.e. the environment) and what "processors"
88
+ # compilation, such as the VERSION of Sprockets (i.e. the environment) and what "processors"
88
89
  # are used.
89
90
  #
90
91
  # For example a history array with one Set of dependencies may look like:
@@ -97,7 +98,7 @@ module Sprockets
97
98
  # This method of asset lookup is used to ensure that none of the dependencies have been modified
98
99
  # since last lookup. If one of them has, the key will be different and a new entry must be stored.
99
100
  #
100
- # URI depndencies are later converted to "compressed" paths
101
+ # URI dependencies are later converted to "compressed" paths
101
102
  #
102
103
  # Returns a String.
103
104
  def dependency_history_key
@@ -108,8 +109,9 @@ module Sprockets
108
109
  #
109
110
  # Used to retrieve a string containing the "compressed" path to an asset based on
110
111
  # a digest. The digest is generated from dependencies stored via information stored in
111
- # the `dependency_history_key` after each of the "dependencies" is "resolved" for example
112
- # "environment-version" may be resolved to "environment-1.0-3.2.0" for version "3.2.0" of sprockets
112
+ # the `dependency_history_key` after each of the "dependencies" is "resolved".
113
+ # For example "environment-version" may be resolved to "environment-1.0-3.2.0"
114
+ # for version "3.2.0" of Sprockets
113
115
  #
114
116
  # Returns a String.
115
117
  def digest_key(digest)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'sprockets/path_utils'
2
3
 
3
4
  module Sprockets
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'uri'
2
3
 
3
4
  module Sprockets
@@ -47,19 +48,21 @@ module Sprockets
47
48
  path = URI::Generic::DEFAULT_PARSER.unescape(path)
48
49
  path.force_encoding(Encoding::UTF_8)
49
50
 
50
- # Hack for parsing Windows "file:///C:/Users/IEUser" paths
51
- path.gsub!(/^\/([a-zA-Z]:)/, '\1'.freeze)
51
+ # Hack for parsing Windows "/C:/Users/IEUser" paths
52
+ if File::ALT_SEPARATOR && path[2] == ':'
53
+ path = path[1..-1]
54
+ end
52
55
 
53
- [scheme, host, path, query]
56
+ [scheme, host || '', path, query]
54
57
  end
55
58
 
56
59
  # Internal: Join file: URI component parts into String.
57
60
  #
58
61
  # Returns String.
59
62
  def join_file_uri(scheme, host, path, query)
60
- str = "#{scheme}://"
63
+ str = +"#{scheme}://"
61
64
  str << host if host
62
- path = "/#{path}" unless path.start_with?("/")
65
+ path = "/#{path}" unless path.start_with?("/".freeze)
63
66
  str << URI::Generic::DEFAULT_PARSER.escape(path)
64
67
  str << "?#{query}" if query
65
68
  str
@@ -72,7 +75,7 @@ module Sprockets
72
75
  # Returns true or false.
73
76
  def valid_asset_uri?(str)
74
77
  # Quick prefix check before attempting a full parse
75
- str.start_with?("file://") && parse_asset_uri(str) ? true : false
78
+ str.start_with?("file://".freeze) && parse_asset_uri(str) ? true : false
76
79
  rescue URI::InvalidURIError
77
80
  false
78
81
  end
@@ -168,7 +171,7 @@ module Sprockets
168
171
  end
169
172
  end
170
173
 
171
- "#{query.join('&')}" if query.any?
174
+ "#{query.join('&'.freeze)}" if query.any?
172
175
  end
173
176
 
174
177
  # Internal: Parse query string into hash of params
@@ -177,8 +180,8 @@ module Sprockets
177
180
  #
178
181
  # Return Hash of params.
179
182
  def parse_uri_query_params(query)
180
- query.to_s.split('&').reduce({}) do |h, p|
181
- k, v = p.split('=', 2)
183
+ query.to_s.split('&'.freeze).reduce({}) do |h, p|
184
+ k, v = p.split('='.freeze, 2)
182
185
  v = URI::Generic::DEFAULT_PARSER.unescape(v) if v
183
186
  h[k.to_sym] = v || true
184
187
  h
@@ -1,11 +1,50 @@
1
+ # frozen_string_literal: true
1
2
  module Sprockets
2
3
  module Utils
3
4
  class Gzip
5
+ # Private: Generates a gzipped file based off of reference asset.
6
+ #
7
+ # ZlibArchiver.call(file, source, mtime)
8
+ #
9
+ # Compresses a given `source` using stdlib Zlib algorithm
10
+ # writes contents to the `file` passed in. Sets `mtime` of
11
+ # written file to passed in `mtime`
12
+ module ZlibArchiver
13
+ def self.call(file, source, mtime)
14
+ gz = Zlib::GzipWriter.new(file, Zlib::BEST_COMPRESSION)
15
+ gz.mtime = mtime
16
+ gz.write(source)
17
+ gz.close
18
+
19
+ File.utime(mtime, mtime, file.path)
20
+ end
21
+ end
22
+
23
+ # Private: Generates a gzipped file based off of reference asset.
24
+ #
25
+ # ZopfliArchiver.call(file, source, mtime)
26
+ #
27
+ # Compresses a given `source` using the zopfli gem
28
+ # writes contents to the `file` passed in. Sets `mtime` of
29
+ # written file to passed in `mtime`
30
+ module ZopfliArchiver
31
+ def self.call(file, source, mtime)
32
+ compressed_source = Autoload::Zopfli.deflate(source, format: :gzip, mtime: mtime)
33
+ file.write(compressed_source)
34
+ file.close
35
+
36
+ nil
37
+ end
38
+ end
39
+
40
+ attr_reader :content_type, :source, :charset, :archiver
41
+
4
42
  # Private: Generates a gzipped file based off of reference file.
5
- def initialize(asset)
43
+ def initialize(asset, archiver: ZlibArchiver)
6
44
  @content_type = asset.content_type
7
45
  @source = asset.source
8
46
  @charset = asset.charset
47
+ @archiver = archiver
9
48
  end
10
49
 
11
50
  # What non-text mime types should we compress? This list comes from:
@@ -26,7 +65,7 @@ module Sprockets
26
65
  # through a compression algorithm would make them larger.
27
66
  #
28
67
  # Return Boolean.
29
- def can_compress?(mime_types)
68
+ def can_compress?
30
69
  # The "charset" of a mime type is present if the value is
31
70
  # encoded text. We can check this value to see if the asset
32
71
  # can be compressed.
@@ -38,8 +77,8 @@ module Sprockets
38
77
  # Private: Opposite of `can_compress?`.
39
78
  #
40
79
  # Returns Boolean.
41
- def cannot_compress?(mime_types)
42
- !can_compress?(mime_types)
80
+ def cannot_compress?
81
+ !can_compress?
43
82
  end
44
83
 
45
84
  # Private: Generates a gzipped file based off of reference asset.
@@ -49,16 +88,9 @@ module Sprockets
49
88
  # Does not modify the target asset.
50
89
  #
51
90
  # Returns nothing.
52
- def compress(target)
53
- mtime = PathUtils.stat(target).mtime
54
- PathUtils.atomic_write("#{target}.gz") do |f|
55
- gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
56
- gz.mtime = mtime
57
- gz.write(@source)
58
- gz.close
59
-
60
- File.utime(mtime, mtime, f.path)
61
- end
91
+ def compress(file, target)
92
+ mtime = Sprockets::PathUtils.stat(target).mtime
93
+ archiver.call(file, source, mtime)
62
94
 
63
95
  nil
64
96
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'set'
2
3
 
3
4
  module Sprockets
@@ -14,21 +15,17 @@ module Sprockets
14
15
  #
15
16
  # Returns false if .dup would raise a TypeError, otherwise true.
16
17
  def duplicable?(obj)
17
- if RUBY_VERSION >= "2.4.0"
18
- true
18
+ case obj
19
+ when NilClass, FalseClass, TrueClass, Symbol, Numeric
20
+ false
19
21
  else
20
- case obj
21
- when NilClass, FalseClass, TrueClass, Symbol, Numeric
22
- false
23
- else
24
- true
25
- end
22
+ true
26
23
  end
27
24
  end
28
25
 
29
26
  # Internal: Duplicate and store key/value on new frozen hash.
30
27
  #
31
- # Seperated for recursive calls, always use hash_reassoc(hash, *keys).
28
+ # Separated for recursive calls, always use hash_reassoc(hash, *keys).
32
29
  #
33
30
  # hash - Hash
34
31
  # key - Object key
@@ -49,7 +46,8 @@ module Sprockets
49
46
  # Similar to Hash#store for nested frozen hashes.
50
47
  #
51
48
  # hash - Hash
52
- # key - Object keys. Use multiple keys for nested hashes.
49
+ # key_a - Object key. Use multiple keys for nested hashes.
50
+ # key_b - Object key. Use multiple keys for nested hashes.
53
51
  # block - Receives current value at key.
54
52
  #
55
53
  # Examples
@@ -60,16 +58,19 @@ module Sprockets
60
58
  # end
61
59
  #
62
60
  # Returns duplicated frozen Hash.
63
- def hash_reassoc(hash, *keys, &block)
64
- if keys.size == 1
65
- hash_reassoc1(hash, keys[0], &block)
66
- else
67
- hash_reassoc1(hash, keys[0]) do |value|
68
- hash_reassoc(value, *keys[1..-1], &block)
61
+ def hash_reassoc(hash, key_a, key_b = nil, &block)
62
+ if key_b
63
+ hash_reassoc1(hash, key_a) do |value|
64
+ hash_reassoc(value, key_b, &block)
69
65
  end
66
+ else
67
+ hash_reassoc1(hash, key_a, &block)
70
68
  end
71
69
  end
72
70
 
71
+ WHITESPACE_ORDINALS = {0x0A => "\n", 0x20 => " ", 0x09 => "\t"}
72
+ private_constant :WHITESPACE_ORDINALS
73
+
73
74
  # Internal: Check if string has a trailing semicolon.
74
75
  #
75
76
  # str - String
@@ -81,14 +82,9 @@ module Sprockets
81
82
  c = str[i].ord
82
83
  i -= 1
83
84
 
84
- # Need to compare against the ordinals because the string can be UTF_8 or UTF_32LE encoded
85
- # 0x0A == "\n"
86
- # 0x20 == " "
87
- # 0x09 == "\t"
88
- # 0x3B == ";"
89
- unless c == 0x0A || c == 0x20 || c == 0x09
90
- return c === 0x3B
91
- end
85
+ next if WHITESPACE_ORDINALS[c]
86
+
87
+ return c === 0x3B
92
88
  end
93
89
 
94
90
  true
@@ -102,50 +98,28 @@ module Sprockets
102
98
  #
103
99
  # Returns buf String.
104
100
  def concat_javascript_sources(buf, source)
105
- if source.bytesize > 0
106
- buf << source
107
-
108
- # If the source contains non-ASCII characters, indexing on it becomes O(N).
109
- # This will lead to O(N^2) performance in string_end_with_semicolon?, so we should use 32 bit encoding to make sure indexing stays O(1)
110
- source = source.encode(Encoding::UTF_32LE) unless source.ascii_only?
111
-
112
- if !string_end_with_semicolon?(source)
113
- buf << ";\n"
114
- elsif source[source.size - 1].ord != 0x0A
115
- buf << "\n"
116
- end
101
+ return buf if source.bytesize <= 0
102
+
103
+ buf << source
104
+ # If the source contains non-ASCII characters, indexing on it becomes O(N).
105
+ # This will lead to O(N^2) performance in string_end_with_semicolon?, so we should use 32 bit encoding to make sure indexing stays O(1)
106
+ source = source.encode(Encoding::UTF_32LE) unless source.ascii_only?
107
+ return buf if string_end_with_semicolon?(source)
108
+
109
+ # If the last character in the string was whitespace,
110
+ # such as a newline, then we want to put the semicolon
111
+ # before the whitespace. Otherwise append a semicolon.
112
+ if whitespace = WHITESPACE_ORDINALS[source[-1].ord]
113
+ buf[-1] = ";#{whitespace}"
114
+ else
115
+ buf << ";"
117
116
  end
118
117
 
119
118
  buf
120
119
  end
121
120
 
122
- # Internal: Prepends a leading "." to an extension if its missing.
123
- #
124
- # normalize_extension("js")
125
- # # => ".js"
126
- #
127
- # normalize_extension(".css")
128
- # # => ".css"
129
- #
130
- def normalize_extension(extension)
131
- extension = extension.to_s
132
- if extension[/^\./]
133
- extension
134
- else
135
- ".#{extension}"
136
- end
137
- end
138
-
139
- # Internal: Feature detect if UnboundMethods can #bind to any Object or
140
- # just Objects that share the same super class.
141
- # Basically if RUBY_VERSION >= 2.
142
- UNBOUND_METHODS_BIND_TO_ANY_OBJECT = begin
143
- foo = Module.new { def bar; end }
144
- foo.instance_method(:bar).bind(Object.new)
145
- true
146
- rescue TypeError
147
- false
148
- end
121
+ MODULE_INCLUDE_MUTEX = Mutex.new
122
+ private_constant :MODULE_INCLUDE_MUTEX
149
123
 
150
124
  # Internal: Inject into target module for the duration of the block.
151
125
  #
@@ -153,28 +127,29 @@ module Sprockets
153
127
  #
154
128
  # Returns result of block.
155
129
  def module_include(base, mod)
156
- old_methods = {}
157
-
158
- mod.instance_methods.each do |sym|
159
- old_methods[sym] = base.instance_method(sym) if base.method_defined?(sym)
160
- end
130
+ MODULE_INCLUDE_MUTEX.synchronize do
131
+ old_methods = {}
161
132
 
162
- unless UNBOUND_METHODS_BIND_TO_ANY_OBJECT
163
- base.send(:include, mod) unless base < mod
164
- end
133
+ mod.instance_methods.each do |sym|
134
+ old_methods[sym] = base.instance_method(sym) if base.method_defined?(sym)
135
+ end
165
136
 
166
- mod.instance_methods.each do |sym|
167
- method = mod.instance_method(sym)
168
- base.send(:define_method, sym, method)
169
- end
137
+ mod.instance_methods.each do |sym|
138
+ method = mod.instance_method(sym)
139
+ if base.method_defined?(sym)
140
+ base.send(:alias_method, sym, sym)
141
+ end
142
+ base.send(:define_method, sym, method)
143
+ end
170
144
 
171
- yield
172
- ensure
173
- mod.instance_methods.each do |sym|
174
- base.send(:undef_method, sym) if base.method_defined?(sym)
175
- end
176
- old_methods.each do |sym, method|
177
- base.send(:define_method, sym, method)
145
+ yield
146
+ ensure
147
+ mod.instance_methods.each do |sym|
148
+ base.send(:undef_method, sym) if base.method_defined?(sym)
149
+ end
150
+ old_methods.each do |sym, method|
151
+ base.send(:define_method, sym, method)
152
+ end
178
153
  end
179
154
  end
180
155
 
@@ -216,16 +191,16 @@ module Sprockets
216
191
  # Returns an Array of node Arrays.
217
192
  def dfs_paths(path)
218
193
  paths = []
219
- stack, seen = [path], Set.new
194
+ stack = [path]
195
+ seen = Set.new
220
196
 
221
197
  while path = stack.pop
222
- if !seen.include?(path.last)
223
- seen.add(path.last)
224
- paths << path if path.size > 1
198
+ seen.add(path.last)
199
+ paths << path
225
200
 
226
- Array(yield path.last).reverse_each do |node|
227
- stack.push(path + [node])
228
- end
201
+ children = yield path.last
202
+ children.reverse_each do |node|
203
+ stack.push(path + [node]) unless seen.include?(node)
229
204
  end
230
205
  end
231
206
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Sprockets
2
- VERSION = "3.7.2"
3
+ VERSION = "4.2.0"
3
4
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'sprockets/autoload'
2
3
  require 'sprockets/digest_utils'
3
4