sprockets 4.0.1

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 (85) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +72 -0
  3. data/README.md +665 -0
  4. data/bin/sprockets +93 -0
  5. data/lib/rake/sprocketstask.rb +153 -0
  6. data/lib/sprockets.rb +229 -0
  7. data/lib/sprockets/add_source_map_comment_to_asset_processor.rb +60 -0
  8. data/lib/sprockets/asset.rb +202 -0
  9. data/lib/sprockets/autoload.rb +16 -0
  10. data/lib/sprockets/autoload/babel.rb +8 -0
  11. data/lib/sprockets/autoload/closure.rb +8 -0
  12. data/lib/sprockets/autoload/coffee_script.rb +8 -0
  13. data/lib/sprockets/autoload/eco.rb +8 -0
  14. data/lib/sprockets/autoload/ejs.rb +8 -0
  15. data/lib/sprockets/autoload/jsminc.rb +8 -0
  16. data/lib/sprockets/autoload/sass.rb +8 -0
  17. data/lib/sprockets/autoload/sassc.rb +8 -0
  18. data/lib/sprockets/autoload/uglifier.rb +8 -0
  19. data/lib/sprockets/autoload/yui.rb +8 -0
  20. data/lib/sprockets/autoload/zopfli.rb +7 -0
  21. data/lib/sprockets/babel_processor.rb +66 -0
  22. data/lib/sprockets/base.rb +147 -0
  23. data/lib/sprockets/bower.rb +61 -0
  24. data/lib/sprockets/bundle.rb +105 -0
  25. data/lib/sprockets/cache.rb +271 -0
  26. data/lib/sprockets/cache/file_store.rb +208 -0
  27. data/lib/sprockets/cache/memory_store.rb +75 -0
  28. data/lib/sprockets/cache/null_store.rb +54 -0
  29. data/lib/sprockets/cached_environment.rb +64 -0
  30. data/lib/sprockets/closure_compressor.rb +48 -0
  31. data/lib/sprockets/coffee_script_processor.rb +39 -0
  32. data/lib/sprockets/compressing.rb +134 -0
  33. data/lib/sprockets/configuration.rb +79 -0
  34. data/lib/sprockets/context.rb +304 -0
  35. data/lib/sprockets/dependencies.rb +74 -0
  36. data/lib/sprockets/digest_utils.rb +200 -0
  37. data/lib/sprockets/directive_processor.rb +414 -0
  38. data/lib/sprockets/eco_processor.rb +33 -0
  39. data/lib/sprockets/ejs_processor.rb +32 -0
  40. data/lib/sprockets/encoding_utils.rb +262 -0
  41. data/lib/sprockets/environment.rb +46 -0
  42. data/lib/sprockets/erb_processor.rb +37 -0
  43. data/lib/sprockets/errors.rb +12 -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 +16 -0
  50. data/lib/sprockets/http_utils.rb +135 -0
  51. data/lib/sprockets/jsminc_compressor.rb +32 -0
  52. data/lib/sprockets/jst_processor.rb +50 -0
  53. data/lib/sprockets/loader.rb +345 -0
  54. data/lib/sprockets/manifest.rb +338 -0
  55. data/lib/sprockets/manifest_utils.rb +48 -0
  56. data/lib/sprockets/mime.rb +96 -0
  57. data/lib/sprockets/npm.rb +52 -0
  58. data/lib/sprockets/path_dependency_utils.rb +77 -0
  59. data/lib/sprockets/path_digest_utils.rb +48 -0
  60. data/lib/sprockets/path_utils.rb +367 -0
  61. data/lib/sprockets/paths.rb +82 -0
  62. data/lib/sprockets/preprocessors/default_source_map.rb +49 -0
  63. data/lib/sprockets/processing.rb +228 -0
  64. data/lib/sprockets/processor_utils.rb +169 -0
  65. data/lib/sprockets/resolve.rb +295 -0
  66. data/lib/sprockets/sass_cache_store.rb +30 -0
  67. data/lib/sprockets/sass_compressor.rb +63 -0
  68. data/lib/sprockets/sass_functions.rb +3 -0
  69. data/lib/sprockets/sass_importer.rb +3 -0
  70. data/lib/sprockets/sass_processor.rb +313 -0
  71. data/lib/sprockets/sassc_compressor.rb +56 -0
  72. data/lib/sprockets/sassc_processor.rb +297 -0
  73. data/lib/sprockets/server.rb +295 -0
  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 +173 -0
  77. data/lib/sprockets/uglifier_compressor.rb +66 -0
  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 +191 -0
  81. data/lib/sprockets/utils.rb +202 -0
  82. data/lib/sprockets/utils/gzip.rb +99 -0
  83. data/lib/sprockets/version.rb +4 -0
  84. data/lib/sprockets/yui_compressor.rb +56 -0
  85. metadata +444 -0
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+ require 'sprockets/uri_utils'
3
+ require 'sprockets/path_utils'
4
+
5
+ module Sprockets
6
+ # This is a processor designed to add a source map "comment"
7
+ # to the bottom of a css or JS file that is serving a source
8
+ # map. An example of a comment might look like this
9
+ #
10
+ # //# application.js-80af0efcc960fc2ac93eda2f7b12e3db40ab360bf6ea269ceed3bea3678326f9.map
11
+ #
12
+ # As an asset is built it gets source map information added
13
+ # to the `asset.to_hash[:metadata][:map]` key. This contains all the
14
+ # information that is needed to build a source map file.
15
+ #
16
+ # To add this comment we must have an asset we can link to.
17
+ # To do this we ensure that the original aset is loaded, then
18
+ # we use a use a special mime type. For example `application/js-sourcemap+json`
19
+ # for a JS source map.
20
+ #
21
+ # This will trigger a new asset to be loaded and generated by the
22
+ # `SourceMapProcessor` processor.
23
+ #
24
+ # Finally once we have that file, we can generate a link to it
25
+ # with it's full fingerprint. This is done and then
26
+ # added to the original asset as a comment at the bottom.
27
+ #
28
+ class AddSourceMapCommentToAssetProcessor
29
+ def self.call(input)
30
+
31
+ case input[:content_type]
32
+ when "application/javascript"
33
+ comment = "\n//# sourceMappingURL=%s"
34
+ map_type = "application/js-sourcemap+json"
35
+ when "text/css"
36
+ comment = "\n/*# sourceMappingURL=%s */"
37
+ map_type = "application/css-sourcemap+json"
38
+ else
39
+ fail input[:content_type]
40
+ end
41
+
42
+ env = input[:environment]
43
+
44
+ uri, _ = env.resolve!(input[:filename], accept: input[:content_type])
45
+ asset = env.load(uri)
46
+
47
+ uri, _ = env.resolve!(input[:filename], accept: map_type)
48
+ map = env.load(uri)
49
+
50
+ uri, params = URIUtils.parse_asset_uri(input[:uri])
51
+ uri = env.expand_from_root(params[:index_alias]) if params[:index_alias]
52
+ path = PathUtils.relative_path_from(PathUtils.split_subpath(input[:load_path], uri), map.digest_path)
53
+
54
+ asset.metadata.merge(
55
+ data: asset.source + (comment % path) + "\n",
56
+ links: asset.links + [asset.uri, map.uri]
57
+ )
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,202 @@
1
+ # frozen_string_literal: true
2
+ require 'fileutils'
3
+ require 'sprockets/digest_utils'
4
+
5
+ module Sprockets
6
+ class Asset
7
+ attr_reader :logical_path
8
+
9
+ # Private: Intialize Asset wrapper from attributes Hash.
10
+ #
11
+ # Asset wrappers should not be initialized directly, only
12
+ # Environment#find_asset should vend them.
13
+ #
14
+ # attributes - Hash of ivars
15
+ #
16
+ # Returns Asset.
17
+ def initialize(attributes = {})
18
+ @attributes = attributes
19
+ @content_type = attributes[:content_type]
20
+ @filename = attributes[:filename]
21
+ @id = attributes[:id]
22
+ @load_path = attributes[:load_path]
23
+ @logical_path = attributes[:logical_path]
24
+ @metadata = attributes[:metadata]
25
+ @name = attributes[:name]
26
+ @source = attributes[:source]
27
+ @uri = attributes[:uri]
28
+ end
29
+
30
+ # Internal: Return all internal instance variables as a hash.
31
+ #
32
+ # Returns a Hash.
33
+ def to_hash
34
+ @attributes
35
+ end
36
+
37
+ # Public: Metadata accumulated from pipeline process.
38
+ #
39
+ # The API status of the keys is dependent on the pipeline processors
40
+ # itself. So some values maybe considered public and others internal.
41
+ # See the pipeline proccessor documentation itself.
42
+ #
43
+ # Returns Hash.
44
+ attr_reader :metadata
45
+
46
+ # Public: Returns String path of asset.
47
+ attr_reader :filename
48
+
49
+ # Internal: Unique asset object ID.
50
+ #
51
+ # Returns a String.
52
+ attr_reader :id
53
+
54
+ # Public: Internal URI to lookup asset by.
55
+ #
56
+ # NOT a publically accessible URL.
57
+ #
58
+ # Returns URI.
59
+ attr_reader :uri
60
+
61
+ # Public: Return logical path with digest spliced in.
62
+ #
63
+ # "foo/bar-37b51d194a7513e45b56f6524f2d51f2.js"
64
+ #
65
+ # Returns String.
66
+ def digest_path
67
+ logical_path.sub(/\.(\w+)$/) { |ext| "-#{etag}#{ext}" }
68
+ end
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
+
77
+ # Public: Returns String MIME type of asset. Returns nil if type is unknown.
78
+ attr_reader :content_type
79
+
80
+ # Public: Get all externally linked asset filenames from asset.
81
+ #
82
+ # All linked assets should be compiled anytime this asset is.
83
+ #
84
+ # Returns Set of String asset URIs.
85
+ def links
86
+ metadata[:links] || Set.new
87
+ end
88
+
89
+ # Public: Return `String` of concatenated source.
90
+ #
91
+ # Returns String.
92
+ def source
93
+ if @source
94
+ @source
95
+ else
96
+ # File is read everytime to avoid memory bloat of large binary files
97
+ File.binread(filename)
98
+ end
99
+ end
100
+
101
+ # Public: Alias for #source.
102
+ #
103
+ # Returns String.
104
+ def to_s
105
+ source
106
+ end
107
+
108
+ # Public: Get charset of source.
109
+ #
110
+ # Returns a String charset name or nil if binary.
111
+ def charset
112
+ metadata[:charset]
113
+ end
114
+
115
+ # Public: Returns Integer length of source.
116
+ def length
117
+ metadata[:length]
118
+ end
119
+ alias_method :bytesize, :length
120
+
121
+ # Public: Returns String byte digest of source.
122
+ def digest
123
+ metadata[:digest]
124
+ end
125
+
126
+ # Private: Return the version of the environment where the asset was generated.
127
+ def environment_version
128
+ metadata[:environment_version]
129
+ end
130
+
131
+ # Public: Returns String hexdigest of source.
132
+ def hexdigest
133
+ DigestUtils.pack_hexdigest(digest)
134
+ end
135
+
136
+ # Pubic: ETag String of Asset.
137
+ def etag
138
+ DigestUtils.pack_hexdigest(environment_version + digest)
139
+ end
140
+
141
+ # Public: Returns String base64 digest of source.
142
+ def base64digest
143
+ DigestUtils.pack_base64digest(digest)
144
+ end
145
+
146
+ # Public: A "named information" URL for subresource integrity.
147
+ def integrity
148
+ DigestUtils.integrity_uri(digest)
149
+ end
150
+
151
+ # Public: Add enumerator to allow `Asset` instances to be used as Rack
152
+ # compatible body objects.
153
+ #
154
+ # block
155
+ # part - String body chunk
156
+ #
157
+ # Returns nothing.
158
+ def each
159
+ yield to_s
160
+ end
161
+
162
+ # Deprecated: Save asset to disk.
163
+ #
164
+ # filename - String target
165
+ #
166
+ # Returns nothing.
167
+ def write_to(filename)
168
+ FileUtils.mkdir_p File.dirname(filename)
169
+
170
+ PathUtils.atomic_write(filename) do |f|
171
+ f.write source
172
+ end
173
+
174
+ nil
175
+ end
176
+
177
+ # Public: Pretty inspect
178
+ #
179
+ # Returns String.
180
+ def inspect
181
+ "#<#{self.class}:#{object_id.to_s(16)} #{uri.inspect}>"
182
+ end
183
+
184
+ # Public: Implements Object#hash so Assets can be used as a Hash key or
185
+ # in a Set.
186
+ #
187
+ # Returns Integer hash of the id.
188
+ def hash
189
+ id.hash
190
+ end
191
+
192
+ # Public: Compare assets.
193
+ #
194
+ # Assets are equal if they share the same path and digest.
195
+ #
196
+ # Returns true or false.
197
+ def eql?(other)
198
+ self.class == other.class && self.id == other.id
199
+ end
200
+ alias_method :==, :eql?
201
+ end
202
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module Sprockets
3
+ module Autoload
4
+ autoload :Babel, 'sprockets/autoload/babel'
5
+ autoload :Closure, 'sprockets/autoload/closure'
6
+ autoload :CoffeeScript, 'sprockets/autoload/coffee_script'
7
+ autoload :Eco, 'sprockets/autoload/eco'
8
+ autoload :EJS, 'sprockets/autoload/ejs'
9
+ autoload :JSMinC, 'sprockets/autoload/jsminc'
10
+ autoload :Sass, 'sprockets/autoload/sass'
11
+ autoload :SassC, 'sprockets/autoload/sassc'
12
+ autoload :Uglifier, 'sprockets/autoload/uglifier'
13
+ autoload :YUI, 'sprockets/autoload/yui'
14
+ autoload :Zopfli, 'sprockets/autoload/zopfli'
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'babel/transpiler'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ Babel = ::Babel
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'closure-compiler'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ Closure = ::Closure
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'coffee_script'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ CoffeeScript = ::CoffeeScript
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'eco'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ Eco = ::Eco
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'ejs'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ EJS = ::EJS
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'jsminc'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ JSMinC = ::JSMinC
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'sass'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ Sass = ::Sass
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'sassc'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ SassC = ::SassC
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'uglifier'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ Uglifier = ::Uglifier
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'yui/compressor'
3
+
4
+ module Sprockets
5
+ module Autoload
6
+ YUI = ::YUI
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ require 'zopfli'
2
+
3
+ module Sprockets
4
+ module Autoload
5
+ Zopfli = ::Zopfli
6
+ end
7
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+ require 'sprockets/autoload'
3
+ require 'sprockets/path_utils'
4
+ require 'sprockets/source_map_utils'
5
+ require 'json'
6
+
7
+ module Sprockets
8
+ class BabelProcessor
9
+ VERSION = '1'
10
+
11
+ def self.instance
12
+ @instance ||= new
13
+ end
14
+
15
+ def self.call(input)
16
+ instance.call(input)
17
+ end
18
+
19
+ def self.cache_key
20
+ instance.cache_key
21
+ end
22
+
23
+ attr_reader :cache_key
24
+
25
+ def initialize(options = {})
26
+ @options = options.merge({
27
+ 'blacklist' => (options['blacklist'] || []) + ['useStrict'],
28
+ 'sourceMap' => true
29
+ }).freeze
30
+
31
+ @cache_key = [
32
+ self.class.name,
33
+ Autoload::Babel::Transpiler::VERSION,
34
+ Autoload::Babel::Source::VERSION,
35
+ VERSION,
36
+ @options
37
+ ].freeze
38
+ end
39
+
40
+ def call(input)
41
+ data = input[:data]
42
+
43
+ result = input[:cache].fetch(@cache_key + [input[:filename]] + [data]) do
44
+ opts = {
45
+ 'moduleRoot' => nil,
46
+ 'filename' => input[:filename],
47
+ 'filenameRelative' => PathUtils.split_subpath(input[:load_path], input[:filename]),
48
+ 'sourceFileName' => File.basename(input[:filename]),
49
+ 'sourceMapTarget' => input[:filename]
50
+ }.merge(@options)
51
+
52
+ if opts['moduleIds'] && opts['moduleRoot']
53
+ opts['moduleId'] ||= File.join(opts['moduleRoot'], input[:name])
54
+ elsif opts['moduleIds']
55
+ opts['moduleId'] ||= input[:name]
56
+ end
57
+ Autoload::Babel::Transpiler.transform(data, opts)
58
+ end
59
+
60
+ map = SourceMapUtils.format_source_map(result["map"], input)
61
+ map = SourceMapUtils.combine_source_maps(input[:metadata][:map], map)
62
+
63
+ { data: result['code'], map: map }
64
+ end
65
+ end
66
+ end