condenser 1.2 → 1.3
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 +19 -16
- data/lib/condenser/build_cache.rb +1 -1
- data/lib/condenser/context.rb +9 -25
- data/lib/condenser/helpers/parse_helpers.rb +1 -1
- data/lib/condenser/manifest.rb +3 -1
- data/lib/condenser/pipeline.rb +8 -3
- data/lib/condenser/processors/babel_processor.rb +1 -1
- data/lib/condenser/processors/css_media_combiner_processor.rb +81 -0
- data/lib/condenser/processors/js_analyzer.rb +0 -2
- data/lib/condenser/processors/purgecss_processor.rb +6 -4
- data/lib/condenser/processors/rollup_processor.rb +37 -35
- data/lib/condenser/resolve.rb +1 -3
- data/lib/condenser/templating_engine/ejs.rb +1 -1
- data/lib/condenser/transformers/dart_sass_transformer.rb +285 -0
- data/lib/condenser/transformers/jst_transformer.rb +67 -17
- data/lib/condenser/transformers/sass/functions.rb +133 -0
- data/lib/condenser/transformers/sass/importer.rb +48 -0
- data/lib/condenser/transformers/sass.rb +4 -0
- data/lib/condenser/transformers/sass_transformer.rb +124 -281
- data/lib/condenser/transformers/svg_transformer/base.rb +26 -0
- data/lib/condenser/transformers/svg_transformer/tag.rb +54 -0
- data/lib/condenser/transformers/svg_transformer/template.rb +151 -0
- data/lib/condenser/transformers/svg_transformer/template_error.rb +2 -0
- data/lib/condenser/transformers/svg_transformer/value.rb +13 -0
- data/lib/condenser/transformers/svg_transformer/var_generator.rb +10 -0
- data/lib/condenser/transformers/svg_transformer.rb +19 -0
- data/lib/condenser/version.rb +1 -1
- data/lib/condenser.rb +17 -5
- data/test/cache_test.rb +46 -2
- data/test/dependency_test.rb +2 -2
- data/test/manifest_test.rb +34 -0
- data/test/minifiers/terser_minifier_test.rb +0 -1
- data/test/minifiers/uglify_minifier_test.rb +0 -1
- data/test/postprocessors/css_media_combiner_test.rb +107 -0
- data/test/postprocessors/purgecss_test.rb +62 -0
- data/test/preprocessor/babel_test.rb +693 -299
- data/test/preprocessor/js_analyzer_test.rb +0 -2
- data/test/processors/rollup_test.rb +50 -20
- data/test/resolve_test.rb +8 -9
- data/test/server_test.rb +6 -1
- data/test/templates/ejs_test.rb +2 -11
- data/test/templates/erb_test.rb +0 -5
- data/test/test_helper.rb +3 -1
- data/test/transformers/dart_scss_test.rb +139 -0
- data/test/transformers/jst_test.rb +165 -21
- data/test/transformers/scss_test.rb +14 -0
- data/test/transformers/svg_test.rb +40 -0
- metadata +23 -6
- data/lib/condenser/transformers/sass_transformer/importer.rb +0 -50
@@ -0,0 +1,19 @@
|
|
1
|
+
class Condenser::SVGTransformer
|
2
|
+
|
3
|
+
autoload :Base, File.expand_path('../svg_transformer/base', __FILE__)
|
4
|
+
autoload :Tag, File.expand_path('../svg_transformer/tag', __FILE__)
|
5
|
+
autoload :Template, File.expand_path('../svg_transformer/template', __FILE__)
|
6
|
+
autoload :TemplateError, File.expand_path('../svg_transformer/template_error', __FILE__)
|
7
|
+
autoload :Value, File.expand_path('../svg_transformer/value', __FILE__)
|
8
|
+
autoload :VarGenerator, File.expand_path('../svg_transformer/var_generator', __FILE__)
|
9
|
+
|
10
|
+
def self.setup(env)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.call(environment, input)
|
14
|
+
input[:source] = Condenser::SVGTransformer::Template.new(input[:source]).to_module
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
|
data/lib/condenser/version.rb
CHANGED
data/lib/condenser.rb
CHANGED
@@ -19,19 +19,25 @@ class Condenser
|
|
19
19
|
autoload :RollupProcessor, 'condenser/processors/rollup_processor'
|
20
20
|
autoload :JSAnalyzer, 'condenser/processors/js_analyzer'
|
21
21
|
autoload :PurgeCSSProcessor,'condenser/processors/purgecss_processor'
|
22
|
+
autoload :CSSMediaCombinerProcessor,'condenser/processors/css_media_combiner_processor'
|
22
23
|
autoload :NodeProcessor, 'condenser/processors/node_processor'
|
23
24
|
autoload :UglifyMinifier, 'condenser/minifiers/uglify_minifier'
|
24
25
|
autoload :TerserMinifier, 'condenser/minifiers/terser_minifier'
|
25
26
|
autoload :Erubi, 'condenser/templating_engine/erb'
|
27
|
+
autoload :Sass, 'condenser/transformers/sass'
|
26
28
|
autoload :SassMinifier, 'condenser/minifiers/sass_minifier'
|
27
|
-
autoload :
|
29
|
+
autoload :DartSassTransformer, 'condenser/transformers/dart_sass_transformer'
|
30
|
+
autoload :DartScssTransformer, 'condenser/transformers/dart_sass_transformer'
|
31
|
+
autoload :SassTransformer, 'condenser/transformers/sass_transformer'
|
28
32
|
autoload :ScssTransformer, 'condenser/transformers/sass_transformer'
|
29
|
-
autoload :
|
33
|
+
autoload :EjsTemplate, 'condenser/templating_engine/ejs'
|
30
34
|
autoload :JstTransformer, 'condenser/transformers/jst_transformer'
|
35
|
+
autoload :SVGTransformer, 'condenser/transformers/svg_transformer'
|
31
36
|
autoload :FileWriter, 'condenser/writers/file_writer'
|
32
37
|
autoload :ZlibWriter, 'condenser/writers/zlib_writer'
|
33
38
|
autoload :BrotliWriter, 'condenser/writers/brotli_writer'
|
34
39
|
autoload :BuildCache, 'condenser/build_cache'
|
40
|
+
autoload :ParseHelpers, 'condenser/helpers/parse_helpers'
|
35
41
|
|
36
42
|
def self.configure(&block)
|
37
43
|
instance_eval(&block)
|
@@ -56,8 +62,8 @@ class Condenser
|
|
56
62
|
configure(&block)
|
57
63
|
elsif pipeline != false
|
58
64
|
self.configure do
|
59
|
-
|
60
|
-
register_preprocessor 'application/javascript', Condenser::BabelProcessor
|
65
|
+
register_preprocessor 'application/javascript', Condenser::JSAnalyzer
|
66
|
+
# register_preprocessor 'application/javascript', Condenser::BabelProcessor
|
61
67
|
register_exporter 'application/javascript', Condenser::RollupProcessor
|
62
68
|
register_minifier 'application/javascript', Condenser::UglifyMinifier
|
63
69
|
|
@@ -132,6 +138,9 @@ Condenser.configure do
|
|
132
138
|
# CSS
|
133
139
|
register_mime_type 'text/css', extension: '.css', charset: :css
|
134
140
|
|
141
|
+
# PDF
|
142
|
+
register_mime_type 'application/pdf', extensions: %w(.pdf)
|
143
|
+
|
135
144
|
# SASS
|
136
145
|
register_mime_type 'text/sass', extensions: %w(.sass .css.sass)
|
137
146
|
# register_transformer 'text/sass', 'text/css', SassProcessor
|
@@ -145,12 +154,15 @@ Condenser.configure do
|
|
145
154
|
|
146
155
|
# EJS
|
147
156
|
register_mime_type 'application/ejs', extensions: '.ejs', charset: :unicode
|
148
|
-
register_template 'application/ejs', Condenser::
|
157
|
+
register_template 'application/ejs', Condenser::EjsTemplate
|
149
158
|
|
150
159
|
# JST
|
151
160
|
register_mime_type 'application/jst', extensions: '.jst', charset: :unicode
|
152
161
|
register_transformer 'application/jst', 'application/javascript', Condenser::JstTransformer
|
153
162
|
|
163
|
+
# SVG
|
164
|
+
register_transformer 'image/svg+xml', 'application/javascript', Condenser::SVGTransformer
|
165
|
+
|
154
166
|
# Writers
|
155
167
|
register_mime_type 'application/gzip', extensions: %w(.gz .gzip)
|
156
168
|
register_mime_type 'application/brotli', extension: %w(.br)
|
data/test/cache_test.rb
CHANGED
@@ -142,7 +142,7 @@ class CacheTest < ActiveSupport::TestCase
|
|
142
142
|
|
143
143
|
end
|
144
144
|
|
145
|
-
test 'a dependency is
|
145
|
+
test 'a dependency is superceeded by a new file' do
|
146
146
|
Dir.mkdir(File.join(@path, 'a'))
|
147
147
|
Dir.mkdir(File.join(@path, 'b'))
|
148
148
|
@env.clear_path
|
@@ -221,6 +221,21 @@ class CacheTest < ActiveSupport::TestCase
|
|
221
221
|
CSS
|
222
222
|
end
|
223
223
|
|
224
|
+
test '2a new dependency for a glob call is reflected in the next call' do
|
225
|
+
file "dir/a.svg", "<svg>test</svg>"
|
226
|
+
file 'test.scss', 'body { background: image-url("dir/a.svg") }'
|
227
|
+
|
228
|
+
assert_exported_file 'test.css', 'text/css', <<~CSS
|
229
|
+
body{background:url(/assets/dir/a-01a4bd3cb9faa518c5df2d2fcc8e6cd0ba24cfc3e9438dd01455ab1e59a39068.svg)}
|
230
|
+
CSS
|
231
|
+
|
232
|
+
file "dir/a.svg", "<svg>tests</svg>"
|
233
|
+
|
234
|
+
assert_exported_file 'test.css', 'text/css', <<~CSS
|
235
|
+
body{background:url(/assets/dir/a-1d7d038c7ace080963e116cbb962075a38d5e5dc68c6ff688e42d213dd432256.svg)}
|
236
|
+
CSS
|
237
|
+
end
|
238
|
+
|
224
239
|
test 'a dependency is removed for a glob call when one of it dependencies is delted' do
|
225
240
|
file "css/a.scss", "body { color: blue; }"
|
226
241
|
file "css/b.scss", "body { color: green; }"
|
@@ -237,7 +252,7 @@ class CacheTest < ActiveSupport::TestCase
|
|
237
252
|
CSS
|
238
253
|
end
|
239
254
|
|
240
|
-
test 'a dependency is added then changed should flush the parent' do
|
255
|
+
test 'a dependency is added then changed should flush the parent (JS)' do
|
241
256
|
file 'a.js', "console.log('a');\n"
|
242
257
|
file 'b.js', <<~JS
|
243
258
|
export default function b () { console.log('b'); }
|
@@ -265,4 +280,33 @@ class CacheTest < ActiveSupport::TestCase
|
|
265
280
|
!function(){"use strict";console.log("a"),console.log("c")}();
|
266
281
|
JS
|
267
282
|
end
|
283
|
+
|
284
|
+
test 'a dependency is added then changed should flush the parent (CSS)' do
|
285
|
+
file 'a.scss', "body { background: aqua; }"
|
286
|
+
file 'b.scss', <<~JS
|
287
|
+
body { background: blue; }
|
288
|
+
JS
|
289
|
+
|
290
|
+
assert_exported_file 'a.css', 'text/css', <<~JS
|
291
|
+
body{background:aqua}
|
292
|
+
JS
|
293
|
+
|
294
|
+
file 'a.scss', <<~JS
|
295
|
+
@import "b";
|
296
|
+
body { background: aqua; }
|
297
|
+
JS
|
298
|
+
|
299
|
+
assert_exported_file 'a.css', 'text/css', <<~JS
|
300
|
+
body{background:blue}body{background:aqua}
|
301
|
+
JS
|
302
|
+
|
303
|
+
file 'b.scss', <<~JS
|
304
|
+
body { background: green; }
|
305
|
+
JS
|
306
|
+
|
307
|
+
assert_exported_file 'a.css', 'text/css', <<~JS
|
308
|
+
body{background:green}body{background:aqua}
|
309
|
+
JS
|
310
|
+
end
|
311
|
+
|
268
312
|
end
|
data/test/dependency_test.rb
CHANGED
@@ -17,7 +17,7 @@ class DependencyTest < ActiveSupport::TestCase
|
|
17
17
|
JS
|
18
18
|
|
19
19
|
asset = @env.find('name.js')
|
20
|
-
assert_equal asset.instance_variable_get(:@process_dependencies), ["models/*.js","helpers/*.js"]
|
20
|
+
assert_equal asset.instance_variable_get(:@process_dependencies).to_a, ["models/*.js","helpers/*.js"]
|
21
21
|
|
22
22
|
|
23
23
|
assert_file 'name.js', 'application/javascript', <<~JS
|
@@ -54,7 +54,7 @@ class DependencyTest < ActiveSupport::TestCase
|
|
54
54
|
JS
|
55
55
|
|
56
56
|
asset = @env.find('name.js')
|
57
|
-
assert_equal asset.instance_variable_get(:@process_dependencies), ["models/*.js","helpers/*.js"]
|
57
|
+
assert_equal asset.instance_variable_get(:@process_dependencies).to_a, ["models/*.js","helpers/*.js"]
|
58
58
|
|
59
59
|
|
60
60
|
assert_file 'name.js', 'application/javascript', <<~JS
|
data/test/manifest_test.rb
CHANGED
@@ -66,6 +66,40 @@ class ManifestTest < ActiveSupport::TestCase
|
|
66
66
|
assert_equal asset.path, data['application.js']['path']
|
67
67
|
end
|
68
68
|
|
69
|
+
test "compile asset dependencies includes the dependencies" do
|
70
|
+
file 'foo.svg', <<-SVG
|
71
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
72
|
+
<path d="M6 18L18 6M6 6l12 12" />
|
73
|
+
</svg>
|
74
|
+
SVG
|
75
|
+
|
76
|
+
file 'test.scss', <<-SCSS
|
77
|
+
body {
|
78
|
+
background: asset-url("foo.svg");
|
79
|
+
}
|
80
|
+
SCSS
|
81
|
+
|
82
|
+
manifest = Condenser::Manifest.new(@env, File.join(@dir, 'manifest.json'))
|
83
|
+
|
84
|
+
main_digest_path = @env['test.css'].path
|
85
|
+
dep_digest_path = @env['foo.svg'].path
|
86
|
+
|
87
|
+
assert !File.exist?("#{@dir}/#{main_digest_path}")
|
88
|
+
assert !File.exist?("#{@dir}/#{dep_digest_path}")
|
89
|
+
|
90
|
+
manifest.compile('test.css')
|
91
|
+
assert File.directory?(manifest.dir)
|
92
|
+
assert File.file?(manifest.filename)
|
93
|
+
|
94
|
+
assert File.exist?("#{@dir}/manifest.json")
|
95
|
+
assert File.exist?("#{@dir}/#{main_digest_path}")
|
96
|
+
assert File.exist?("#{@dir}/#{dep_digest_path}")
|
97
|
+
|
98
|
+
data = JSON.parse(File.read(manifest.filename))
|
99
|
+
assert_equal main_digest_path, data['test.css']['path']
|
100
|
+
assert_equal dep_digest_path, data['foo.svg']['path']
|
101
|
+
end
|
102
|
+
|
69
103
|
# TODO:
|
70
104
|
# test "compile asset with aliased index links" do
|
71
105
|
# manifest = Sprockets::Manifest.new(@env, File.join(@dir, 'manifest.json'))
|
@@ -4,7 +4,6 @@ class TerserMinifierTest < ActiveSupport::TestCase
|
|
4
4
|
|
5
5
|
def setup
|
6
6
|
super
|
7
|
-
@env.unregister_preprocessor('application/javascript', Condenser::BabelProcessor)
|
8
7
|
@env.unregister_exporter('application/javascript', Condenser::RollupProcessor)
|
9
8
|
@env.register_minifier('application/javascript', Condenser::TerserMinifier)
|
10
9
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class MediaCombinerTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
super
|
7
|
+
@env.register_postprocessor('text/css', Condenser::CSSMediaCombinerProcessor)
|
8
|
+
@env.unregister_minifier('text/css')
|
9
|
+
end
|
10
|
+
|
11
|
+
test 'combine media queries' do
|
12
|
+
file 'main.css', <<~CSS
|
13
|
+
.test{
|
14
|
+
display: block;
|
15
|
+
}
|
16
|
+
@media only screen and (max-width: 100px) {
|
17
|
+
.test {
|
18
|
+
display: inline-block;
|
19
|
+
color: blue;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
@media only screen and (max-width: 500px) {
|
23
|
+
.test {
|
24
|
+
display: inline;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
.test2{
|
29
|
+
display: block;
|
30
|
+
}
|
31
|
+
@media only screen and (max-width: 100px) {
|
32
|
+
.test2 {
|
33
|
+
display: inline-block;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
CSS
|
37
|
+
|
38
|
+
assert_exported_file 'main.css', 'text/css', <<~FILE
|
39
|
+
.test{
|
40
|
+
display: block;
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
.test2{
|
46
|
+
display: block;
|
47
|
+
}
|
48
|
+
@media only screen and (max-width: 100px) {
|
49
|
+
.test {
|
50
|
+
display: inline-block;
|
51
|
+
color: blue;
|
52
|
+
}
|
53
|
+
|
54
|
+
.test2 {
|
55
|
+
display: inline-block;
|
56
|
+
}
|
57
|
+
}@media only screen and (max-width: 500px) {
|
58
|
+
.test {
|
59
|
+
display: inline;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
FILE
|
63
|
+
end
|
64
|
+
|
65
|
+
test 'single line css' do
|
66
|
+
file 'main.css', <<~CSS
|
67
|
+
.test{display: block;} @media only screen and (max-width: 100px) {.test {display: inline-block;}}@media only screen and (max-width: 500px) {.test {display: inline;}}.test2{display: block;}@media only screen and (max-width: 100px) {.test2 {display: inline-block;}}
|
68
|
+
CSS
|
69
|
+
|
70
|
+
assert_exported_file 'main.css', 'text/css', <<~FILE
|
71
|
+
.test{display: block;} .test2{display: block;}@media only screen and (max-width: 100px) {.test {display: inline-block;}.test2 {display: inline-block;}}@media only screen and (max-width: 500px) {.test {display: inline;}}
|
72
|
+
FILE
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
test 'keyframes' do
|
77
|
+
file 'main.css', <<~CSS
|
78
|
+
.trobber {
|
79
|
+
animation: throb 1s infinite;
|
80
|
+
}
|
81
|
+
@keyframes throb {
|
82
|
+
0% {
|
83
|
+
opacity: 1;
|
84
|
+
}
|
85
|
+
100%{
|
86
|
+
opacity: 0;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
CSS
|
90
|
+
|
91
|
+
assert_exported_file 'main.css', 'text/css', <<~FILE
|
92
|
+
.trobber {
|
93
|
+
animation: throb 1s infinite;
|
94
|
+
}
|
95
|
+
@keyframes throb {
|
96
|
+
0% {
|
97
|
+
opacity: 1;
|
98
|
+
}
|
99
|
+
100%{
|
100
|
+
opacity: 0;
|
101
|
+
}
|
102
|
+
}
|
103
|
+
FILE
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
end
|
@@ -79,5 +79,67 @@ class PurgeCSSTest < ActiveSupport::TestCase
|
|
79
79
|
}
|
80
80
|
FILE
|
81
81
|
end
|
82
|
+
|
83
|
+
test 'purge from html with class with /' do
|
84
|
+
file 'main.css', <<~CSS
|
85
|
+
.test{
|
86
|
+
display: block;
|
87
|
+
}
|
88
|
+
.test2-1\\/2{
|
89
|
+
display: inline;
|
90
|
+
}
|
91
|
+
CSS
|
92
|
+
file 'index.html', <<~HTML
|
93
|
+
<div class="test2-1/2"></div>
|
94
|
+
HTML
|
95
|
+
|
96
|
+
assert_exported_file 'main.css', 'text/css', <<~FILE
|
97
|
+
.test2-1\\/2{
|
98
|
+
display: inline;
|
99
|
+
}
|
100
|
+
FILE
|
101
|
+
end
|
102
|
+
|
103
|
+
test 'purge from html with nested tag' do
|
104
|
+
file 'main.css', <<~CSS
|
105
|
+
.test pre{
|
106
|
+
display: block;
|
107
|
+
}
|
108
|
+
CSS
|
109
|
+
file 'index.html', <<~HTML
|
110
|
+
<div class="test">
|
111
|
+
<pre>Test</pre>
|
112
|
+
</div>
|
113
|
+
HTML
|
114
|
+
|
115
|
+
assert_exported_file 'main.css', 'text/css', <<~FILE
|
116
|
+
.test pre{
|
117
|
+
display: block;
|
118
|
+
}
|
119
|
+
FILE
|
120
|
+
end
|
121
|
+
|
122
|
+
test 'purge from html with nested tags' do
|
123
|
+
file 'main.css', <<~CSS
|
124
|
+
code {
|
125
|
+
background: gray;
|
126
|
+
}
|
127
|
+
pre code{
|
128
|
+
background: none;
|
129
|
+
}
|
130
|
+
CSS
|
131
|
+
file 'index.html', <<~HTML
|
132
|
+
<pre><code>Test</code></pre>
|
133
|
+
HTML
|
134
|
+
|
135
|
+
assert_exported_file 'main.css', 'text/css', <<~FILE
|
136
|
+
code {
|
137
|
+
background: gray;
|
138
|
+
}
|
139
|
+
pre code{
|
140
|
+
background: none;
|
141
|
+
}
|
142
|
+
FILE
|
143
|
+
end
|
82
144
|
|
83
145
|
end
|