condenser 1.0.rc1 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|