sprockets 3.0.3 → 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 (95) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +101 -0
  3. data/{LICENSE → MIT-LICENSE} +2 -2
  4. data/README.md +531 -276
  5. data/bin/sprockets +12 -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 +41 -28
  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 +61 -13
  23. data/lib/sprockets/bower.rb +6 -3
  24. data/lib/sprockets/bundle.rb +41 -5
  25. data/lib/sprockets/cache/file_store.rb +32 -7
  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 +43 -6
  29. data/lib/sprockets/cached_environment.rb +15 -20
  30. data/lib/sprockets/closure_compressor.rb +6 -11
  31. data/lib/sprockets/coffee_script_processor.rb +20 -6
  32. data/lib/sprockets/compressing.rb +62 -2
  33. data/lib/sprockets/configuration.rb +5 -9
  34. data/lib/sprockets/context.rb +99 -25
  35. data/lib/sprockets/dependencies.rb +10 -9
  36. data/lib/sprockets/digest_utils.rb +103 -62
  37. data/lib/sprockets/directive_processor.rb +64 -36
  38. data/lib/sprockets/eco_processor.rb +4 -3
  39. data/lib/sprockets/ejs_processor.rb +4 -3
  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 +244 -62
  54. data/lib/sprockets/manifest.rb +100 -46
  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 +107 -22
  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 -52
  64. data/lib/sprockets/processor_utils.rb +38 -39
  65. data/lib/sprockets/resolve.rb +177 -97
  66. data/lib/sprockets/sass_cache_store.rb +1 -0
  67. data/lib/sprockets/sass_compressor.rb +21 -17
  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 +46 -18
  71. data/lib/sprockets/sassc_compressor.rb +56 -0
  72. data/lib/sprockets/sassc_processor.rb +297 -0
  73. data/lib/sprockets/server.rb +77 -44
  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 +23 -20
  78. data/lib/sprockets/unloaded_asset.rb +139 -0
  79. data/lib/sprockets/uri_tar.rb +99 -0
  80. data/lib/sprockets/uri_utils.rb +14 -14
  81. data/lib/sprockets/utils/gzip.rb +99 -0
  82. data/lib/sprockets/utils.rb +63 -71
  83. data/lib/sprockets/version.rb +2 -1
  84. data/lib/sprockets/yui_compressor.rb +5 -14
  85. data/lib/sprockets.rb +105 -33
  86. metadata +157 -27
  87. data/lib/sprockets/coffee_script_template.rb +0 -6
  88. data/lib/sprockets/eco_template.rb +0 -6
  89. data/lib/sprockets/ejs_template.rb +0 -6
  90. data/lib/sprockets/engines.rb +0 -81
  91. data/lib/sprockets/erb_template.rb +0 -6
  92. data/lib/sprockets/legacy.rb +0 -314
  93. data/lib/sprockets/legacy_proc_processor.rb +0 -35
  94. data/lib/sprockets/legacy_tilt_processor.rb +0 -29
  95. data/lib/sprockets/sass_template.rb +0 -7
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+ module Sprockets
3
+ module Preprocessors
4
+ # Private: Adds a default map to assets when one is not present
5
+ #
6
+ # If the input file already has a source map, it effectively returns the original
7
+ # result. Otherwise it maps 1 for 1 lines original to generated. This is needed
8
+ # Because other generators run after might depend on having a valid source map
9
+ # available.
10
+ class DefaultSourceMap
11
+ def call(input)
12
+ result = { data: input[:data] }
13
+ map = input[:metadata][:map]
14
+ filename = input[:filename]
15
+ load_path = input[:load_path]
16
+ lines = input[:data].lines.length
17
+ basename = File.basename(filename)
18
+ mime_exts = input[:environment].config[:mime_exts]
19
+ pipeline_exts = input[:environment].config[:pipeline_exts]
20
+ if map.nil? || map.empty?
21
+ result[:map] = {
22
+ "version" => 3,
23
+ "file" => PathUtils.split_subpath(load_path, filename),
24
+ "mappings" => default_mappings(lines),
25
+ "sources" => [PathUtils.set_pipeline(basename, mime_exts, pipeline_exts, :source)],
26
+ "names" => []
27
+ }
28
+ else
29
+ result[:map] = map
30
+ end
31
+
32
+ result[:map]["x_sprockets_linecount"] = lines
33
+ return result
34
+ end
35
+
36
+ private
37
+
38
+ def default_mappings(lines)
39
+ if (lines == 0)
40
+ ""
41
+ elsif (lines == 1)
42
+ "AAAA"
43
+ else
44
+ "AAAA;" + "AACA;"*(lines - 2) + "AACA"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,7 +1,5 @@
1
- require 'sprockets/engines'
1
+ # frozen_string_literal: true
2
2
  require 'sprockets/file_reader'
3
- require 'sprockets/legacy_proc_processor'
4
- require 'sprockets/legacy_tilt_processor'
5
3
  require 'sprockets/mime'
6
4
  require 'sprockets/processor_utils'
7
5
  require 'sprockets/uri_utils'
@@ -17,9 +15,14 @@ module Sprockets
17
15
  config[:pipelines]
18
16
  end
19
17
 
18
+ # Registers a pipeline that will be called by `call_processor` method.
20
19
  def register_pipeline(name, proc = nil, &block)
21
20
  proc ||= block
22
21
 
22
+ self.config = hash_reassoc(config, :pipeline_exts) do |pipeline_exts|
23
+ pipeline_exts.merge(".#{name}".freeze => name.to_sym)
24
+ end
25
+
23
26
  self.config = hash_reassoc(config, :pipelines) do |pipelines|
24
27
  pipelines.merge(name.to_sym => proc)
25
28
  end
@@ -43,12 +46,13 @@ module Sprockets
43
46
  #
44
47
  # A block can be passed for to create a shorthand processor.
45
48
  #
46
- # register_preprocessor 'text/css', :my_processor do |context, data|
47
- # data.gsub(...)
49
+ # register_preprocessor 'text/css' do |input|
50
+ # input[:data].gsub(...)
48
51
  # end
49
52
  #
50
53
  def register_preprocessor(*args, &block)
51
54
  register_config_processor(:preprocessors, *args, &block)
55
+ compute_transformers!(self.config[:registered_transformers])
52
56
  end
53
57
  alias_method :register_processor, :register_preprocessor
54
58
 
@@ -58,12 +62,13 @@ module Sprockets
58
62
  #
59
63
  # A block can be passed for to create a shorthand processor.
60
64
  #
61
- # register_postprocessor 'application/javascript', :my_processor do |context, data|
62
- # data.gsub(...)
65
+ # register_postprocessor 'application/javascript' do |input|
66
+ # input[:data].gsub(...)
63
67
  # end
64
68
  #
65
69
  def register_postprocessor(*args, &block)
66
70
  register_config_processor(:postprocessors, *args, &block)
71
+ compute_transformers!(self.config[:registered_transformers])
67
72
  end
68
73
 
69
74
  # Remove Preprocessor `klass` for `mime_type`.
@@ -72,6 +77,7 @@ module Sprockets
72
77
  #
73
78
  def unregister_preprocessor(*args)
74
79
  unregister_config_processor(:preprocessors, *args)
80
+ compute_transformers!(self.config[:registered_transformers])
75
81
  end
76
82
  alias_method :unregister_processor, :unregister_preprocessor
77
83
 
@@ -81,6 +87,7 @@ module Sprockets
81
87
  #
82
88
  def unregister_postprocessor(*args)
83
89
  unregister_config_processor(:postprocessors, *args)
90
+ compute_transformers!(self.config[:registered_transformers])
84
91
  end
85
92
 
86
93
  # Bundle Processors are ran on concatenated assets rather than
@@ -95,8 +102,8 @@ module Sprockets
95
102
  #
96
103
  # A block can be passed for to create a shorthand processor.
97
104
  #
98
- # register_bundle_processor 'application/javascript', :my_processor do |context, data|
99
- # data.gsub(...)
105
+ # register_bundle_processor 'application/javascript' do |input|
106
+ # input[:data].gsub(...)
100
107
  # end
101
108
  #
102
109
  def register_bundle_processor(*args, &block)
@@ -123,7 +130,7 @@ module Sprockets
123
130
  #
124
131
  # mime_type - String MIME Type. Use '*/*' applies to all types.
125
132
  # key - Symbol metadata key
126
- # initial - Initial memo to pass to the reduce funciton (default: nil)
133
+ # initial - Initial memo to pass to the reduce function (default: nil)
127
134
  # block - Proc accepting the memo accumulator and current value
128
135
  #
129
136
  # Returns nothing.
@@ -154,46 +161,44 @@ module Sprockets
154
161
  protected
155
162
  def resolve_processors_cache_key_uri(uri)
156
163
  params = parse_uri_query_params(uri[11..-1])
157
- params[:engine_extnames] = params[:engines] ? params[:engines].split(',') : []
158
- processors = processors_for(params[:type], params[:file_type], params[:engine_extnames], params[:pipeline])
164
+ processors = processors_for(params[:type], params[:file_type], params[:pipeline])
159
165
  processors_cache_keys(processors)
160
166
  end
161
167
 
162
- def build_processors_uri(type, file_type, engine_extnames, pipeline)
163
- engines = engine_extnames.join(',') if engine_extnames.any?
168
+ def build_processors_uri(type, file_type, pipeline)
164
169
  query = encode_uri_query_params(
165
170
  type: type,
166
171
  file_type: file_type,
167
- engines: engines,
168
172
  pipeline: pipeline
169
173
  )
170
174
  "processors:#{query}"
171
175
  end
172
176
 
173
- def processors_for(type, file_type, engine_extnames, pipeline)
177
+ def processors_for(type, file_type, pipeline)
174
178
  pipeline ||= :default
175
- config[:pipelines][pipeline.to_sym].call(self, type, file_type, engine_extnames)
179
+ if fn = config[:pipelines][pipeline.to_sym]
180
+ fn.call(self, type, file_type)
181
+ else
182
+ raise Error, "no pipeline: #{pipeline}"
183
+ end
176
184
  end
177
185
 
178
- def default_processors_for(type, file_type, engine_extnames)
186
+ def default_processors_for(type, file_type)
179
187
  bundled_processors = config[:bundle_processors][type]
180
188
  if bundled_processors.any?
181
189
  bundled_processors
182
190
  else
183
- self_processors_for(type, file_type, engine_extnames)
191
+ self_processors_for(type, file_type)
184
192
  end
185
193
  end
186
194
 
187
- def self_processors_for(type, file_type, engine_extnames)
195
+ def self_processors_for(type, file_type)
188
196
  processors = []
189
197
 
190
198
  processors.concat config[:postprocessors][type]
191
-
192
199
  if type != file_type && processor = config[:transformers][file_type][type]
193
200
  processors << processor
194
201
  end
195
-
196
- processors.concat engine_extnames.map { |ext| engines[ext] }
197
202
  processors.concat config[:preprocessors][file_type]
198
203
 
199
204
  if processors.any? || mime_type_charset_detecter(type)
@@ -204,45 +209,20 @@ module Sprockets
204
209
  end
205
210
 
206
211
  private
207
- def register_config_processor(type, mime_type, klass, proc = nil, &block)
208
- proc ||= block
209
- processor = wrap_processor(klass, proc)
212
+ def register_config_processor(type, mime_type, processor = nil, &block)
213
+ processor ||= block
210
214
 
211
215
  self.config = hash_reassoc(config, type, mime_type) do |processors|
212
216
  processors.unshift(processor)
213
217
  processors
214
218
  end
215
-
216
- compute_transformers!
217
219
  end
218
220
 
219
- def unregister_config_processor(type, mime_type, klass)
220
- if klass.is_a?(String) || klass.is_a?(Symbol)
221
- klass = config[type][mime_type].detect do |cls|
222
- cls.respond_to?(:name) && cls.name == "Sprockets::LegacyProcProcessor (#{klass})"
223
- end
224
- end
225
-
221
+ def unregister_config_processor(type, mime_type, processor)
226
222
  self.config = hash_reassoc(config, type, mime_type) do |processors|
227
- processors.delete(klass)
223
+ processors.delete_if { |p| p == processor || p.class == processor }
228
224
  processors
229
225
  end
230
-
231
- compute_transformers!
232
- end
233
-
234
- def wrap_processor(klass, proc)
235
- if !proc
236
- if klass.respond_to?(:call)
237
- klass
238
- else
239
- LegacyTiltProcessor.new(klass)
240
- end
241
- elsif proc.respond_to?(:arity) && proc.arity == 2
242
- LegacyProcProcessor.new(klass.to_s, proc)
243
- else
244
- proc
245
- end
246
226
  end
247
227
  end
248
228
  end
@@ -1,11 +1,12 @@
1
+ # frozen_string_literal: true
1
2
  require 'set'
2
3
 
3
4
  module Sprockets
4
5
  # Functional utilities for dealing with Processor functions.
5
6
  #
6
- # A Processor is a general function that my modify or transform an asset as
7
+ # A Processor is a general function that may modify or transform an asset as
7
8
  # part of the pipeline. CoffeeScript to JavaScript conversion, Minification
8
- # or Concatenation are all implemented as seperate Processor steps.
9
+ # or Concatenation are all implemented as separate Processor steps.
9
10
  #
10
11
  # Processors maybe any object that responds to call. So procs or a class that
11
12
  # defines a self.call method.
@@ -16,26 +17,34 @@ module Sprockets
16
17
  module ProcessorUtils
17
18
  extend self
18
19
 
20
+ class CompositeProcessor < Struct.new(:processor_strategy, :param, :processors) # :nodoc:
21
+ SINGULAR = lambda { |param, input| ProcessorUtils.call_processor param, input }
22
+ PLURAL = lambda { |param, input| ProcessorUtils.call_processors param, input }
23
+
24
+ def self.create(processors)
25
+ if processors.length == 1
26
+ new SINGULAR, processors.first, processors
27
+ else
28
+ new PLURAL, processors, processors
29
+ end
30
+ end
31
+
32
+ def call(input)
33
+ processor_strategy.call param, input
34
+ end
35
+
36
+ def cache_key
37
+ ProcessorUtils.processors_cache_keys(processors)
38
+ end
39
+ end
40
+
19
41
  # Public: Compose processors in right to left order.
20
42
  #
21
43
  # processors - Array of processors callables
22
44
  #
23
45
  # Returns a composed Proc.
24
46
  def compose_processors(*processors)
25
- context = self
26
-
27
- if processors.length == 1
28
- obj = method(:call_processor).to_proc.curry[processors.first]
29
- else
30
- obj = method(:call_processors).to_proc.curry[processors]
31
- end
32
-
33
- metaclass = (class << obj; self; end)
34
- metaclass.send(:define_method, :cache_key) do
35
- context.processors_cache_keys(processors)
36
- end
37
-
38
- obj
47
+ CompositeProcessor.create processors
39
48
  end
40
49
 
41
50
  # Public: Invoke list of processors in right to left order.
@@ -107,11 +116,10 @@ module Sprockets
107
116
  VALID_METADATA_VALUE_TYPES = Set.new([
108
117
  String,
109
118
  Symbol,
110
- Fixnum,
111
- Bignum,
112
119
  TrueClass,
113
120
  FalseClass,
114
- NilClass
121
+ NilClass,
122
+ Integer
115
123
  ]).freeze
116
124
 
117
125
  # Internal: Set of all nested compound metadata types that can nest values.
@@ -121,6 +129,17 @@ module Sprockets
121
129
  Set
122
130
  ]).freeze
123
131
 
132
+ # Internal: Hash of all "simple" value types allowed to be returned in
133
+ # processor metadata.
134
+ VALID_METADATA_VALUE_TYPES_HASH = VALID_METADATA_VALUE_TYPES.each_with_object({}) do |type, hash|
135
+ hash[type] = true
136
+ end.freeze
137
+
138
+ # Internal: Hash of all nested compound metadata types that can nest values.
139
+ VALID_METADATA_COMPOUND_TYPES_HASH = VALID_METADATA_COMPOUND_TYPES.each_with_object({}) do |type, hash|
140
+ hash[type] = true
141
+ end.freeze
142
+
124
143
  # Internal: Set of all allowed metadata types.
125
144
  VALID_METADATA_TYPES = (VALID_METADATA_VALUE_TYPES + VALID_METADATA_COMPOUND_TYPES).freeze
126
145
 
@@ -143,29 +162,9 @@ module Sprockets
143
162
  if !key.instance_of?(Symbol)
144
163
  raise TypeError, "processor metadata[#{key.inspect}] expected to be a Symbol"
145
164
  end
146
-
147
- if !valid_processor_metadata_value?(value)
148
- raise TypeError, "processor metadata[:#{key}] returned a complex type: #{value.inspect}\n" +
149
- "Only #{VALID_METADATA_TYPES.to_a.join(", ")} maybe used."
150
- end
151
165
  end
152
166
 
153
167
  result
154
168
  end
155
-
156
- # Internal: Validate object is in validate metadata whitelist.
157
- #
158
- # value - Any Object
159
- #
160
- # Returns true if class is in whitelist otherwise false.
161
- def valid_processor_metadata_value?(value)
162
- if VALID_METADATA_VALUE_TYPES.include?(value.class)
163
- true
164
- elsif VALID_METADATA_COMPOUND_TYPES.include?(value.class)
165
- value.all? { |v| valid_processor_metadata_value?(v) }
166
- else
167
- false
168
- end
169
- end
170
169
  end
171
170
  end