condenser 1.4 → 1.5.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.
- checksums.yaml +4 -4
- data/lib/condenser/asset.rb +55 -8
- data/lib/condenser/build_cache.rb +2 -0
- data/lib/condenser/cache/file_store.rb +1 -0
- data/lib/condenser/cache/memory_store.rb +1 -0
- data/lib/condenser/cache/null_store.rb +1 -0
- data/lib/condenser/cache_store.rb +1 -0
- data/lib/condenser/context.rb +1 -0
- data/lib/condenser/encoding_utils.rb +2 -0
- data/lib/condenser/environment.rb +2 -0
- data/lib/condenser/errors.rb +2 -0
- data/lib/condenser/export.rb +11 -6
- data/lib/condenser/helpers/parse_helpers.rb +19 -4
- data/lib/condenser/manifest.rb +6 -4
- data/lib/condenser/minifiers/sass_minifier.rb +2 -0
- data/lib/condenser/minifiers/terser_minifier.rb +2 -0
- data/lib/condenser/minifiers/uglify_minifier.rb +2 -0
- data/lib/condenser/pipeline.rb +2 -0
- data/lib/condenser/processors/babel_processor.rb +11 -2
- data/lib/condenser/processors/css_media_combiner_processor.rb +7 -5
- data/lib/condenser/processors/js_analyzer.rb +109 -37
- data/lib/condenser/processors/node_processor.rb +2 -0
- data/lib/condenser/processors/purgecss_processor.rb +2 -0
- data/lib/condenser/processors/rollup_processor.rb +289 -136
- data/lib/condenser/resolve.rb +15 -7
- data/lib/condenser/server.rb +22 -20
- data/lib/condenser/templating_engine/ejs.rb +2 -0
- data/lib/condenser/templating_engine/erb.rb +2 -0
- data/lib/condenser/transformers/dart_sass_transformer.rb +5 -3
- data/lib/condenser/transformers/jst_transformer.rb +2 -0
- data/lib/condenser/transformers/sass/functions.rb +2 -0
- data/lib/condenser/transformers/sass/importer.rb +2 -0
- data/lib/condenser/transformers/sass.rb +2 -0
- data/lib/condenser/transformers/sass_transformer.rb +2 -0
- data/lib/condenser/transformers/svg_transformer/base.rb +2 -0
- data/lib/condenser/transformers/svg_transformer/tag.rb +2 -0
- data/lib/condenser/transformers/svg_transformer/template.rb +3 -1
- data/lib/condenser/transformers/svg_transformer/template_error.rb +2 -0
- data/lib/condenser/transformers/svg_transformer/value.rb +2 -0
- data/lib/condenser/transformers/svg_transformer/var_generator.rb +2 -0
- data/lib/condenser/transformers/svg_transformer.rb +2 -0
- data/lib/condenser/utils.rb +2 -0
- data/lib/condenser/version.rb +3 -1
- data/lib/condenser/writers/brotli_writer.rb +2 -0
- data/lib/condenser/writers/file_writer.rb +2 -0
- data/lib/condenser/writers/zlib_writer.rb +2 -0
- data/lib/condenser.rb +2 -0
- data/lib/rake/condensertask.rb +2 -0
- data/test/cache_test.rb +14 -14
- data/test/manifest_test.rb +17 -2
- data/test/postprocessors/css_media_combiner_test.rb +9 -12
- data/test/preprocessor/babel_test.rb +843 -327
- data/test/preprocessor/js_analyzer_test.rb +174 -5
- data/test/processors/rollup/dynamic_import_test.rb +358 -0
- data/test/processors/rollup_test.rb +37 -56
- data/test/resolve_test.rb +4 -9
- data/test/server_test.rb +6 -5
- data/test/transformers/dart_scss_test.rb +2 -2
- data/test/transformers/scss_test.rb +2 -2
- metadata +6 -11
- data/lib/condenser/minifiers/package-lock.json +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f9c3ee00b220c07b9a0791215a5f260ac84c4d7432c19a0764339ebae02d48d
|
4
|
+
data.tar.gz: 460361e7976a33f448a06d348582aa70c370cd7fcc334b4839e47c1c6738b2ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7af0b344077380ed7c25ad7a7c27e16a11f584518688f4f30e18e4a84af252c9aaa889aca549108ca7487bce6d246985ee15e34b5864f88e146578a34a328e04
|
7
|
+
data.tar.gz: 3f425933f7f0c2f07b9e5da5d17a78a0234bf35bd0c0e1095822a1c62f62b74cd93a935b8717a3f249d3321733826530c1afa82008e39fd847e61d93a35f2c13
|
data/lib/condenser/asset.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'set'
|
2
4
|
require 'digest/md5'
|
3
5
|
require 'digest/sha1'
|
@@ -10,7 +12,7 @@ class Condenser
|
|
10
12
|
include EncodingUtils
|
11
13
|
|
12
14
|
attr_reader :environment, :filename, :content_types, :source_file, :source_path
|
13
|
-
attr_reader :
|
15
|
+
attr_reader :content_types_digest, :exports, :type
|
14
16
|
attr_writer :source, :sourcemap
|
15
17
|
|
16
18
|
attr_accessor :imports, :processed
|
@@ -65,7 +67,9 @@ class Condenser
|
|
65
67
|
def process_dependencies
|
66
68
|
deps = @environment.cache.fetch "direct-deps/#{cache_key}" do
|
67
69
|
process
|
68
|
-
|
70
|
+
# Sort so etag and cache key are same irrelevant of ordering of
|
71
|
+
# dependencies
|
72
|
+
@process_dependencies.map { |fn| [normalize_filename_base(fn[0]), fn[1]] }.sort_by { |d| d[0] }
|
69
73
|
end
|
70
74
|
|
71
75
|
deps.inject([]) do |memo, i|
|
@@ -80,7 +84,24 @@ class Condenser
|
|
80
84
|
def export_dependencies
|
81
85
|
deps = @environment.cache.fetch "export-deps/#{cache_key}" do
|
82
86
|
process
|
83
|
-
|
87
|
+
# Sort so etag and cache key are same irrelevant of ordering of
|
88
|
+
# dependencies
|
89
|
+
(@export_dependencies + @process_dependencies).map { |fn| [normalize_filename_base(fn[0]), fn[1]] }.sort_by { |d| d[0] }
|
90
|
+
end
|
91
|
+
|
92
|
+
deps.inject([]) do |memo, i|
|
93
|
+
i[0] = File.join(@environment.base, i[0].delete_prefix('!')) if i[0].start_with?('!') && @environment.base
|
94
|
+
@environment.resolve(i[0], File.dirname(@source_file), accept: i[1], npm: true).each do |asset|
|
95
|
+
memo << asset
|
96
|
+
end
|
97
|
+
memo
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def linked_assets
|
102
|
+
deps = @environment.cache.fetch "linked-assets/#{cache_key}" do
|
103
|
+
process
|
104
|
+
@linked_assets.map { |fn| [normalize_filename_base(fn[0]), fn[1]] }
|
84
105
|
end
|
85
106
|
|
86
107
|
deps.inject([]) do |memo, i|
|
@@ -122,7 +143,7 @@ class Condenser
|
|
122
143
|
end
|
123
144
|
|
124
145
|
def all_process_dependencies(visited = Set.new)
|
125
|
-
f =
|
146
|
+
f = Set.new
|
126
147
|
if !visited.include?(@source_file)
|
127
148
|
f << @source_file
|
128
149
|
visited << self.source_file
|
@@ -135,7 +156,7 @@ class Condenser
|
|
135
156
|
end
|
136
157
|
|
137
158
|
def all_export_dependencies(visited = Set.new)
|
138
|
-
f =
|
159
|
+
f = Set.new
|
139
160
|
if !visited.include?(@source_file)
|
140
161
|
f << @source_file
|
141
162
|
visited << self.source_file
|
@@ -192,7 +213,7 @@ class Condenser
|
|
192
213
|
]
|
193
214
|
end
|
194
215
|
|
195
|
-
@ecv = Digest::SHA1.
|
216
|
+
@ecv = Digest::SHA1.hexdigest(JSON.generate(f))
|
196
217
|
end
|
197
218
|
|
198
219
|
def needs_reprocessing!
|
@@ -296,6 +317,7 @@ class Condenser
|
|
296
317
|
data[:digest_name] = @environment.digestor.name.sub(/^.*::/, '').downcase
|
297
318
|
data[:process_dependencies] = normialize_dependency_names(data[:process_dependencies])
|
298
319
|
data[:export_dependencies] = normialize_dependency_names(data[:export_dependencies])
|
320
|
+
data[:linked_assets] = normialize_dependency_names(data[:linked_assets])
|
299
321
|
|
300
322
|
# Do this here and at the end so cache_key can be calculated if we
|
301
323
|
# run this block
|
@@ -313,6 +335,15 @@ class Condenser
|
|
313
335
|
@processors = data[:processors]
|
314
336
|
@processors_loaded = true
|
315
337
|
@processed = true
|
338
|
+
@type = data[:type]
|
339
|
+
|
340
|
+
digestor = @environment.digestor.new
|
341
|
+
digestor << data[:source]
|
342
|
+
all_dependenies(export_dependencies, Set.new, :export_dependencies) do |dep|
|
343
|
+
digestor << dep.source
|
344
|
+
end
|
345
|
+
data[:etag] = digestor.digest.unpack('H*'.freeze).first
|
346
|
+
@etag = data[:etag]
|
316
347
|
data
|
317
348
|
end
|
318
349
|
end
|
@@ -329,6 +360,8 @@ class Condenser
|
|
329
360
|
@default_export = result[:default_export]
|
330
361
|
@exports = result[:exports]
|
331
362
|
@processors = result[:processors]
|
363
|
+
@etag = result[:etag]
|
364
|
+
@type = result[:type]
|
332
365
|
load_processors
|
333
366
|
|
334
367
|
@processed = true
|
@@ -353,6 +386,9 @@ class Condenser
|
|
353
386
|
process
|
354
387
|
dirname, basename, extensions, mime_types = @environment.decompose_path(@filename)
|
355
388
|
data = {
|
389
|
+
etag: @etag,
|
390
|
+
type: @type,
|
391
|
+
|
356
392
|
source: @source.dup,
|
357
393
|
source_file: @source_file,
|
358
394
|
|
@@ -429,7 +465,11 @@ class Condenser
|
|
429
465
|
process
|
430
466
|
@digest.unpack('H*'.freeze).first
|
431
467
|
end
|
432
|
-
|
468
|
+
|
469
|
+
def etag
|
470
|
+
process
|
471
|
+
@etag
|
472
|
+
end
|
433
473
|
|
434
474
|
def integrity
|
435
475
|
process
|
@@ -437,7 +477,14 @@ class Condenser
|
|
437
477
|
end
|
438
478
|
|
439
479
|
def to_json
|
440
|
-
{
|
480
|
+
{
|
481
|
+
path: path,
|
482
|
+
etag: etag,
|
483
|
+
type: type,
|
484
|
+
size: size,
|
485
|
+
digest: hexdigest,
|
486
|
+
integrity: integrity
|
487
|
+
}
|
441
488
|
end
|
442
489
|
|
443
490
|
def write(output_directory)
|
data/lib/condenser/context.rb
CHANGED
data/lib/condenser/errors.rb
CHANGED
data/lib/condenser/export.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Condenser
|
2
4
|
class Export
|
3
5
|
|
4
|
-
attr_reader :filename, :source, :sourcemap, :content_types, :digest, :digest_name
|
6
|
+
attr_reader :filename, :source, :sourcemap, :content_types, :digest, :digest_name, :etag, :type
|
5
7
|
|
6
8
|
def initialize(env, input={})
|
7
9
|
@environment = env
|
@@ -12,6 +14,8 @@ class Condenser
|
|
12
14
|
@content_types = input[:content_types]
|
13
15
|
@digest = input[:digest]
|
14
16
|
@digest_name = input[:digest_name]
|
17
|
+
@etag = input[:etag]
|
18
|
+
@type = input[:type]
|
15
19
|
end
|
16
20
|
|
17
21
|
def path
|
@@ -43,7 +47,6 @@ class Condenser
|
|
43
47
|
def hexdigest
|
44
48
|
@digest.unpack('H*'.freeze).first
|
45
49
|
end
|
46
|
-
alias_method :etag, :hexdigest
|
47
50
|
|
48
51
|
def integrity
|
49
52
|
"#{@digest_name}-#{[@digest].pack('m0')}"
|
@@ -51,10 +54,12 @@ class Condenser
|
|
51
54
|
|
52
55
|
def to_json
|
53
56
|
{
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
57
|
+
path: path,
|
58
|
+
etag: etag,
|
59
|
+
type: type,
|
60
|
+
size: size,
|
61
|
+
digest: hexdigest,
|
62
|
+
integrity: integrity
|
58
63
|
}
|
59
64
|
end
|
60
65
|
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Condenser::ParseHelpers
|
2
4
|
|
3
5
|
attr_accessor :matched
|
4
6
|
|
5
7
|
def eos?
|
6
|
-
@index >=
|
8
|
+
@index >= @source.size
|
7
9
|
end
|
8
10
|
|
9
11
|
def scan_until(r)
|
@@ -56,9 +58,22 @@ module Condenser::ParseHelpers
|
|
56
58
|
end
|
57
59
|
|
58
60
|
def gobble(r)
|
59
|
-
|
60
|
-
|
61
|
-
|
61
|
+
if r.is_a?(Regexp)
|
62
|
+
m = @source.match(r, @index)
|
63
|
+
if m&.begin(0) == @index
|
64
|
+
scan_until(r)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
forward(1)
|
68
|
+
@source[@index-1];
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def peek(n=1)
|
73
|
+
if n.is_a?(Regexp)
|
74
|
+
@source.match(n, @index)
|
75
|
+
else
|
76
|
+
@source.slice(@index, n)
|
62
77
|
end
|
63
78
|
end
|
64
79
|
|
data/lib/condenser/manifest.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Condenser
|
2
4
|
class Manifest
|
3
5
|
|
@@ -39,7 +41,7 @@ class Condenser
|
|
39
41
|
|
40
42
|
if File.exist?(@filename)
|
41
43
|
begin
|
42
|
-
@data = JSON.parse(File.read(@filename))
|
44
|
+
@data = JSON.parse(File.read(@filename), symbolize_names: true).transform_keys(&:to_s)
|
43
45
|
rescue JSON::ParserError => e
|
44
46
|
@data = {}
|
45
47
|
logger.error "#{@filename} is invalid: #{e.class} #{e.message}"
|
@@ -72,14 +74,14 @@ class Condenser
|
|
72
74
|
@data[asset.filename] = export.to_json
|
73
75
|
outputs = export.write(@dir)
|
74
76
|
asset.linked_assets.each do |la|
|
75
|
-
|
77
|
+
outputs += add_asset(la)
|
76
78
|
end
|
77
79
|
outputs
|
78
80
|
end
|
79
81
|
|
80
82
|
def [](key)
|
81
83
|
add(key) if @environment
|
82
|
-
@data[key]
|
84
|
+
@data[key.delete_prefix('/')]
|
83
85
|
end
|
84
86
|
|
85
87
|
def compile(*args)
|
@@ -104,7 +106,7 @@ class Condenser
|
|
104
106
|
# Cleanup old assets in the compile directory. By default it will keep the
|
105
107
|
# latest version and remove any other files over 4 weeks old.
|
106
108
|
def clean(age = 2419200)
|
107
|
-
clean_dir(@dir, @data.values.map{ |v| v[
|
109
|
+
clean_dir(@dir, @data.values.map{ |v| v[:path] }, Time.now - age)
|
108
110
|
end
|
109
111
|
|
110
112
|
def clean_dir(dir, assets, age)
|
data/lib/condenser/pipeline.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
|
3
5
|
class Condenser::BabelProcessor < Condenser::NodeProcessor
|
@@ -16,6 +18,7 @@ class Condenser::BabelProcessor < Condenser::NodeProcessor
|
|
16
18
|
targets: { browsers: '> 1% and not dead' }
|
17
19
|
}]
|
18
20
|
]
|
21
|
+
options[:highlightCode] = false if !options.has_key?(:highlightCode)
|
19
22
|
|
20
23
|
packages = options.slice(:plugins, :presets).values.reduce(&:+).map { |p| p.is_a?(Array) ? p[0] : p}
|
21
24
|
packages.unshift('@babel/core')
|
@@ -80,11 +83,17 @@ class Condenser::BabelProcessor < Condenser::NodeProcessor
|
|
80
83
|
end
|
81
84
|
end
|
82
85
|
|
83
|
-
|
86
|
+
opts['preset']&.each do |preset|
|
87
|
+
preset[0] = preset[0].gsub(/"@?babel[\/-][^"]+"/) { |m| "require(#{m})"}
|
88
|
+
end
|
89
|
+
opts['plugins']&.each do |preset|
|
90
|
+
preset[0] = preset[0].gsub(/"@?babel[\/-][^"]+"/) { |m| "require(#{m})"}
|
91
|
+
end
|
92
|
+
|
84
93
|
result = exec_runtime(<<-JS)
|
85
94
|
const babel = require("#{File.join(npm_module_path('@babel/core'))}");
|
86
95
|
const source = #{JSON.generate(input[:source])};
|
87
|
-
const options = #{JSON.generate(opts)
|
96
|
+
const options = #{JSON.generate(opts)};
|
88
97
|
|
89
98
|
let imports = [];
|
90
99
|
let defaultExport = false;
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Condenser::CSSMediaCombinerProcessor
|
2
4
|
|
3
5
|
include Condenser::ParseHelpers
|
@@ -10,7 +12,7 @@ class Condenser::CSSMediaCombinerProcessor
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def reduce_media_query(queries)
|
13
|
-
output =
|
15
|
+
output = String.new
|
14
16
|
queries.each do |query, contents|
|
15
17
|
output << query if query
|
16
18
|
output << if contents.is_a?(Hash)
|
@@ -30,12 +32,12 @@ class Condenser::CSSMediaCombinerProcessor
|
|
30
32
|
@selectors = []
|
31
33
|
@media_queries = {}
|
32
34
|
|
33
|
-
input[:source] =
|
35
|
+
input[:source] = String.new
|
34
36
|
while !eos?
|
35
37
|
output = if @selectors.empty?
|
36
38
|
input[:source]
|
37
39
|
else
|
38
|
-
(@selectors[0...-1].reduce(@media_queries) { |hash, selector| hash[selector] ||= {} }[@selectors.last] ||=
|
40
|
+
(@selectors[0...-1].reduce(@media_queries) { |hash, selector| hash[selector] ||= {} }[@selectors.last] ||= String.new)
|
39
41
|
end
|
40
42
|
|
41
43
|
case @stack.last
|
@@ -64,11 +66,11 @@ class Condenser::CSSMediaCombinerProcessor
|
|
64
66
|
@stack.pop
|
65
67
|
end
|
66
68
|
else
|
67
|
-
case scan_until(/(@media[^\{]*{|\
|
69
|
+
case scan_until(/(@media[^\{]*{|\z)/)
|
68
70
|
when ''
|
69
71
|
output << pre_match
|
70
72
|
else
|
71
|
-
output << pre_match
|
73
|
+
output << pre_match.rstrip
|
72
74
|
@selectors << matched.squish
|
73
75
|
@stack << :media_query
|
74
76
|
end
|