sprockets 4.0.0.beta4 → 4.0.0.beta5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +5 -6
- data/lib/sprockets.rb +2 -8
- data/lib/sprockets/babel_processor.rb +4 -4
- data/lib/sprockets/base.rb +2 -0
- data/lib/sprockets/bundle.rb +38 -3
- data/lib/sprockets/cache.rb +34 -0
- data/lib/sprockets/cache/file_store.rb +17 -1
- data/lib/sprockets/cache/memory_store.rb +8 -0
- data/lib/sprockets/cache/null_store.rb +7 -0
- data/lib/sprockets/cached_environment.rb +10 -16
- data/lib/sprockets/coffee_script_processor.rb +9 -2
- data/lib/sprockets/digest_utils.rb +3 -0
- data/lib/sprockets/directive_processor.rb +21 -13
- data/lib/sprockets/loader.rb +1 -7
- data/lib/sprockets/manifest.rb +13 -9
- data/lib/sprockets/manifest_utils.rb +0 -1
- data/lib/sprockets/npm.rb +52 -0
- data/lib/sprockets/path_utils.rb +25 -1
- data/lib/sprockets/preprocessors/default_source_map.rb +27 -7
- data/lib/sprockets/sass_compressor.rb +3 -5
- data/lib/sprockets/sass_processor.rb +2 -18
- data/lib/sprockets/sassc_compressor.rb +11 -10
- data/lib/sprockets/sassc_processor.rb +10 -17
- data/lib/sprockets/server.rb +1 -1
- data/lib/sprockets/source_map_comment_processor.rb +6 -1
- data/lib/sprockets/source_map_processor.rb +16 -18
- data/lib/sprockets/source_map_utils.rb +197 -70
- data/lib/sprockets/uglifier_compressor.rb +14 -8
- data/lib/sprockets/version.rb +1 -1
- metadata +7 -6
@@ -6,6 +6,56 @@ module Sprockets
|
|
6
6
|
module SourceMapUtils
|
7
7
|
extend self
|
8
8
|
|
9
|
+
# Public: Transpose source maps into a standard format
|
10
|
+
#
|
11
|
+
# NOTE: Does not support index maps
|
12
|
+
#
|
13
|
+
# version => 3
|
14
|
+
# file => logical path
|
15
|
+
# sources => relative from filename
|
16
|
+
#
|
17
|
+
# Unnecessary attributes are removed
|
18
|
+
#
|
19
|
+
# Example
|
20
|
+
#
|
21
|
+
# map
|
22
|
+
# #=> {
|
23
|
+
# # "version" => 3,
|
24
|
+
# # "file" => "stdin",
|
25
|
+
# # "sourceRoot" => "",
|
26
|
+
# # "sourceContents" => "blah blah blah",
|
27
|
+
# # "sources" => [/root/logical/path.js],
|
28
|
+
# # "names" => [..],
|
29
|
+
# #}
|
30
|
+
# format_source_map(map, input)
|
31
|
+
# #=> {
|
32
|
+
# # "version" => 3,
|
33
|
+
# # "file" => "logical/path.js",
|
34
|
+
# # "sources" => ["path.js"],
|
35
|
+
# # "names" => [..],
|
36
|
+
# #}
|
37
|
+
def format_source_map(map, input)
|
38
|
+
filename = input[:filename]
|
39
|
+
load_path = input[:load_path]
|
40
|
+
load_paths = input[:environment].config[:paths]
|
41
|
+
mime_exts = input[:environment].config[:mime_exts]
|
42
|
+
pipeline_exts = input[:environment].config[:pipeline_exts]
|
43
|
+
file = PathUtils.split_subpath(load_path, filename)
|
44
|
+
{
|
45
|
+
"version" => 3,
|
46
|
+
"file" => file,
|
47
|
+
"mappings" => map["mappings"],
|
48
|
+
"sources" => map["sources"].map do |source|
|
49
|
+
source = URIUtils.split_file_uri(source)[2] if source.start_with? "file://"
|
50
|
+
source = PathUtils.join(File.dirname(filename), source) unless PathUtils.absolute_path?(source)
|
51
|
+
_, source = PathUtils.paths_split(load_paths, source)
|
52
|
+
source = PathUtils.relative_path_from(file, source)
|
53
|
+
PathUtils.set_pipeline(source, mime_exts, pipeline_exts, :source)
|
54
|
+
end,
|
55
|
+
"names" => map["names"]
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
9
59
|
# Public: Concatenate two source maps.
|
10
60
|
#
|
11
61
|
# For an example, if two js scripts are concatenated, the individual source
|
@@ -16,25 +66,75 @@ module Sprockets
|
|
16
66
|
# script3 = "#{script1}#{script2}"
|
17
67
|
# map3 = concat_source_maps(map1, map2)
|
18
68
|
#
|
19
|
-
# a -
|
20
|
-
# b -
|
69
|
+
# a - Source map hash
|
70
|
+
# b - Source map hash
|
21
71
|
#
|
22
|
-
# Returns a new
|
72
|
+
# Returns a new source map hash.
|
23
73
|
def concat_source_maps(a, b)
|
24
|
-
a
|
25
|
-
b
|
26
|
-
mappings = a.dup
|
74
|
+
return a || b unless a && b
|
75
|
+
a, b = make_index_map(a), make_index_map(b)
|
27
76
|
|
28
|
-
if a.
|
29
|
-
offset = a.last[:generated][0]
|
30
|
-
else
|
77
|
+
if a["sections"].count == 0 || a["sections"].last["map"]["mappings"].empty?
|
31
78
|
offset = 0
|
79
|
+
else
|
80
|
+
offset = a["sections"].last["map"]["mappings"].count(';') +
|
81
|
+
a["sections"].last["offset"]["line"] + 1
|
32
82
|
end
|
33
83
|
|
34
|
-
b.
|
35
|
-
|
84
|
+
a["sections"] += b["sections"].map do |section|
|
85
|
+
{
|
86
|
+
"offset" => section["offset"].merge({ "line" => section["offset"]["line"] + offset }),
|
87
|
+
"map" => section["map"].merge({
|
88
|
+
"sources" => section["map"]["sources"].map do |source|
|
89
|
+
PathUtils.relative_path_from(a["file"], PathUtils.join(File.dirname(b["file"]), source))
|
90
|
+
end
|
91
|
+
})
|
92
|
+
}
|
36
93
|
end
|
37
|
-
|
94
|
+
a
|
95
|
+
end
|
96
|
+
|
97
|
+
# Public: Converts source map to index map
|
98
|
+
#
|
99
|
+
# Example:
|
100
|
+
#
|
101
|
+
# map
|
102
|
+
# # => {
|
103
|
+
# "version" => 3,
|
104
|
+
# "file" => "..",
|
105
|
+
# "mappings" => "AAAA;AACA;..;AACA",
|
106
|
+
# "sources" => [..],
|
107
|
+
# "names" => [..]
|
108
|
+
# }
|
109
|
+
# make_index_map(map)
|
110
|
+
# # => {
|
111
|
+
# "version" => 3,
|
112
|
+
# "file" => "..",
|
113
|
+
# "sections" => [
|
114
|
+
# {
|
115
|
+
# "offset" => { "line" => 0, "column" => 0 },
|
116
|
+
# "map" => {
|
117
|
+
# "version" => 3,
|
118
|
+
# "file" => "..",
|
119
|
+
# "mappings" => "AAAA;AACA;..;AACA",
|
120
|
+
# "sources" => [..],
|
121
|
+
# "names" => [..]
|
122
|
+
# }
|
123
|
+
# }
|
124
|
+
# ]
|
125
|
+
# }
|
126
|
+
def make_index_map(map)
|
127
|
+
return map if map.key? "sections"
|
128
|
+
{
|
129
|
+
"version" => map["version"],
|
130
|
+
"file" => map["file"],
|
131
|
+
"sections" => [
|
132
|
+
{
|
133
|
+
"offset" => { "line" => 0, "column" => 0 },
|
134
|
+
"map" => map
|
135
|
+
}
|
136
|
+
]
|
137
|
+
}
|
38
138
|
end
|
39
139
|
|
40
140
|
# Public: Combine two seperate source map transformations into a single
|
@@ -49,25 +149,95 @@ module Sprockets
|
|
49
149
|
# map can be combined with the Uglifier map so the source lines of the
|
50
150
|
# minified output can be traced back to the original CoffeeScript file.
|
51
151
|
#
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
def combine_source_maps(original_map, second_map)
|
59
|
-
original_map ||= []
|
60
|
-
return second_map.dup if original_map.empty?
|
152
|
+
# Returns a source map hash.
|
153
|
+
def combine_source_maps(first, second)
|
154
|
+
return second unless first
|
155
|
+
|
156
|
+
_first = decode_source_map(first)
|
157
|
+
_second = decode_source_map(second)
|
61
158
|
|
62
|
-
|
159
|
+
new_mappings = []
|
63
160
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
new_map << original_line.merge(generated: m[:generated])
|
161
|
+
_second[:mappings].each do |m|
|
162
|
+
first_line = bsearch_mappings(_first[:mappings], m[:original])
|
163
|
+
new_mappings << first_line.merge(generated: m[:generated]) if first_line
|
68
164
|
end
|
69
165
|
|
70
|
-
|
166
|
+
_first[:mappings] = new_mappings
|
167
|
+
|
168
|
+
encode_source_map(_first)
|
169
|
+
end
|
170
|
+
|
171
|
+
# Public: Decompress source map
|
172
|
+
#
|
173
|
+
# Example:
|
174
|
+
#
|
175
|
+
# decode_source_map(map)
|
176
|
+
# # => {
|
177
|
+
# version: 3,
|
178
|
+
# file: "..",
|
179
|
+
# mappings: [
|
180
|
+
# { source: "..", generated: [0, 0], original: [0, 0], name: ".."}, ..
|
181
|
+
# ],
|
182
|
+
# sources: [..],
|
183
|
+
# names: [..]
|
184
|
+
# }
|
185
|
+
#
|
186
|
+
# map - Source map hash (v3 spec)
|
187
|
+
#
|
188
|
+
# Returns an uncompressed source map hash
|
189
|
+
def decode_source_map(map)
|
190
|
+
return nil unless map
|
191
|
+
|
192
|
+
mappings, sources, names = [], [], []
|
193
|
+
if map["sections"]
|
194
|
+
map["sections"].each do |s|
|
195
|
+
mappings += decode_source_map(s["map"])[:mappings].each do |m|
|
196
|
+
m[:generated][0] += s["offset"]["line"]
|
197
|
+
m[:generated][1] += s["offset"]["column"]
|
198
|
+
end
|
199
|
+
sources |= s["map"]["sources"]
|
200
|
+
names |= s["map"]["names"]
|
201
|
+
end
|
202
|
+
else
|
203
|
+
mappings = decode_vlq_mappings(map["mappings"], sources: map["sources"], names: map["names"])
|
204
|
+
sources = map["sources"]
|
205
|
+
names = map["names"]
|
206
|
+
end
|
207
|
+
{
|
208
|
+
version: 3,
|
209
|
+
file: map["file"],
|
210
|
+
mappings: mappings,
|
211
|
+
sources: sources,
|
212
|
+
names: names
|
213
|
+
}
|
214
|
+
end
|
215
|
+
|
216
|
+
# Public: Compress source map
|
217
|
+
#
|
218
|
+
# Example:
|
219
|
+
#
|
220
|
+
# encode_source_map(map)
|
221
|
+
# # => {
|
222
|
+
# "version" => 3,
|
223
|
+
# "file" => "..",
|
224
|
+
# "mappings" => "AAAA;AACA;..;AACA",
|
225
|
+
# "sources" => [..],
|
226
|
+
# "names" => [..]
|
227
|
+
# }
|
228
|
+
#
|
229
|
+
# map - Source map hash (uncompressed)
|
230
|
+
#
|
231
|
+
# Returns a compressed source map hash according to source map spec v3
|
232
|
+
def encode_source_map(map)
|
233
|
+
return nil unless map
|
234
|
+
{
|
235
|
+
"version" => map[:version],
|
236
|
+
"file" => map[:file],
|
237
|
+
"mappings" => encode_vlq_mappings(map[:mappings], sources: map[:sources], names: map[:names]),
|
238
|
+
"sources" => map[:sources],
|
239
|
+
"names" => map[:names]
|
240
|
+
}
|
71
241
|
end
|
72
242
|
|
73
243
|
# Public: Compare two source map offsets.
|
@@ -114,49 +284,6 @@ module Sprockets
|
|
114
284
|
end
|
115
285
|
end
|
116
286
|
|
117
|
-
# Public: Decode Source Map JSON into Ruby objects.
|
118
|
-
#
|
119
|
-
# json - String source map JSON
|
120
|
-
#
|
121
|
-
# Returns Hash.
|
122
|
-
def decode_json_source_map(json)
|
123
|
-
map = JSON.parse(json)
|
124
|
-
map['mappings'] = decode_vlq_mappings(map['mappings'], sources: map['sources'], names: map['names'])
|
125
|
-
map
|
126
|
-
end
|
127
|
-
|
128
|
-
# Public: Encode mappings to Source Map JSON.
|
129
|
-
#
|
130
|
-
# mappings - Array of Hash or String VLQ encoded mappings
|
131
|
-
# sources - Array of String sources
|
132
|
-
# names - Array of String names
|
133
|
-
# filename - String filename
|
134
|
-
#
|
135
|
-
# Returns JSON String.
|
136
|
-
def encode_json_source_map(mappings, sources: nil, names: nil, filename: nil)
|
137
|
-
case mappings
|
138
|
-
when String
|
139
|
-
when Array
|
140
|
-
mappings.each do |m|
|
141
|
-
m[:source] = PathUtils.relative_path_from(filename, m[:source])
|
142
|
-
end if filename
|
143
|
-
sources = sources.map { |s| PathUtils.relative_path_from(filename, s) } if filename && sources
|
144
|
-
sources = (Array(sources) + mappings.map { |m| m[:source] }).uniq.compact
|
145
|
-
names ||= mappings.map { |m| m[:name] }.uniq.compact
|
146
|
-
mappings = encode_vlq_mappings(mappings, sources: sources, names: names)
|
147
|
-
else
|
148
|
-
raise TypeError, "could not encode mappings: #{mappings}"
|
149
|
-
end
|
150
|
-
|
151
|
-
JSON.generate({
|
152
|
-
"version" => 3,
|
153
|
-
"file" => filename,
|
154
|
-
"mappings" => mappings,
|
155
|
-
"sources" => sources,
|
156
|
-
"names" => names
|
157
|
-
})
|
158
|
-
end
|
159
|
-
|
160
287
|
# Public: Decode VLQ mappings and match up sources and symbol names.
|
161
288
|
#
|
162
289
|
# str - VLQ string from 'mappings' attribute
|
@@ -44,16 +44,22 @@ module Sprockets
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def call(input)
|
47
|
-
|
48
|
-
|
47
|
+
case Autoload::Uglifier::VERSION.to_i
|
48
|
+
when 1
|
49
|
+
raise "uglifier 1.x is no longer supported, please upgrade to 2.x or newer"
|
50
|
+
when 2
|
51
|
+
input_options = { source_filename: input[:filename] }
|
52
|
+
else
|
53
|
+
input_options = { source_map: { filename: input[:filename] } }
|
49
54
|
end
|
50
|
-
@uglifier ||= Autoload::Uglifier.new(@options)
|
51
55
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
)
|
56
|
+
uglifier = Autoload::Uglifier.new(@options.merge(input_options))
|
57
|
+
|
58
|
+
js, map = uglifier.compile_with_map(input[:data])
|
59
|
+
|
60
|
+
map = SourceMapUtils.format_source_map(JSON.parse(map), input)
|
61
|
+
map = SourceMapUtils.combine_source_maps(input[:metadata][:map], map)
|
62
|
+
|
57
63
|
{ data: js, map: map }
|
58
64
|
end
|
59
65
|
end
|
data/lib/sprockets/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sprockets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.0.
|
4
|
+
version: 4.0.0.beta5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Stephenson
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-08-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -251,14 +251,14 @@ dependencies:
|
|
251
251
|
name: uglifier
|
252
252
|
requirement: !ruby/object:Gem::Requirement
|
253
253
|
requirements:
|
254
|
-
- - "
|
254
|
+
- - ">="
|
255
255
|
- !ruby/object:Gem::Version
|
256
256
|
version: '2.3'
|
257
257
|
type: :development
|
258
258
|
prerelease: false
|
259
259
|
version_requirements: !ruby/object:Gem::Requirement
|
260
260
|
requirements:
|
261
|
-
- - "
|
261
|
+
- - ">="
|
262
262
|
- !ruby/object:Gem::Version
|
263
263
|
version: '2.3'
|
264
264
|
- !ruby/object:Gem::Dependency
|
@@ -353,6 +353,7 @@ files:
|
|
353
353
|
- lib/sprockets/manifest.rb
|
354
354
|
- lib/sprockets/manifest_utils.rb
|
355
355
|
- lib/sprockets/mime.rb
|
356
|
+
- lib/sprockets/npm.rb
|
356
357
|
- lib/sprockets/path_dependency_utils.rb
|
357
358
|
- lib/sprockets/path_digest_utils.rb
|
358
359
|
- lib/sprockets/path_utils.rb
|
@@ -393,7 +394,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
393
394
|
requirements:
|
394
395
|
- - ">="
|
395
396
|
- !ruby/object:Gem::Version
|
396
|
-
version: 2.
|
397
|
+
version: 2.2.0
|
397
398
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
398
399
|
requirements:
|
399
400
|
- - ">"
|
@@ -401,7 +402,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
401
402
|
version: 1.3.1
|
402
403
|
requirements: []
|
403
404
|
rubyforge_project: sprockets
|
404
|
-
rubygems_version: 2.
|
405
|
+
rubygems_version: 2.6.13
|
405
406
|
signing_key:
|
406
407
|
specification_version: 4
|
407
408
|
summary: Rack-based asset packaging system
|