condenser 1.0.rc1 → 1.0
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/README.md +21 -0
- data/lib/condenser.rb +6 -2
- data/lib/condenser/asset.rb +12 -11
- data/lib/condenser/helpers/parse_helpers.rb +1 -1
- data/lib/condenser/pipeline.rb +3 -1
- data/lib/condenser/processors/babel_processor.rb +10 -0
- data/lib/condenser/processors/js_analyzer.rb +62 -43
- data/lib/condenser/processors/rollup_processor.rb +2 -17
- data/lib/condenser/transformers/jst_transformer.rb +1 -1
- data/lib/condenser/version.rb +1 -1
- data/test/cache_test.rb +25 -0
- data/test/dependency_test.rb +77 -0
- data/test/preprocessor/js_analyzer_test.rb +63 -0
- data/test/transformers/jst_test.rb +67 -0
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24f2e6a83798d231764a5940648a38a65f72c34e55e70e833292397bb98347a8
|
4
|
+
data.tar.gz: 384ceedcef19c3137ad969a255fe8519eb37ac20116c54879ccaa19a05a331c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 906d4e278f46053c31bd55943fab2100468f604aa43472a98993ea71350384abde3b0181f08d8357c814f020c897a359fe496397012a402602f0cdc8777695ae
|
7
|
+
data.tar.gz: f96cfdc8570e74939b71a4257a3b8647495aac682f49cc5a60e39f653367fbf6e73fe77cd5965e1f92b4cab899cf3262be7533158cf4760d2e7e166a244fe0e7
|
data/README.md
CHANGED
@@ -111,6 +111,27 @@ alpha();
|
|
111
111
|
beta();
|
112
112
|
```
|
113
113
|
|
114
|
+
## Directives
|
115
|
+
|
116
|
+
Sometimes you need to tell Condenser that a file depends on other files. For
|
117
|
+
example a `js.erb` file maybe dynamically update depending on the contents of a
|
118
|
+
folder as follows:
|
119
|
+
|
120
|
+
```js
|
121
|
+
console.log([<%= Dir.children("#{asset_path}/models").sort.map(&:inspect).join(', ') %>]);
|
122
|
+
```
|
123
|
+
|
124
|
+
To tell Condenser that this file depends on `models/*` simply add the depends_on
|
125
|
+
directive:
|
126
|
+
|
127
|
+
```js
|
128
|
+
// depends_on models/*.js
|
129
|
+
|
130
|
+
console.log([<%= Dir.children("#{asset_path}/models").sort.map(&:inspect).join(', ') %>]);
|
131
|
+
```
|
132
|
+
|
133
|
+
The directives must be the first portion of the file.
|
134
|
+
|
114
135
|
## Cache
|
115
136
|
|
116
137
|
Compiling assets is slow. It requires a lot of disk use to pull assets off of
|
data/lib/condenser.rb
CHANGED
@@ -36,13 +36,17 @@ class Condenser
|
|
36
36
|
instance_eval(&block)
|
37
37
|
end
|
38
38
|
|
39
|
-
attr_accessor :logger, :digestor
|
39
|
+
attr_accessor :logger, :digestor, :base
|
40
40
|
|
41
|
-
|
41
|
+
# base: If base is passed assets cache_keys will be realitve to this.
|
42
|
+
# This allows deploy systems like Capistrano to take advantage of the
|
43
|
+
# cache even though it precompiles assets in a different folder
|
44
|
+
def initialize(*path, logger: nil, digestor: nil, cache: nil, pipeline: nil, npm_path: nil, base: nil, &block)
|
42
45
|
@logger = logger || Logger.new($stdout, level: :info)
|
43
46
|
@path = []
|
44
47
|
append_path(path)
|
45
48
|
self.npm_path = npm_path
|
49
|
+
@base = base
|
46
50
|
@cache = cache || Cache::MemoryStore.new
|
47
51
|
@build_cc = 0
|
48
52
|
self.digestor = digestor || Digest::SHA256
|
data/lib/condenser/asset.rb
CHANGED
@@ -51,10 +51,6 @@ class Condenser
|
|
51
51
|
[dirname, basename].compact.join('/')
|
52
52
|
end
|
53
53
|
|
54
|
-
def stat
|
55
|
-
@stat ||= File.stat(@source_file)
|
56
|
-
end
|
57
|
-
|
58
54
|
def restat!
|
59
55
|
@stat = nil
|
60
56
|
end
|
@@ -144,13 +140,11 @@ class Condenser
|
|
144
140
|
end
|
145
141
|
|
146
142
|
def cache_key
|
147
|
-
Digest::SHA1.base64digest(JSON.generate([
|
143
|
+
@cache_key ||= Digest::SHA1.base64digest(JSON.generate([
|
148
144
|
Condenser::VERSION,
|
149
145
|
@environment.pipline_digest,
|
150
|
-
@source_file,
|
151
|
-
|
152
|
-
stat.mtime.to_f,
|
153
|
-
stat.size,
|
146
|
+
@environment.base ? @source_file.delete_prefix(@environment.base) : @source_file,
|
147
|
+
Digest::SHA256.file(@source_file).hexdigest,
|
154
148
|
@content_types_digest
|
155
149
|
]))
|
156
150
|
end
|
@@ -160,7 +154,10 @@ class Condenser
|
|
160
154
|
|
161
155
|
f = []
|
162
156
|
all_dependenies(process_dependencies, [], :process_dependencies) do |dep|
|
163
|
-
f << [
|
157
|
+
f << [
|
158
|
+
@environment.base ? dep.source_file.delete_prefix(@environment.base) : dep.source_file,
|
159
|
+
Digest::SHA256.file(dep.source_file).hexdigest
|
160
|
+
]
|
164
161
|
end
|
165
162
|
|
166
163
|
@pcv = Digest::SHA1.base64digest(JSON.generate(f))
|
@@ -171,7 +168,10 @@ class Condenser
|
|
171
168
|
|
172
169
|
f = []
|
173
170
|
all_dependenies(export_dependencies, [], :export_dependencies) do |dep|
|
174
|
-
f << [
|
171
|
+
f << [
|
172
|
+
@environment.base ? dep.source_file.delete_prefix(@environment.base) : dep.source_file,
|
173
|
+
Digest::SHA256.file(dep.source_file).hexdigest
|
174
|
+
]
|
175
175
|
end
|
176
176
|
|
177
177
|
@ecv = Digest::SHA1.base64digest(JSON.generate(f))
|
@@ -180,6 +180,7 @@ class Condenser
|
|
180
180
|
def needs_reprocessing!
|
181
181
|
@processed = false
|
182
182
|
@pcv = nil
|
183
|
+
@cache_key = nil
|
183
184
|
needs_reexporting!
|
184
185
|
end
|
185
186
|
|
@@ -52,7 +52,7 @@ module Condenser::ParseHelpers
|
|
52
52
|
start = (@source.rindex("\n", @old_index) || 0) + 1
|
53
53
|
uptop = @source.index("\n", @index) || (@old_index + @matched.length)
|
54
54
|
lineno = @source[0..start].count("\n") + 1
|
55
|
-
"#{lineno.to_s.rjust(4)}: " + @source[start..uptop] + "\n #{'-'* (@
|
55
|
+
"#{lineno.to_s.rjust(4)}: " + @source[start..uptop] + "\n #{'-'* (@index-1-start)}#{'^'*(@matched.length)}"
|
56
56
|
end
|
57
57
|
|
58
58
|
end
|
data/lib/condenser/pipeline.rb
CHANGED
@@ -39,7 +39,9 @@ class Condenser
|
|
39
39
|
end
|
40
40
|
elsif values.is_a?(Class) || values.is_a?(Module)
|
41
41
|
values.name
|
42
|
-
elsif values.
|
42
|
+
elsif values.is_a?(String)
|
43
|
+
@base ? values.delete_prefix(@base) : values
|
44
|
+
elsif values.nil? || values == true || values == false || values.is_a?(Symbol) || values.is_a?(Integer) || values.is_a?(Float)
|
43
45
|
values
|
44
46
|
else
|
45
47
|
{ values.class.name => pipline_to_json(values.options) }
|
@@ -71,6 +71,16 @@ class Condenser::BabelProcessor < Condenser::NodeProcessor
|
|
71
71
|
# 'inputSourceMap'
|
72
72
|
}.merge(@options).select { |k,v| !v.nil? }
|
73
73
|
|
74
|
+
if match = input[:source].match(/\A(\/\/[^\n]*(\n|\z))*/)
|
75
|
+
directives = match.to_s.split(/\n/).map { |l| l.delete_prefix("//").strip }
|
76
|
+
directives.each do |directive|
|
77
|
+
if directive.start_with?('depends_on')
|
78
|
+
input[:process_dependencies] << directive.sub(/\Adepends_on\s+/, '')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
74
84
|
result = exec_runtime(<<-JS)
|
75
85
|
const babel = require("#{File.join(npm_module_path('@babel/core'))}");
|
76
86
|
const source = #{JSON.generate(input[:source])};
|
@@ -13,14 +13,26 @@ class Condenser::JSAnalyzer
|
|
13
13
|
|
14
14
|
def call(environment, input)
|
15
15
|
seek(0)
|
16
|
+
@sourcefile = input[:source_file]
|
16
17
|
@source = input[:source]
|
17
|
-
@stack = []
|
18
|
-
|
19
|
-
|
20
|
-
input[:export_dependencies] = parse_imports
|
18
|
+
@stack = [:main]
|
21
19
|
|
20
|
+
input[:export_dependencies] ||= []
|
21
|
+
|
22
|
+
scan_until(/\A(\/\/[^\n]*(\n|\z))*/)
|
23
|
+
if matched
|
24
|
+
directives = matched.split(/\n/).map { |l| l.delete_prefix("//").strip }
|
25
|
+
directives.each do |directive|
|
26
|
+
if directive.start_with?('depends_on')
|
27
|
+
input[:process_dependencies] << directive.sub(/\Adepends_on\s+/, '')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
last_postion = nil
|
22
33
|
while !eos?
|
23
34
|
case @stack.last
|
35
|
+
|
24
36
|
when :tick_value
|
25
37
|
scan_until(/(\$\{|\`)/)
|
26
38
|
case matched
|
@@ -29,8 +41,23 @@ class Condenser::JSAnalyzer
|
|
29
41
|
when '${'
|
30
42
|
@stack << :tick_statment
|
31
43
|
end
|
44
|
+
|
45
|
+
when :import
|
46
|
+
scan_until(/[\"\'\`]/)
|
47
|
+
input[:export_dependencies] << case matched
|
48
|
+
when "\""
|
49
|
+
double_quoted_value
|
50
|
+
when "'"
|
51
|
+
single_quoted_value
|
52
|
+
when '`'
|
53
|
+
tick_quoted_value
|
54
|
+
end
|
55
|
+
scan_until(/(;|\n)/)
|
56
|
+
@stack.pop
|
57
|
+
|
32
58
|
else
|
33
|
-
scan_until(/(\/\/|\/\*|\/|\(|\)|\{|\}|\"|\'|\`|export|\z)/)
|
59
|
+
scan_until(/(\/\/|\/\*|\/|\(|\)|\{|\}|\"|\'|\`|export|import|\z)/)
|
60
|
+
|
34
61
|
case matched
|
35
62
|
when '//'
|
36
63
|
scan_until(/(\n|\z)/)
|
@@ -43,8 +70,8 @@ class Condenser::JSAnalyzer
|
|
43
70
|
when '`'
|
44
71
|
@stack << :tick_value
|
45
72
|
when '/'
|
46
|
-
if match_index = @source.rindex(/(\w+|\))\s*\//, @index)
|
47
|
-
match = @source.match(/(\w+|\))\s*\//, match_index)
|
73
|
+
if match_index = @source.rindex(/(\w+|\)|\])\s*\//, @index)
|
74
|
+
match = @source.match(/(\w+|\)|\])\s*\//, match_index)
|
48
75
|
if match[0].length + match_index != @index
|
49
76
|
regex_value
|
50
77
|
end
|
@@ -54,7 +81,7 @@ class Condenser::JSAnalyzer
|
|
54
81
|
when '('
|
55
82
|
@stack.push :parenthesis
|
56
83
|
when ')'
|
57
|
-
raise
|
84
|
+
raise unexptected_token(")") if @stack.last != :parenthesis
|
58
85
|
@stack.pop
|
59
86
|
when '{'
|
60
87
|
@stack.push :brackets
|
@@ -63,48 +90,40 @@ class Condenser::JSAnalyzer
|
|
63
90
|
when :brackets, :tick_statment
|
64
91
|
@stack.pop
|
65
92
|
else
|
66
|
-
raise
|
93
|
+
raise unexptected_token("}")
|
67
94
|
end
|
68
95
|
when 'export'
|
69
|
-
|
70
|
-
|
96
|
+
if @stack.last == :main
|
97
|
+
input[:exports] = true;
|
98
|
+
input[:default_export] = true if next_word == 'default'
|
99
|
+
end
|
100
|
+
when 'import'
|
101
|
+
if @stack.last == :main
|
102
|
+
@stack << :import
|
103
|
+
end
|
71
104
|
else
|
72
105
|
@stack.pop
|
73
106
|
end
|
74
107
|
end
|
108
|
+
|
109
|
+
if last_postion == @index
|
110
|
+
raise Condenser::SyntaxError, "Error parsing JS file with JSAnalyzer"
|
111
|
+
else
|
112
|
+
last_postion = @index
|
113
|
+
end
|
75
114
|
end
|
76
115
|
end
|
77
116
|
|
78
|
-
def
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
else
|
89
|
-
seek(@old_index)
|
90
|
-
@stack << :statment
|
91
|
-
end
|
92
|
-
when :import
|
93
|
-
scan_until(/[\"\'\`]/)
|
94
|
-
imports << case matched
|
95
|
-
when "\""
|
96
|
-
double_quoted_value
|
97
|
-
when "'"
|
98
|
-
single_quoted_value
|
99
|
-
when '`'
|
100
|
-
tick_quoted_value
|
101
|
-
end
|
102
|
-
scan_until(/(;|\n)/)
|
103
|
-
@stack.pop
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
imports
|
117
|
+
def unexptected_token(token)
|
118
|
+
start = (@source.rindex("\n", @old_index) || 0) + 1
|
119
|
+
uptop = @source.index("\n", @index) || (@old_index + @matched.length)
|
120
|
+
lineno = @source[0..start].count("\n") + 1
|
121
|
+
|
122
|
+
message = "Unexpected token #{token} #{@sourcefile} #{lineno.to_s.rjust(4)}:#{(@index-start)}"
|
123
|
+
message << "\n#{lineno.to_s.rjust(4)}: " << @source[start..uptop]
|
124
|
+
message << "\n #{'-'* (@index-1-start)}#{'^'*(@matched.length)}"
|
125
|
+
message << "\n"
|
126
|
+
Condenser::SyntaxError.new(message)
|
108
127
|
end
|
109
128
|
|
110
129
|
def double_quoted_value
|
@@ -112,7 +131,7 @@ class Condenser::JSAnalyzer
|
|
112
131
|
|
113
132
|
while scan_until(/[\"\n]/)
|
114
133
|
if matched == "\n"
|
115
|
-
raise
|
134
|
+
raise unexptected_token("\\n")
|
116
135
|
elsif matched == "\""
|
117
136
|
if pre_match[-1] != "\\"
|
118
137
|
ret_value << pre_match
|
@@ -133,7 +152,7 @@ class Condenser::JSAnalyzer
|
|
133
152
|
|
134
153
|
while scan_until(/[\'\n]/)
|
135
154
|
if matched == "\n"
|
136
|
-
raise
|
155
|
+
raise unexptected_token("\\n")
|
137
156
|
elsif matched == "\'" && pre_match[-1] != "\\"
|
138
157
|
ret_value << pre_match
|
139
158
|
return ret_value
|
@@ -200,34 +200,19 @@ class Condenser::RollupProcessor < Condenser::NodeProcessor
|
|
200
200
|
when 'resolve'
|
201
201
|
importee, importer = message['args']
|
202
202
|
|
203
|
-
|
203
|
+
if importer.nil? && importee == @entry
|
204
204
|
@entry
|
205
205
|
elsif importee.start_with?('@babel/runtime') || importee.start_with?('core-js-pure') || importee.start_with?('regenerator-runtime')
|
206
206
|
x = File.join(npm_module_path, importee.gsub(/^\.\//, File.dirname(importer) + '/')).sub('/node_modules/regenerator-runtime', '/node_modules/regenerator-runtime/runtime.js')
|
207
207
|
x = "#{x}.js" if !x.end_with?('.js')
|
208
208
|
File.file?(x) ? x : (x.delete_suffix('.js') + "/index.js")
|
209
|
-
elsif importer.start_with?(npm_module_path)
|
210
|
-
x = File.expand_path(importee, File.dirname(importer))
|
211
|
-
x = x.end_with?('.js') ? x : "#{x}.js"
|
212
|
-
File.file?(x) ? x : (x.delete_suffix('.js') + "/index.js")
|
213
|
-
elsif npm_module_path &&
|
214
|
-
importer.start_with?(npm_module_path) #&&
|
215
|
-
# File.file?(File.expand_path(importee, File.dirname(importer))) &&
|
216
|
-
# File.file?(File.expand_path(importee, File.dirname(importer)) + '.js')
|
217
|
-
# x = File.expand_path(importee, File.dirname(importer))
|
218
|
-
# x.end_with?('.js') ? x : "#{x}.js"
|
209
|
+
elsif npm_module_path && importer.start_with?(npm_module_path)
|
219
210
|
nil
|
220
211
|
elsif importee.end_with?('*')
|
221
212
|
File.join(File.dirname(importee), '*')
|
222
213
|
else
|
223
214
|
@environment.find(importee, importer ? File.dirname(@entry == importer ? @input[:source_file] : importer) : nil, accept: @input[:content_types].last)&.source_file
|
224
215
|
end
|
225
|
-
# begin
|
226
|
-
asset
|
227
|
-
# rescue Errno::EPIPE
|
228
|
-
# puts io.read
|
229
|
-
# raise
|
230
|
-
# end
|
231
216
|
when 'load'
|
232
217
|
importee = message['args'].first
|
233
218
|
if importee == @entry
|
@@ -26,7 +26,7 @@ class Condenser::JstTransformer < Condenser::NodeProcessor
|
|
26
26
|
function globalVar(scope, name) {
|
27
27
|
if (name in scope.globals) {
|
28
28
|
return true;
|
29
|
-
} else if (scope.parent === null) {
|
29
|
+
} else if (scope.parent === null || scope.parent === undefined) {
|
30
30
|
return false;
|
31
31
|
} else {
|
32
32
|
return globalVar(scope.parent, name);
|
data/lib/condenser/version.rb
CHANGED
data/test/cache_test.rb
CHANGED
@@ -20,6 +20,31 @@ class CacheTest < ActiveSupport::TestCase
|
|
20
20
|
123
|
21
21
|
CSS
|
22
22
|
end
|
23
|
+
|
24
|
+
test 'with a base set and the same cache, the second attempt from another location should use the cache' do
|
25
|
+
@env.base = @path
|
26
|
+
|
27
|
+
file 'test.txt.erb', "1<%= 1 + 1 %>3\n"
|
28
|
+
assert_file 'test.txt', 'text/plain', <<~CSS
|
29
|
+
123
|
30
|
+
CSS
|
31
|
+
|
32
|
+
@new_path = File.realpath(Dir.mktmpdir)
|
33
|
+
@new_env = Condenser.new(@new_path, logger: Logger.new('/dev/null', level: :debug), base: @new_path)
|
34
|
+
@new_env.unregister_writer(Condenser::ZlibWriter)
|
35
|
+
@new_env.unregister_writer(Condenser::BrotliWriter)
|
36
|
+
@new_env.cache = @env.cache
|
37
|
+
FileUtils.cp(File.join(@path, 'test.txt.erb'), File.join(@new_path, 'test.txt.erb'))
|
38
|
+
FileUtils.touch File.join(@new_path, 'test.txt.erb'), mtime: File.stat(File.join(@path, 'test.txt.erb')).mtime
|
39
|
+
|
40
|
+
Condenser::Erubi.stubs(:call).never
|
41
|
+
|
42
|
+
asset = @new_env.find('test.txt')
|
43
|
+
asset.process
|
44
|
+
assert_equal 'test.txt', asset.filename
|
45
|
+
assert_equal ['text/plain'], asset.content_types
|
46
|
+
assert_equal('123'.rstrip, asset.source.rstrip)
|
47
|
+
end
|
23
48
|
|
24
49
|
test 'changing a source file reflects in the next call' do
|
25
50
|
file 'test.txt.erb', "1<%= 1 + 1 %>3\n"
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DependencyTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test 'js file with dependencies processed with BabelPorcessor' do
|
6
|
+
@env.unregister_minifier('application/javascript')
|
7
|
+
|
8
|
+
file 'models/a.js', ''
|
9
|
+
file 'models/b.js', ''
|
10
|
+
|
11
|
+
file 'helpers/a.js', ''
|
12
|
+
|
13
|
+
file 'name.js.erb', <<~JS
|
14
|
+
// depends_on models/*.js
|
15
|
+
// depends_on helpers/*.js
|
16
|
+
console.log([<%= Dir.children("#{@path}/models").sort.map(&:inspect).join(', ') %>]);
|
17
|
+
JS
|
18
|
+
|
19
|
+
asset = @env.find('name.js')
|
20
|
+
assert_equal asset.instance_variable_get(:@process_dependencies), ["models/*.js","helpers/*.js"]
|
21
|
+
|
22
|
+
|
23
|
+
assert_file 'name.js', 'application/javascript', <<~JS
|
24
|
+
// depends_on models/*.js
|
25
|
+
// depends_on helpers/*.js
|
26
|
+
console.log(["a.js", "b.js"]);
|
27
|
+
JS
|
28
|
+
|
29
|
+
file 'models/c.js', ''
|
30
|
+
|
31
|
+
assert_file 'name.js', 'application/javascript', <<~JS
|
32
|
+
// depends_on models/*.js
|
33
|
+
// depends_on helpers/*.js
|
34
|
+
console.log(["a.js", "b.js", "c.js"]);
|
35
|
+
JS
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
test 'js file with dependencies processed with JSAnalzyer' do
|
40
|
+
@env.unregister_preprocessor 'application/javascript', Condenser::BabelProcessor
|
41
|
+
@env.register_preprocessor 'application/javascript', Condenser::JSAnalyzer
|
42
|
+
@env.unregister_minifier('application/javascript')
|
43
|
+
|
44
|
+
file 'models/a.js', ''
|
45
|
+
file 'models/b.js', ''
|
46
|
+
|
47
|
+
file 'helpers/a.js', ''
|
48
|
+
|
49
|
+
file 'name.js.erb', <<~JS
|
50
|
+
// depends_on models/*.js
|
51
|
+
// depends_on helpers/*.js
|
52
|
+
|
53
|
+
console.log([<%= Dir.children("#{@path}/models").sort.map(&:inspect).join(', ') %>]);
|
54
|
+
JS
|
55
|
+
|
56
|
+
asset = @env.find('name.js')
|
57
|
+
assert_equal asset.instance_variable_get(:@process_dependencies), ["models/*.js","helpers/*.js"]
|
58
|
+
|
59
|
+
|
60
|
+
assert_file 'name.js', 'application/javascript', <<~JS
|
61
|
+
// depends_on models/*.js
|
62
|
+
// depends_on helpers/*.js
|
63
|
+
|
64
|
+
console.log(["a.js", "b.js"]);
|
65
|
+
JS
|
66
|
+
|
67
|
+
file 'models/c.js', ''
|
68
|
+
|
69
|
+
assert_file 'name.js', 'application/javascript', <<~JS
|
70
|
+
// depends_on models/*.js
|
71
|
+
// depends_on helpers/*.js
|
72
|
+
|
73
|
+
console.log(["a.js", "b.js", "c.js"]);
|
74
|
+
JS
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -159,6 +159,22 @@ class JSAnalyzerTest < ActiveSupport::TestCase
|
|
159
159
|
assert_empty asset.export_dependencies.map(&:filename)
|
160
160
|
end
|
161
161
|
|
162
|
+
test 'another example file where / as a divisor might get confused as a regex' do
|
163
|
+
file 'name.js', <<~JS
|
164
|
+
row.append(`
|
165
|
+
<td class="text-right">
|
166
|
+
${m(amounts_by_month[month] / 1000, 'USD', {precision: 0})}K
|
167
|
+
</td>
|
168
|
+
`)
|
169
|
+
JS
|
170
|
+
|
171
|
+
asset = @env.find('name.js')
|
172
|
+
assert_nil asset.exports
|
173
|
+
assert_not asset.has_default_export?
|
174
|
+
assert_empty asset.export_dependencies
|
175
|
+
end
|
176
|
+
|
177
|
+
|
162
178
|
test 'x' do
|
163
179
|
file 'test.js', <<-DOC
|
164
180
|
this.$('.pagination').html(`
|
@@ -187,4 +203,51 @@ class JSAnalyzerTest < ActiveSupport::TestCase
|
|
187
203
|
assert_empty asset.export_dependencies.map(&:filename)
|
188
204
|
end
|
189
205
|
|
206
|
+
test 'comments before imports' do
|
207
|
+
file 'a.js', ''
|
208
|
+
|
209
|
+
file 'test.js', <<-DOC
|
210
|
+
/*
|
211
|
+
Availabilities Index
|
212
|
+
*/
|
213
|
+
import template from 'a';
|
214
|
+
|
215
|
+
export default Viking.View.extend({})
|
216
|
+
DOC
|
217
|
+
|
218
|
+
asset = @env.find('test.js')
|
219
|
+
assert asset.exports
|
220
|
+
assert asset.has_default_export?
|
221
|
+
assert_equal ['a.js'], asset.export_dependencies.map(&:filename)
|
222
|
+
|
223
|
+
file 'test.js', <<-DOC
|
224
|
+
// Availabilities Index
|
225
|
+
//
|
226
|
+
import template from 'a';
|
227
|
+
|
228
|
+
export default Viking.View.extend({})
|
229
|
+
DOC
|
230
|
+
|
231
|
+
asset = @env.find('test.js')
|
232
|
+
assert asset.exports
|
233
|
+
assert asset.has_default_export?
|
234
|
+
assert_equal ['a.js'], asset.export_dependencies.map(&:filename)
|
235
|
+
end
|
236
|
+
|
237
|
+
test 'imports interweaved' do
|
238
|
+
file 'a.js', ''
|
239
|
+
file 'b.js', ''
|
240
|
+
|
241
|
+
file 'test.js', <<-DOC
|
242
|
+
import a from 'a';
|
243
|
+
console.log();
|
244
|
+
import b from 'b';
|
245
|
+
DOC
|
246
|
+
|
247
|
+
asset = @env.find('test.js')
|
248
|
+
assert_not asset.exports
|
249
|
+
assert_not asset.has_default_export?
|
250
|
+
assert_equal ['a.js', 'b.js'], asset.export_dependencies.map(&:filename)
|
251
|
+
end
|
252
|
+
|
190
253
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class JSTTransformerTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test 'jst transoformation' do
|
6
|
+
file 'test.jst', <<~SCSS
|
7
|
+
import {escape} from 'ejs';
|
8
|
+
export default function (locals) {
|
9
|
+
var __output = [], __append = __output.push.bind(__output);
|
10
|
+
__append("<div class=\\"uniformLoader\\n");
|
11
|
+
if(typeof transparent != "undefined") {
|
12
|
+
__append(" -transparent");
|
13
|
+
}
|
14
|
+
__append("\\n");
|
15
|
+
if(typeof cover != "undefined") {
|
16
|
+
__append(" -cover");
|
17
|
+
}
|
18
|
+
__append("\\n");
|
19
|
+
if(typeof light != "undefined") {
|
20
|
+
__append(" -light");
|
21
|
+
}
|
22
|
+
__append(" ");
|
23
|
+
__append( klass );
|
24
|
+
__append("\\">\\n <div class=\\"uniformLoader-container\\">\\n <span></span>\\n <span></span>\\n <span></span>\\n </div>\\n</div>");
|
25
|
+
return __output.join("");
|
26
|
+
}
|
27
|
+
SCSS
|
28
|
+
|
29
|
+
assert_file 'test.js', 'application/javascript', <<~JS
|
30
|
+
import _bindInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/bind";
|
31
|
+
import { escape } from 'ejs';
|
32
|
+
export default function (locals) {
|
33
|
+
var _context;
|
34
|
+
|
35
|
+
var __output = [],
|
36
|
+
__append = _bindInstanceProperty(_context = __output.push).call(_context, __output);
|
37
|
+
|
38
|
+
__append("<div class=\\"uniformLoader\\n");
|
39
|
+
|
40
|
+
if (typeof locals.transparent != "undefined") {
|
41
|
+
__append(" -transparent");
|
42
|
+
}
|
43
|
+
|
44
|
+
__append("\\n");
|
45
|
+
|
46
|
+
if (typeof locals.cover != "undefined") {
|
47
|
+
__append(" -cover");
|
48
|
+
}
|
49
|
+
|
50
|
+
__append("\\n");
|
51
|
+
|
52
|
+
if (typeof locals.light != "undefined") {
|
53
|
+
__append(" -light");
|
54
|
+
}
|
55
|
+
|
56
|
+
__append(" ");
|
57
|
+
|
58
|
+
__append(locals.klass);
|
59
|
+
|
60
|
+
__append("\\">\\n <div class=\\"uniformLoader-container\\">\\n <span></span>\\n <span></span>\\n <span></span>\\n </div>\\n</div>");
|
61
|
+
|
62
|
+
return __output.join("");
|
63
|
+
}
|
64
|
+
JS
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: condenser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: '1.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Bracy
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: erubi
|
@@ -342,6 +342,7 @@ files:
|
|
342
342
|
- lib/rake/condensertask.rb
|
343
343
|
- test/cache_stores/file_store_test.rb
|
344
344
|
- test/cache_test.rb
|
345
|
+
- test/dependency_test.rb
|
345
346
|
- test/environment_test.rb
|
346
347
|
- test/manifest_test.rb
|
347
348
|
- test/minifiers/sass_minifier_test.rb
|
@@ -356,6 +357,7 @@ files:
|
|
356
357
|
- test/templates/ejs_test.rb
|
357
358
|
- test/templates/erb_test.rb
|
358
359
|
- test/test_helper.rb
|
360
|
+
- test/transformers/jst_test.rb
|
359
361
|
- test/transformers/scss_test.rb
|
360
362
|
- test/writers/brotli_writer_test.rb
|
361
363
|
- test/writers/zlib_writer_test.rb
|
@@ -363,7 +365,7 @@ homepage: https://github.com/malomalo/condenser
|
|
363
365
|
licenses:
|
364
366
|
- MIT
|
365
367
|
metadata: {}
|
366
|
-
post_install_message:
|
368
|
+
post_install_message:
|
367
369
|
rdoc_options:
|
368
370
|
- "--main"
|
369
371
|
- README.md
|
@@ -376,17 +378,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
376
378
|
version: 2.4.0
|
377
379
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
378
380
|
requirements:
|
379
|
-
- - "
|
381
|
+
- - ">="
|
380
382
|
- !ruby/object:Gem::Version
|
381
|
-
version:
|
383
|
+
version: '0'
|
382
384
|
requirements: []
|
383
|
-
rubygems_version: 3.
|
384
|
-
signing_key:
|
385
|
+
rubygems_version: 3.1.4
|
386
|
+
signing_key:
|
385
387
|
specification_version: 4
|
386
388
|
summary: A Rack-based asset packaging system
|
387
389
|
test_files:
|
388
390
|
- test/cache_stores/file_store_test.rb
|
389
391
|
- test/cache_test.rb
|
392
|
+
- test/dependency_test.rb
|
390
393
|
- test/environment_test.rb
|
391
394
|
- test/manifest_test.rb
|
392
395
|
- test/minifiers/sass_minifier_test.rb
|
@@ -401,6 +404,7 @@ test_files:
|
|
401
404
|
- test/templates/ejs_test.rb
|
402
405
|
- test/templates/erb_test.rb
|
403
406
|
- test/test_helper.rb
|
407
|
+
- test/transformers/jst_test.rb
|
404
408
|
- test/transformers/scss_test.rb
|
405
409
|
- test/writers/brotli_writer_test.rb
|
406
410
|
- test/writers/zlib_writer_test.rb
|