sprockets 4.0.0.beta3 → 4.0.0.beta4
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 +13 -0
- data/bin/sprockets +1 -0
- data/lib/sprockets.rb +13 -1
- data/lib/sprockets/asset.rb +7 -0
- data/lib/sprockets/autoload.rb +2 -1
- data/lib/sprockets/autoload/zopfli.rb +7 -0
- data/lib/sprockets/babel_processor.rb +6 -0
- data/lib/sprockets/base.rb +10 -0
- data/lib/sprockets/compressing.rb +22 -1
- data/lib/sprockets/configuration.rb +2 -1
- data/lib/sprockets/context.rb +31 -0
- data/lib/sprockets/digest_utils.rb +12 -6
- data/lib/sprockets/environment.rb +4 -0
- data/lib/sprockets/erb_processor.rb +24 -23
- data/lib/sprockets/exporters/base.rb +72 -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/loader.rb +1 -1
- data/lib/sprockets/manifest.rb +51 -28
- data/lib/sprockets/path_utils.rb +28 -2
- data/lib/sprockets/processing.rb +2 -2
- data/lib/sprockets/processor_utils.rb +1 -3
- data/lib/sprockets/resolve.rb +3 -0
- data/lib/sprockets/sass_processor.rb +6 -3
- data/lib/sprockets/sassc_processor.rb +16 -12
- data/lib/sprockets/source_map_comment_processor.rb +3 -1
- data/lib/sprockets/source_map_processor.rb +5 -4
- data/lib/sprockets/source_map_utils.rb +6 -1
- data/lib/sprockets/utils/gzip.rb +45 -14
- data/lib/sprockets/version.rb +1 -1
- metadata +32 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52d1dd6743105d82450959d44e27538e02130e7e
|
4
|
+
data.tar.gz: 02f58032703403898778cc33d6a56e0ca8bbee01
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac089336d45577a2647ba6b329c5a62862613674be5969f4312e0d7afbb0cf3a9a06cbc7d9db7dd55649fac74c234da54d4482f83d091c4d2357269502006d99
|
7
|
+
data.tar.gz: 990363e0a8e9545ad6243279075cad733d7b403b45737b0c76b35d4647824e693c9f012c88b4220a431970d649dc7ad3582980311dc30c8e2b7b1871c1e5d611
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,19 @@
|
|
2
2
|
|
3
3
|
Get upgrade notes from Sprockets 3.x to 4.x at https://github.com/rails/sprockets/blob/master/UPGRADING.md
|
4
4
|
|
5
|
+
## Master
|
6
|
+
|
7
|
+
|
8
|
+
## 4.0.0.beta4
|
9
|
+
|
10
|
+
- Changing the version now busts the digest of all assets [#404]
|
11
|
+
- Exporter interface added [#386]
|
12
|
+
- Using ENV vars in templates will recompile templates when the env vars change. [#365]
|
13
|
+
- Source maps for imported sass files with sassc is now fixed [#391]
|
14
|
+
- Load paths now in error messages [#322]
|
15
|
+
- Cache key added to babel processor [#387]
|
16
|
+
- `Environment#find_asset!` can now be used to raise an exception when asset could not be found [#379]
|
17
|
+
|
5
18
|
## 4.0.0.beta3
|
6
19
|
|
7
20
|
- Source Map fixes [#255] [#367]
|
data/bin/sprockets
CHANGED
data/lib/sprockets.rb
CHANGED
@@ -34,8 +34,10 @@ module Sprockets
|
|
34
34
|
registered_transformers: [].freeze,
|
35
35
|
root: __dir__.dup.freeze,
|
36
36
|
transformers: Hash.new { |h, k| {}.freeze }.freeze,
|
37
|
+
exporters: Hash.new { |h, k| Set.new.freeze }.freeze,
|
37
38
|
version: "",
|
38
|
-
gzip_enabled: true
|
39
|
+
gzip_enabled: true,
|
40
|
+
export_concurrent: true
|
39
41
|
}.freeze
|
40
42
|
|
41
43
|
@context_class = Context
|
@@ -126,6 +128,7 @@ module Sprockets
|
|
126
128
|
register_bundle_metadata_reducer '*/*', :data, proc { String.new("") }, :concat
|
127
129
|
register_bundle_metadata_reducer 'application/javascript', :data, proc { String.new("") }, Utils.method(:concat_javascript_sources)
|
128
130
|
register_bundle_metadata_reducer '*/*', :links, :+
|
131
|
+
register_bundle_metadata_reducer '*/*', :sources, proc { [] }, :+
|
129
132
|
register_bundle_metadata_reducer '*/*', :map, SourceMapUtils.method(:concat_source_maps)
|
130
133
|
|
131
134
|
require 'sprockets/closure_compressor'
|
@@ -197,6 +200,11 @@ module Sprockets
|
|
197
200
|
register_mime_type 'application/html+ruby', extensions: ['.html.erb', '.erb', '.rhtml'], charset: :html
|
198
201
|
register_mime_type 'application/xml+ruby', extensions: ['.xml.erb', '.rxml']
|
199
202
|
|
203
|
+
require 'sprockets/exporters/file_exporter'
|
204
|
+
require 'sprockets/exporters/zlib_exporter'
|
205
|
+
require 'sprockets/exporters/zopfli_exporter'
|
206
|
+
register_exporter '*/*', Exporters::FileExporter
|
207
|
+
register_exporter '*/*', Exporters::ZlibExporter
|
200
208
|
|
201
209
|
register_dependency_resolver 'environment-version' do |env|
|
202
210
|
env.version
|
@@ -210,6 +218,10 @@ module Sprockets
|
|
210
218
|
register_dependency_resolver 'processors' do |env, str|
|
211
219
|
env.resolve_processors_cache_key_uri(str)
|
212
220
|
end
|
221
|
+
register_dependency_resolver 'env' do |env, str|
|
222
|
+
_, var = str.split(':', 2)
|
223
|
+
ENV[var]
|
224
|
+
end
|
213
225
|
|
214
226
|
depend_on 'environment-version'
|
215
227
|
depend_on 'environment-paths'
|
data/lib/sprockets/asset.rb
CHANGED
@@ -67,6 +67,13 @@ module Sprockets
|
|
67
67
|
logical_path.sub(/\.(\w+)$/) { |ext| "-#{etag}#{ext}" }
|
68
68
|
end
|
69
69
|
|
70
|
+
# Public: Return load path + logical path with digest spliced in.
|
71
|
+
#
|
72
|
+
# Returns String.
|
73
|
+
def full_digest_path
|
74
|
+
File.join(@load_path, digest_path)
|
75
|
+
end
|
76
|
+
|
70
77
|
# Public: Returns String MIME type of asset. Returns nil if type is unknown.
|
71
78
|
attr_reader :content_type
|
72
79
|
|
data/lib/sprockets/autoload.rb
CHANGED
@@ -6,10 +6,11 @@ module Sprockets
|
|
6
6
|
autoload :CoffeeScript, 'sprockets/autoload/coffee_script'
|
7
7
|
autoload :Eco, 'sprockets/autoload/eco'
|
8
8
|
autoload :EJS, 'sprockets/autoload/ejs'
|
9
|
-
autoload :JSMinC, 'sprockets/autoload/jsminc'
|
9
|
+
autoload :JSMinC, 'sprockets/autoload/jsminc'
|
10
10
|
autoload :Sass, 'sprockets/autoload/sass'
|
11
11
|
autoload :SassC, 'sprockets/autoload/sassc'
|
12
12
|
autoload :Uglifier, 'sprockets/autoload/uglifier'
|
13
13
|
autoload :YUI, 'sprockets/autoload/yui'
|
14
|
+
autoload :Zopfli, 'sprockets/autoload/zopfli'
|
14
15
|
end
|
15
16
|
end
|
@@ -16,6 +16,12 @@ module Sprockets
|
|
16
16
|
instance.call(input)
|
17
17
|
end
|
18
18
|
|
19
|
+
def self.cache_key
|
20
|
+
instance.cache_key
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :cache_key
|
24
|
+
|
19
25
|
def initialize(options = {})
|
20
26
|
@options = options.merge({
|
21
27
|
'blacklist' => (options['blacklist'] || []) + ['useStrict'],
|
data/lib/sprockets/base.rb
CHANGED
@@ -93,6 +93,16 @@ module Sprockets
|
|
93
93
|
find_asset(*args)
|
94
94
|
end
|
95
95
|
|
96
|
+
# Find asset by logical path or expanded path.
|
97
|
+
#
|
98
|
+
# If the asset is not found an error will be raised.
|
99
|
+
def find_asset!(*args)
|
100
|
+
uri, _ = resolve!(*args)
|
101
|
+
if uri
|
102
|
+
load(uri)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
96
106
|
# Pretty inspect
|
97
107
|
def inspect
|
98
108
|
"#<#{self.class}:0x#{object_id.to_s(16)} " +
|
@@ -102,12 +102,33 @@ module Sprockets
|
|
102
102
|
|
103
103
|
# Public: Enable or disable the creation of Gzip files.
|
104
104
|
#
|
105
|
-
#
|
105
|
+
# To disable gzip generation set to a falsey value:
|
106
106
|
#
|
107
107
|
# environment.gzip = false
|
108
108
|
#
|
109
|
+
# To enable set to a truthy value. By default zlib wil
|
110
|
+
# be used to gzip assets. If you have the Zopfli gem
|
111
|
+
# installed you can specify the zopfli algorithm to be used
|
112
|
+
# instead:
|
113
|
+
#
|
114
|
+
# environment.gzip = :zopfli
|
115
|
+
#
|
109
116
|
def gzip=(gzip)
|
110
117
|
self.config = config.merge(gzip_enabled: gzip).freeze
|
118
|
+
|
119
|
+
case gzip
|
120
|
+
when false, nil
|
121
|
+
self.unregister_exporter Exporters::ZlibExporter
|
122
|
+
self.unregister_exporter Exporters::ZopfliExporter
|
123
|
+
when :zopfli
|
124
|
+
self.unregister_exporter Exporters::ZlibExporter
|
125
|
+
self.register_exporter '*/*', Exporters::ZopfliExporter
|
126
|
+
else
|
127
|
+
self.unregister_exporter Exporters::ZopfliExporter
|
128
|
+
self.register_exporter '*/*', Exporters::ZlibExporter
|
129
|
+
end
|
130
|
+
|
131
|
+
gzip
|
111
132
|
end
|
112
133
|
end
|
113
134
|
end
|
@@ -4,12 +4,13 @@ require 'sprockets/dependencies'
|
|
4
4
|
require 'sprockets/mime'
|
5
5
|
require 'sprockets/paths'
|
6
6
|
require 'sprockets/processing'
|
7
|
+
require 'sprockets/exporting'
|
7
8
|
require 'sprockets/transformers'
|
8
9
|
require 'sprockets/utils'
|
9
10
|
|
10
11
|
module Sprockets
|
11
12
|
module Configuration
|
12
|
-
include Paths, Mime, Transformers, Processing, Compressing, Dependencies, Utils
|
13
|
+
include Paths, Mime, Transformers, Processing, Exporting, Compressing, Dependencies, Utils
|
13
14
|
|
14
15
|
def initialize_configuration(parent)
|
15
16
|
@config = parent.config
|
data/lib/sprockets/context.rb
CHANGED
@@ -18,6 +18,24 @@ module Sprockets
|
|
18
18
|
# The `Context` also collects dependencies declared by
|
19
19
|
# assets. See `DirectiveProcessor` for an example of this.
|
20
20
|
class Context
|
21
|
+
# Internal: Proxy for ENV that keeps track of the environment variables used
|
22
|
+
class ENVProxy < SimpleDelegator
|
23
|
+
def initialize(context)
|
24
|
+
@context = context
|
25
|
+
super(ENV)
|
26
|
+
end
|
27
|
+
|
28
|
+
def [](key)
|
29
|
+
@context.depend_on_env(key)
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def fetch(key, *)
|
34
|
+
@context.depend_on_env(key)
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
21
39
|
attr_reader :environment, :filename
|
22
40
|
|
23
41
|
def initialize(input)
|
@@ -42,6 +60,10 @@ module Sprockets
|
|
42
60
|
dependencies: @dependencies }
|
43
61
|
end
|
44
62
|
|
63
|
+
def env_proxy
|
64
|
+
ENVProxy.new(self)
|
65
|
+
end
|
66
|
+
|
45
67
|
# Returns the environment path that contains the file.
|
46
68
|
#
|
47
69
|
# If `app/javascripts` and `app/stylesheets` are in your path, and
|
@@ -122,6 +144,15 @@ module Sprockets
|
|
122
144
|
load(resolve(path))
|
123
145
|
end
|
124
146
|
|
147
|
+
# `depend_on_env` allows you to state a dependency on an environment
|
148
|
+
# variable.
|
149
|
+
#
|
150
|
+
# This is used for caching purposes. Any changes in the value of the
|
151
|
+
# environment variable will invalidate the cache of the source file.
|
152
|
+
def depend_on_env(key)
|
153
|
+
@dependencies << "env:#{key}"
|
154
|
+
end
|
155
|
+
|
125
156
|
# `require_asset` declares `path` as a dependency of the file. The
|
126
157
|
# dependency will be inserted before the file and will only be
|
127
158
|
# included once.
|
@@ -45,12 +45,8 @@ module Sprockets
|
|
45
45
|
digest << 'Symbol'.freeze
|
46
46
|
digest << val.to_s
|
47
47
|
},
|
48
|
-
|
49
|
-
digest << '
|
50
|
-
digest << val.to_s
|
51
|
-
},
|
52
|
-
Bignum => ->(val, digest) {
|
53
|
-
digest << 'Bignum'.freeze
|
48
|
+
Integer => ->(val, digest) {
|
49
|
+
digest << 'Integer'.freeze
|
54
50
|
digest << val.to_s
|
55
51
|
},
|
56
52
|
Array => ->(val, digest) {
|
@@ -74,6 +70,16 @@ module Sprockets
|
|
74
70
|
digest << val.name
|
75
71
|
},
|
76
72
|
}
|
73
|
+
if 0.class != Integer # Ruby < 2.4
|
74
|
+
ADD_VALUE_TO_DIGEST[Fixnum] = ->(val, digest) {
|
75
|
+
digest << 'Integer'.freeze
|
76
|
+
digest << val.to_s
|
77
|
+
}
|
78
|
+
ADD_VALUE_TO_DIGEST[Bignum] = ->(val, digest) {
|
79
|
+
digest << 'Integer'.freeze
|
80
|
+
digest << val.to_s
|
81
|
+
}
|
82
|
+
end
|
77
83
|
ADD_VALUE_TO_DIGEST.default_proc = ->(_, val) {
|
78
84
|
raise TypeError, "couldn't digest #{ val }"
|
79
85
|
}
|
@@ -1,31 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'erb'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
+
|
12
|
+
def self.call(input)
|
13
|
+
instance.call(input)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(&block)
|
17
|
+
@block = block
|
18
|
+
end
|
12
19
|
|
13
|
-
|
14
|
-
|
15
|
-
|
20
|
+
def call(input)
|
21
|
+
engine = ::ERB.new(input[:data], nil, '<>')
|
22
|
+
engine.filename = input[:filename]
|
16
23
|
|
17
|
-
|
18
|
-
|
19
|
-
|
24
|
+
context = input[:environment].context_class.new(input)
|
25
|
+
klass = (class << context; self; end)
|
26
|
+
klass.const_set(:ENV, context.env_proxy)
|
27
|
+
klass.class_eval(&@block) if @block
|
20
28
|
|
21
|
-
|
22
|
-
|
23
|
-
context = input[:environment].context_class.new(input)
|
24
|
-
klass = (class << context; self; end)
|
25
|
-
klass.class_eval(&@block) if @block
|
26
|
-
engine.def_method(klass, :_evaluate_template, input[:filename])
|
27
|
-
data = context._evaluate_template
|
28
|
-
context.metadata.merge(data: data)
|
29
|
-
end
|
29
|
+
data = engine.result(context.instance_eval('binding'))
|
30
|
+
context.metadata.merge(data: data)
|
30
31
|
end
|
31
32
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Sprockets
|
2
|
+
module Exporters
|
3
|
+
# Convienence 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 intialization
|
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
|
72
|
+
|
@@ -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::Zlib
|
32
|
+
#
|
33
|
+
# Can be called without a mime type
|
34
|
+
#
|
35
|
+
# environment.unregister_exporter Sprockets::Exporters::Zlib
|
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/loader.rb
CHANGED
@@ -163,7 +163,7 @@ module Sprockets
|
|
163
163
|
source = result.delete(:data)
|
164
164
|
metadata = result
|
165
165
|
metadata[:charset] = source.encoding.name.downcase unless metadata.key?(:charset)
|
166
|
-
metadata[:digest] = digest(source)
|
166
|
+
metadata[:digest] = digest(self.version + source)
|
167
167
|
metadata[:length] = source.bytesize
|
168
168
|
else
|
169
169
|
dependencies << build_file_digest_uri(unloaded.filename)
|
data/lib/sprockets/manifest.rb
CHANGED
@@ -5,7 +5,6 @@ require 'time'
|
|
5
5
|
require 'concurrent'
|
6
6
|
|
7
7
|
require 'sprockets/manifest_utils'
|
8
|
-
require 'sprockets/utils/gzip'
|
9
8
|
|
10
9
|
module Sprockets
|
11
10
|
# The Manifest logs the contents of assets compiled to a single directory. It
|
@@ -147,7 +146,7 @@ module Sprockets
|
|
147
146
|
end
|
148
147
|
end
|
149
148
|
|
150
|
-
# Compile
|
149
|
+
# Compile asset to directory. The asset is written to a
|
151
150
|
# fingerprinted filename like
|
152
151
|
# `application-2e8e9a7c6b0aafa0c9bdeec90ea30213.js`. An entry is
|
153
152
|
# also inserted into the manifest file.
|
@@ -159,14 +158,15 @@ module Sprockets
|
|
159
158
|
raise Error, "manifest requires environment for compilation"
|
160
159
|
end
|
161
160
|
|
162
|
-
filenames
|
163
|
-
|
164
|
-
|
161
|
+
filenames = []
|
162
|
+
concurrent_exporters = []
|
163
|
+
executor = Concurrent::FixedThreadPool.new(Concurrent.processor_count)
|
165
164
|
|
166
165
|
find(*args) do |asset|
|
166
|
+
mtime = Time.now.iso8601
|
167
167
|
files[asset.digest_path] = {
|
168
168
|
'logical_path' => asset.logical_path,
|
169
|
-
'mtime' =>
|
169
|
+
'mtime' => mtime,
|
170
170
|
'size' => asset.bytesize,
|
171
171
|
'digest' => asset.hexdigest,
|
172
172
|
|
@@ -177,34 +177,28 @@ module Sprockets
|
|
177
177
|
}
|
178
178
|
assets[asset.logical_path] = asset.digest_path
|
179
179
|
|
180
|
-
target = File.join(dir, asset.digest_path)
|
181
|
-
|
182
|
-
if File.exist?(target)
|
183
|
-
logger.debug "Skipping #{target}, already exists"
|
184
|
-
else
|
185
|
-
logger.info "Writing #{target}"
|
186
|
-
write_file = Concurrent::Future.execute { asset.write_to target }
|
187
|
-
concurrent_writers << write_file
|
188
|
-
end
|
189
180
|
filenames << asset.filename
|
190
181
|
|
191
|
-
|
192
|
-
|
193
|
-
|
182
|
+
promise = nil
|
183
|
+
exporters_for_asset(asset) do |exporter|
|
184
|
+
next if exporter.skip?(logger)
|
194
185
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
logger.info "Writing #{target}.gz"
|
199
|
-
concurrent_compressors << Concurrent::Future.execute do
|
200
|
-
write_file.wait! if write_file
|
201
|
-
gzip.compress(target)
|
186
|
+
if !environment.export_concurrent
|
187
|
+
exporter.call
|
188
|
+
next
|
202
189
|
end
|
203
|
-
end
|
204
190
|
|
191
|
+
if promise.nil?
|
192
|
+
promise = Concurrent::Promise.new(executor: executor) { exporter.call }
|
193
|
+
concurrent_exporters << promise.execute
|
194
|
+
else
|
195
|
+
concurrent_exporters << promise.then { exporter.call }
|
196
|
+
end
|
197
|
+
end
|
205
198
|
end
|
206
|
-
|
207
|
-
|
199
|
+
|
200
|
+
# make sure all exporters have finished before returning the main thread
|
201
|
+
concurrent_exporters.each(&:wait!)
|
208
202
|
save
|
209
203
|
|
210
204
|
filenames
|
@@ -284,6 +278,35 @@ module Sprockets
|
|
284
278
|
end
|
285
279
|
|
286
280
|
private
|
281
|
+
|
282
|
+
# Given an asset, finds all exporters that
|
283
|
+
# match its mime-type.
|
284
|
+
#
|
285
|
+
# Will yield each expoter to the passed in block.
|
286
|
+
#
|
287
|
+
# array = []
|
288
|
+
# puts asset.content_type # => "application/javascript"
|
289
|
+
# exporters_for_asset(asset) do |exporter|
|
290
|
+
# array << exporter
|
291
|
+
# end
|
292
|
+
# # puts array => [Exporters::FileExporter, Exporters::ZlibExporter]
|
293
|
+
def exporters_for_asset(asset)
|
294
|
+
exporters = [Exporters::FileExporter]
|
295
|
+
|
296
|
+
environment.exporters.each do |mime_type, exporter_list|
|
297
|
+
next unless environment.match_mime_type? asset.content_type, mime_type
|
298
|
+
exporter_list.each do |exporter|
|
299
|
+
exporters << exporter
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
exporters.uniq!
|
304
|
+
|
305
|
+
exporters.each do |exporter|
|
306
|
+
yield exporter.new(asset: asset, environment: environment, directory: dir)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
287
310
|
def json_decode(obj)
|
288
311
|
JSON.parse(obj, create_additions: false)
|
289
312
|
end
|
data/lib/sprockets/path_utils.rb
CHANGED
@@ -6,6 +6,7 @@ module Sprockets
|
|
6
6
|
# when code actually wants to reference ::FileUtils.
|
7
7
|
module PathUtils
|
8
8
|
extend self
|
9
|
+
require 'pathname'
|
9
10
|
|
10
11
|
# Public: Like `File.stat`.
|
11
12
|
#
|
@@ -73,8 +74,6 @@ module Sprockets
|
|
73
74
|
#
|
74
75
|
# Returns true if path is absolute, otherwise false.
|
75
76
|
if File::ALT_SEPARATOR
|
76
|
-
require 'pathname'
|
77
|
-
|
78
77
|
# On Windows, ALT_SEPARATOR is \
|
79
78
|
# Delegate to Pathname since the logic gets complex.
|
80
79
|
def absolute_path?(path)
|
@@ -102,6 +101,33 @@ module Sprockets
|
|
102
101
|
path =~ /^\.\.?($|#{SEPARATOR_PATTERN})/ ? true : false
|
103
102
|
end
|
104
103
|
|
104
|
+
# Public: Get relative path from `start` to `dest`.
|
105
|
+
#
|
106
|
+
# start - String start path (file or dir)
|
107
|
+
# dest - String destination path
|
108
|
+
#
|
109
|
+
# Returns relative String path from `start` to `dest`
|
110
|
+
def relative_path_from(start, dest)
|
111
|
+
start, dest = Pathname.new(start), Pathname.new(dest)
|
112
|
+
start = start.dirname unless start.directory?
|
113
|
+
dest.relative_path_from(start).to_s
|
114
|
+
end
|
115
|
+
|
116
|
+
# Public: Joins path to base path.
|
117
|
+
#
|
118
|
+
# base - Root path
|
119
|
+
# path - Extending path
|
120
|
+
#
|
121
|
+
# Example
|
122
|
+
#
|
123
|
+
# join('base/path/', '../file.js')
|
124
|
+
# # => 'base/file.js'
|
125
|
+
#
|
126
|
+
# Returns string path starting from base and ending at path
|
127
|
+
def join(base, path)
|
128
|
+
(Pathname.new(base) + path).to_s
|
129
|
+
end
|
130
|
+
|
105
131
|
# Internal: Get relative path for root path and subpath.
|
106
132
|
#
|
107
133
|
# path - String path
|
data/lib/sprockets/processing.rb
CHANGED
@@ -218,9 +218,9 @@ module Sprockets
|
|
218
218
|
end
|
219
219
|
end
|
220
220
|
|
221
|
-
def unregister_config_processor(type, mime_type,
|
221
|
+
def unregister_config_processor(type, mime_type, processor)
|
222
222
|
self.config = hash_reassoc(config, type, mime_type) do |processors|
|
223
|
-
processors.
|
223
|
+
processors.delete_if { |p| p == processor || p.class == processor }
|
224
224
|
processors
|
225
225
|
end
|
226
226
|
end
|
@@ -116,12 +116,10 @@ module Sprockets
|
|
116
116
|
VALID_METADATA_VALUE_TYPES = Set.new([
|
117
117
|
String,
|
118
118
|
Symbol,
|
119
|
-
Fixnum,
|
120
|
-
Bignum,
|
121
119
|
TrueClass,
|
122
120
|
FalseClass,
|
123
121
|
NilClass
|
124
|
-
]).freeze
|
122
|
+
] + (0.class == Integer ? [Integer] : [Bignum, Fixnum])).freeze
|
125
123
|
|
126
124
|
# Internal: Set of all nested compound metadata types that can nest values.
|
127
125
|
VALID_METADATA_COMPOUND_TYPES = Set.new([
|
data/lib/sprockets/resolve.rb
CHANGED
@@ -100,11 +100,14 @@ module Sprockets
|
|
100
100
|
|
101
101
|
private
|
102
102
|
|
103
|
+
def expand_source(source, env)
|
104
|
+
uri, _ = env.resolve!(source, pipeline: :source)
|
105
|
+
env.load(uri).digest_path
|
106
|
+
end
|
107
|
+
|
103
108
|
def expand_map_sources(mapping, env)
|
104
109
|
mapping.each do |map|
|
105
|
-
|
106
|
-
source_path = env.load(uri).digest_path
|
107
|
-
map[:source] = source_path
|
110
|
+
map[:source] = expand_source(map[:source], env)
|
108
111
|
end
|
109
112
|
end
|
110
113
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'sprockets/sass_processor'
|
3
|
+
require 'sprockets/path_utils'
|
3
4
|
require 'base64'
|
4
5
|
|
5
6
|
module Sprockets
|
@@ -22,39 +23,42 @@ module Sprockets
|
|
22
23
|
options = engine_options(input, context)
|
23
24
|
engine = Autoload::SassC::Engine.new(input[:data], options)
|
24
25
|
|
25
|
-
|
26
|
-
engine.render
|
26
|
+
css = Utils.module_include(Autoload::SassC::Script::Functions, @functions) do
|
27
|
+
engine.render.sub(/^\n^\/\*# sourceMappingURL=.*\*\/$/m, '')
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
-
|
30
|
+
map = SourceMapUtils.decode_json_source_map(engine.source_map)
|
31
|
+
sources = map['sources'].map do |s|
|
32
|
+
expand_source(PathUtils.join(File.dirname(input[:filename]), s), input[:environment])
|
33
|
+
end
|
34
|
+
|
35
|
+
map = map["mappings"].each do |m|
|
36
|
+
m[:source] = PathUtils.join(File.dirname(input[:filename]), m[:source])
|
37
|
+
end
|
31
38
|
|
32
39
|
map = SourceMapUtils.combine_source_maps(
|
33
40
|
input[:metadata][:map],
|
34
|
-
|
41
|
+
expand_map_sources(map, input[:environment])
|
35
42
|
)
|
36
43
|
|
37
44
|
engine.dependencies.each do |dependency|
|
38
45
|
context.metadata[:dependencies] << URIUtils.build_file_digest_uri(dependency.filename)
|
39
46
|
end
|
40
47
|
|
41
|
-
context.metadata.merge(data: css, map: map)
|
48
|
+
context.metadata.merge(data: css, map: map, sources: sources)
|
42
49
|
end
|
43
50
|
|
44
51
|
private
|
45
52
|
|
46
|
-
def change_source(mappings, source)
|
47
|
-
mappings.each { |m| m[:source] = source }
|
48
|
-
end
|
49
|
-
|
50
53
|
def engine_options(input, context)
|
51
54
|
merge_options({
|
52
55
|
filename: input[:filename],
|
53
56
|
syntax: self.class.syntax,
|
54
57
|
load_paths: input[:environment].paths,
|
55
58
|
importer: @importer_class,
|
56
|
-
|
57
|
-
source_map_file:
|
59
|
+
source_map_contents: true,
|
60
|
+
source_map_file: "#{input[:filename]}.map",
|
61
|
+
omit_source_map_url: true,
|
58
62
|
sprockets: {
|
59
63
|
context: context,
|
60
64
|
environment: input[:environment],
|
@@ -21,8 +21,10 @@ module Sprockets
|
|
21
21
|
uri, _ = env.resolve!(input[:filename], accept: map_type)
|
22
22
|
map = env.load(uri)
|
23
23
|
|
24
|
+
path = PathUtils.relative_path_from(input[:filename], map.full_digest_path)
|
25
|
+
|
24
26
|
asset.metadata.merge(
|
25
|
-
data: asset.source + (comment %
|
27
|
+
data: asset.source + (comment % path),
|
26
28
|
links: asset.links + [asset.uri, map.uri]
|
27
29
|
)
|
28
30
|
end
|
@@ -17,9 +17,10 @@ module Sprockets
|
|
17
17
|
|
18
18
|
env = input[:environment]
|
19
19
|
|
20
|
-
uri, _
|
21
|
-
asset
|
22
|
-
map
|
20
|
+
uri, _ = env.resolve!(input[:filename], accept: accept)
|
21
|
+
asset = env.load(uri)
|
22
|
+
map = asset.metadata[:map] || []
|
23
|
+
sources = asset.metadata[:sources]
|
23
24
|
|
24
25
|
# TODO: Because of the default piplene hack we have to apply dependencies
|
25
26
|
# from compiled asset to the source map, otherwise the source map cache
|
@@ -39,7 +40,7 @@ module Sprockets
|
|
39
40
|
links << uri
|
40
41
|
end
|
41
42
|
|
42
|
-
json = env.encode_json_source_map(map, filename: asset.logical_path)
|
43
|
+
json = env.encode_json_source_map(map, sources: sources, filename: asset.logical_path)
|
43
44
|
|
44
45
|
{ data: json, links: links, dependencies: dependencies }
|
45
46
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'json'
|
3
|
+
require 'sprockets/path_utils'
|
3
4
|
|
4
5
|
module Sprockets
|
5
6
|
module SourceMapUtils
|
@@ -136,7 +137,11 @@ module Sprockets
|
|
136
137
|
case mappings
|
137
138
|
when String
|
138
139
|
when Array
|
139
|
-
|
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
|
140
145
|
names ||= mappings.map { |m| m[:name] }.uniq.compact
|
141
146
|
mappings = encode_vlq_mappings(mappings, sources: sources, names: names)
|
142
147
|
else
|
data/lib/sprockets/utils/gzip.rb
CHANGED
@@ -2,11 +2,49 @@
|
|
2
2
|
module Sprockets
|
3
3
|
module Utils
|
4
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
|
+
|
5
42
|
# Private: Generates a gzipped file based off of reference file.
|
6
|
-
def initialize(asset)
|
43
|
+
def initialize(asset, archiver: ZlibArchiver)
|
7
44
|
@content_type = asset.content_type
|
8
45
|
@source = asset.source
|
9
46
|
@charset = asset.charset
|
47
|
+
@archiver = archiver
|
10
48
|
end
|
11
49
|
|
12
50
|
# What non-text mime types should we compress? This list comes from:
|
@@ -27,7 +65,7 @@ module Sprockets
|
|
27
65
|
# through a compression algorithm would make them larger.
|
28
66
|
#
|
29
67
|
# Return Boolean.
|
30
|
-
def can_compress?
|
68
|
+
def can_compress?
|
31
69
|
# The "charset" of a mime type is present if the value is
|
32
70
|
# encoded text. We can check this value to see if the asset
|
33
71
|
# can be compressed.
|
@@ -39,8 +77,8 @@ module Sprockets
|
|
39
77
|
# Private: Opposite of `can_compress?`.
|
40
78
|
#
|
41
79
|
# Returns Boolean.
|
42
|
-
def cannot_compress?
|
43
|
-
!can_compress?
|
80
|
+
def cannot_compress?
|
81
|
+
!can_compress?
|
44
82
|
end
|
45
83
|
|
46
84
|
# Private: Generates a gzipped file based off of reference asset.
|
@@ -50,16 +88,9 @@ module Sprockets
|
|
50
88
|
# Does not modify the target asset.
|
51
89
|
#
|
52
90
|
# Returns nothing.
|
53
|
-
def compress(target)
|
54
|
-
mtime = PathUtils.stat(target).mtime
|
55
|
-
|
56
|
-
gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
|
57
|
-
gz.mtime = mtime
|
58
|
-
gz.write(@source)
|
59
|
-
gz.close
|
60
|
-
|
61
|
-
File.utime(mtime, mtime, f.path)
|
62
|
-
end
|
91
|
+
def compress(file, target)
|
92
|
+
mtime = Sprockets::PathUtils.stat(target).mtime
|
93
|
+
archiver.call(file, source, mtime)
|
63
94
|
|
64
95
|
nil
|
65
96
|
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.beta4
|
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: 2016-
|
12
|
+
date: 2016-10-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -231,16 +231,22 @@ dependencies:
|
|
231
231
|
name: sassc
|
232
232
|
requirement: !ruby/object:Gem::Requirement
|
233
233
|
requirements:
|
234
|
-
- - "
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: 1.10.1
|
237
|
+
- - "<"
|
235
238
|
- !ruby/object:Gem::Version
|
236
|
-
version: '
|
239
|
+
version: '2.0'
|
237
240
|
type: :development
|
238
241
|
prerelease: false
|
239
242
|
version_requirements: !ruby/object:Gem::Requirement
|
240
243
|
requirements:
|
241
|
-
- - "
|
244
|
+
- - ">="
|
242
245
|
- !ruby/object:Gem::Version
|
243
|
-
version:
|
246
|
+
version: 1.10.1
|
247
|
+
- - "<"
|
248
|
+
- !ruby/object:Gem::Version
|
249
|
+
version: '2.0'
|
244
250
|
- !ruby/object:Gem::Dependency
|
245
251
|
name: uglifier
|
246
252
|
requirement: !ruby/object:Gem::Requirement
|
@@ -269,6 +275,20 @@ dependencies:
|
|
269
275
|
- - "~>"
|
270
276
|
- !ruby/object:Gem::Version
|
271
277
|
version: '0.12'
|
278
|
+
- !ruby/object:Gem::Dependency
|
279
|
+
name: zopfli
|
280
|
+
requirement: !ruby/object:Gem::Requirement
|
281
|
+
requirements:
|
282
|
+
- - "~>"
|
283
|
+
- !ruby/object:Gem::Version
|
284
|
+
version: 0.0.4
|
285
|
+
type: :development
|
286
|
+
prerelease: false
|
287
|
+
version_requirements: !ruby/object:Gem::Requirement
|
288
|
+
requirements:
|
289
|
+
- - "~>"
|
290
|
+
- !ruby/object:Gem::Version
|
291
|
+
version: 0.0.4
|
272
292
|
description: Sprockets is a Rack-based asset packaging system that concatenates and
|
273
293
|
serves JavaScript, CoffeeScript, CSS, Sass, and SCSS.
|
274
294
|
email:
|
@@ -296,6 +316,7 @@ files:
|
|
296
316
|
- lib/sprockets/autoload/sassc.rb
|
297
317
|
- lib/sprockets/autoload/uglifier.rb
|
298
318
|
- lib/sprockets/autoload/yui.rb
|
319
|
+
- lib/sprockets/autoload/zopfli.rb
|
299
320
|
- lib/sprockets/babel_processor.rb
|
300
321
|
- lib/sprockets/base.rb
|
301
322
|
- lib/sprockets/bower.rb
|
@@ -319,6 +340,11 @@ files:
|
|
319
340
|
- lib/sprockets/environment.rb
|
320
341
|
- lib/sprockets/erb_processor.rb
|
321
342
|
- lib/sprockets/errors.rb
|
343
|
+
- lib/sprockets/exporters/base.rb
|
344
|
+
- lib/sprockets/exporters/file_exporter.rb
|
345
|
+
- lib/sprockets/exporters/zlib_exporter.rb
|
346
|
+
- lib/sprockets/exporters/zopfli_exporter.rb
|
347
|
+
- lib/sprockets/exporting.rb
|
322
348
|
- lib/sprockets/file_reader.rb
|
323
349
|
- lib/sprockets/http_utils.rb
|
324
350
|
- lib/sprockets/jsminc_compressor.rb
|