condenser 1.3 → 1.5
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 +103 -25
- data/lib/condenser/build_cache.rb +23 -8
- 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 +23 -1
- data/lib/condenser/manifest.rb +3 -1
- 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 +19 -16
- data/lib/condenser/processors/css_media_combiner_processor.rb +7 -5
- data/lib/condenser/processors/js_analyzer.rb +149 -42
- data/lib/condenser/processors/node_processor.rb +3 -0
- data/lib/condenser/processors/purgecss_processor.rb +2 -0
- data/lib/condenser/processors/rollup_processor.rb +289 -136
- data/lib/condenser/resolve.rb +41 -10
- 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 +115 -20
- data/test/dependency_test.rb +51 -2
- data/test/manifest_test.rb +17 -2
- data/test/postprocessors/css_media_combiner_test.rb +9 -12
- data/test/preprocessor/babel_test.rb +876 -349
- data/test/preprocessor/js_analyzer_test.rb +208 -4
- data/test/processors/rollup/dynamic_import_test.rb +358 -0
- data/test/processors/rollup_test.rb +37 -56
- data/test/resolve_test.rb +14 -9
- data/test/server_test.rb +10 -9
- data/test/test_helper.rb +6 -3
- 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
@@ -1,38 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
require 'tmpdir'
|
3
5
|
|
4
|
-
class Condenser::RollupProcessor
|
6
|
+
class Condenser::RollupProcessor
|
7
|
+
|
8
|
+
@@setup = false
|
5
9
|
|
6
|
-
|
10
|
+
def self.setup(environment)
|
11
|
+
install_npm_packages(environment.npm_path)
|
12
|
+
end
|
7
13
|
|
8
|
-
def
|
9
|
-
|
10
|
-
npm_install('rollup', '@rollup/plugin-commonjs', '@rollup/plugin-node-resolve')
|
14
|
+
def self.install_npm_packages(npm_path)
|
15
|
+
return if @@setup
|
11
16
|
|
12
|
-
|
17
|
+
::Condenser::NodeProcessor.new(npm_path).npm_install(
|
18
|
+
'rollup',
|
19
|
+
'@rollup/plugin-commonjs',
|
20
|
+
'@rollup/plugin-node-resolve',
|
21
|
+
'@rollup/plugin-replace'
|
22
|
+
)
|
23
|
+
@@setup = true
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.call(environment, input)
|
27
|
+
new(environment.npm_path).call(environment, input)
|
28
|
+
end
|
29
|
+
|
30
|
+
def name
|
31
|
+
self.class.name
|
32
|
+
end
|
33
|
+
|
34
|
+
def options
|
35
|
+
{prefix: @prefix, dynamic_imports: @dynamic_imports}
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param prefix [string] string to prefix to the url of dynamic imports
|
39
|
+
# @param imports [symbol] :inline will inline all the imports in the
|
40
|
+
# output file if possible.
|
41
|
+
# false will keep all the imports as imports.
|
42
|
+
# :local will not inline URLS.
|
43
|
+
# @param dynamic_imports [symbol] Default is :local
|
44
|
+
# :inline - Inline dynamic imports into the output file if possible.
|
45
|
+
# :local - Same as :inline except for URLs are kept as URLs
|
46
|
+
# :keep - Keep the dynamic imports but rewrite the import as a URL
|
47
|
+
def initialize(dir = nil, prefix: nil, dynamic_imports: :inline)
|
48
|
+
self.class.install_npm_packages(dir)
|
49
|
+
@npm_dir = dir
|
50
|
+
@prefix = prefix
|
51
|
+
@dynamic_imports = dynamic_imports
|
13
52
|
end
|
14
53
|
|
15
54
|
def call(environment, input)
|
16
|
-
@
|
17
|
-
|
55
|
+
Runner.new(@npm_dir, prefix: @prefix, dynamic_imports: @dynamic_imports).call(environment, input)
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
class Runner < Condenser::NodeProcessor
|
60
|
+
def initialize(dir = nil, prefix: nil, dynamic_imports: :inline)
|
61
|
+
super(dir)
|
62
|
+
@prefix = prefix
|
63
|
+
@dynamic_imports = dynamic_imports
|
64
|
+
end
|
65
|
+
|
66
|
+
def call(environment, input)
|
67
|
+
@environment = environment
|
68
|
+
@input = input
|
69
|
+
|
70
|
+
@input_dir = File.realdirpath(Dir.mktmpdir)
|
71
|
+
@output_dir = File.realdirpath(Dir.mktmpdir)
|
72
|
+
|
73
|
+
@entry = File.join(@input_dir, 'entry.js')
|
18
74
|
|
19
|
-
Dir.mktmpdir do |output_dir|
|
20
|
-
@entry = File.join(output_dir, 'entry.js')
|
21
75
|
input_options = {
|
22
76
|
input: @entry
|
23
77
|
}
|
78
|
+
|
24
79
|
output_options = {
|
25
|
-
|
26
|
-
format: '
|
27
|
-
# output: { sourcemap: true, format: 'iife' },
|
80
|
+
dir: @output_dir,
|
81
|
+
format: 'es',
|
28
82
|
globals: [],
|
29
|
-
sourcemap:
|
83
|
+
sourcemap: false,
|
84
|
+
inlineDynamicImports: true,
|
85
|
+
generatedCode: {
|
86
|
+
arrowFunctions: true,
|
87
|
+
constBindings: true,
|
88
|
+
objectShorthand: true,
|
89
|
+
preset: 'es2015',
|
90
|
+
}
|
30
91
|
}
|
92
|
+
|
31
93
|
if input[:source] =~ /export\s+{[^}]+};?\z/i
|
32
94
|
output_options[:name] = File.basename(input[:filename], ".*").capitalize
|
33
|
-
# output_options[:output][:name] = File.basename(input[:filename], ".*").capitalize
|
34
95
|
end
|
35
|
-
|
96
|
+
|
36
97
|
exec_runtime(<<-JS, @entry)
|
37
98
|
const fs = require('fs');
|
38
99
|
const path = require('path');
|
@@ -73,14 +134,19 @@ class Condenser::RollupProcessor < Condenser::NodeProcessor
|
|
73
134
|
buffer += chunk;
|
74
135
|
buffer = emitMessages(buffer);
|
75
136
|
});
|
76
|
-
|
137
|
+
|
77
138
|
const rollup = require("#{npm_module_path('rollup')}");
|
78
139
|
const commonjs = require("#{npm_module_path('@rollup/plugin-commonjs')}");
|
79
140
|
const nodeResolve = require("#{npm_module_path('@rollup/plugin-node-resolve')}").nodeResolve;
|
141
|
+
const asyncWalk = require("#{npm_module_path('estree-walker')}").asyncWalk;
|
142
|
+
const MagicString = require("#{npm_module_path('magic-string')}");
|
143
|
+
const replace = require("#{npm_module_path('@rollup/plugin-replace')}");
|
144
|
+
|
80
145
|
var rid = 0;
|
81
146
|
var renderStack = {};
|
147
|
+
var dynamicImports = {};
|
82
148
|
var nodeResolver = null;
|
83
|
-
|
149
|
+
|
84
150
|
function request(method, args) {
|
85
151
|
var trid = rid;
|
86
152
|
rid += 1;
|
@@ -107,8 +173,58 @@ class Condenser::RollupProcessor < Condenser::NodeProcessor
|
|
107
173
|
|
108
174
|
const inputOptions = #{JSON.generate(input_options)};
|
109
175
|
inputOptions.plugins = [];
|
110
|
-
|
176
|
+
|
177
|
+
inputOptions.plugins.push(replace({
|
178
|
+
preventAssignment: true,
|
179
|
+
values: {
|
180
|
+
"process.env.NODE_ENV": JSON.stringify("production")
|
181
|
+
}
|
182
|
+
}), {
|
183
|
+
name: 'transform',
|
184
|
+
transform: async function(code, id) {
|
185
|
+
const magicString = new MagicString(code);
|
186
|
+
const ast = this.parse(code, { sourceType: 'module' });
|
187
|
+
|
188
|
+
await asyncWalk(ast, {
|
189
|
+
async enter(node) {
|
190
|
+
if(['ImportExpression'].includes(node.type) && node.source.type == 'Literal') {
|
191
|
+
const asset = await request('resolveDynamicImport', [node.source.value, id]);
|
192
|
+
|
193
|
+
if (asset.export) {
|
194
|
+
dynamicImports[asset.source] = asset;
|
195
|
+
magicString.update(node.source.start, node.source.end, `'${asset.source}'`);
|
196
|
+
} else {
|
197
|
+
dynamicImports[node.source.value] = asset;
|
198
|
+
}
|
199
|
+
} else if (node.type == 'ImportDeclaration' ) {
|
200
|
+
if (node.value == '@arcgis/lumina/controllers') {
|
201
|
+
magicString.update(node.start, node.end, `'@arcgis/components-controllers'`);
|
202
|
+
}
|
203
|
+
}
|
204
|
+
}
|
205
|
+
});
|
206
|
+
|
207
|
+
return {
|
208
|
+
code: magicString.toString(),
|
209
|
+
map: null
|
210
|
+
};
|
211
|
+
}
|
212
|
+
}, {
|
111
213
|
name: 'condenser',
|
214
|
+
resolveDynamicImport: function (importee, importer, options) {
|
215
|
+
const asset = dynamicImports[importee];
|
216
|
+
request('resolve!!!!', [importee, dynamicImports]);
|
217
|
+
|
218
|
+
if (!asset) {
|
219
|
+
return;
|
220
|
+
}
|
221
|
+
|
222
|
+
if (asset.export) {
|
223
|
+
return false;
|
224
|
+
}
|
225
|
+
|
226
|
+
return asset.source;
|
227
|
+
},
|
112
228
|
resolveId: function (importee, importer, options) {
|
113
229
|
if (importee.startsWith('\\0') || (importer && importer.startsWith('\\0'))) {
|
114
230
|
return null;
|
@@ -125,36 +241,32 @@ class Condenser::RollupProcessor < Condenser::NodeProcessor
|
|
125
241
|
return value;
|
126
242
|
});
|
127
243
|
},
|
244
|
+
|
128
245
|
load: function(id) {
|
129
246
|
if (id.startsWith('\\0')) {
|
130
247
|
return null;
|
131
248
|
}
|
132
249
|
|
133
|
-
return request('load', [id])
|
134
|
-
return value;
|
135
|
-
});
|
250
|
+
return request('load', [id]);
|
136
251
|
}
|
137
252
|
});
|
138
|
-
|
253
|
+
|
139
254
|
inputOptions.plugins.push(nodeResolver);
|
140
255
|
inputOptions.plugins.push(commonjs());
|
141
|
-
|
142
|
-
// inputOptions.plugins.push({
|
143
|
-
// name: 'nullHanlder',
|
144
|
-
// resolveId: function (importee, importer, options) {
|
145
|
-
// request('log', [importee, importer, options])
|
146
|
-
// // request('error', ["AssetNotFound", importee, importer, renderStack]).then(function(value) {
|
147
|
-
// // process.exit(1);
|
148
|
-
// // });
|
149
|
-
// }
|
150
|
-
// });
|
151
|
-
|
256
|
+
|
152
257
|
const outputOptions = #{JSON.generate(output_options)};
|
258
|
+
outputOptions.paths = (id) => {
|
259
|
+
const asset = dynamicImports[id];
|
260
|
+
|
261
|
+
if (asset) {
|
262
|
+
return asset.path;
|
263
|
+
}
|
264
|
+
}
|
153
265
|
|
154
266
|
async function build() {
|
155
267
|
try {
|
156
268
|
// inputOptions.cache = await JSON.parse(request('get_cache', []));
|
157
|
-
|
269
|
+
|
158
270
|
const bundle = await rollup.rollup(inputOptions);
|
159
271
|
await bundle.write(outputOptions);
|
160
272
|
// await request('set_cache', [JSON.stringify(bundle)]);
|
@@ -167,134 +279,175 @@ class Condenser::RollupProcessor < Condenser::NodeProcessor
|
|
167
279
|
|
168
280
|
build();
|
169
281
|
JS
|
170
|
-
|
171
|
-
input[:source] = File.read(File.join(output_dir, '
|
282
|
+
|
283
|
+
input[:source] = File.read(File.join(@output_dir, 'entry.js'))
|
172
284
|
input[:source].delete_suffix!("//# sourceMappingURL=result.js.map\n")
|
285
|
+
input[:type] = 'module'
|
173
286
|
# asset.map = File.read(File.join(output_dir, 'result.js.map'))
|
287
|
+
input
|
288
|
+
ensure
|
289
|
+
begin
|
290
|
+
[@input_dir, @output_dir].each { |dir| FileUtils.remove_entry(dir) }
|
291
|
+
rescue Errno::ENOENT
|
292
|
+
end
|
174
293
|
end
|
175
|
-
end
|
176
294
|
|
177
|
-
|
178
|
-
|
179
|
-
|
295
|
+
def exec_runtime(script, input)
|
296
|
+
io = IO.popen([binary, '--max_old_space_size=5120', '-e', script], 'r+')
|
297
|
+
buffer = String.new
|
180
298
|
|
181
|
-
|
299
|
+
begin
|
182
300
|
|
183
|
-
|
184
|
-
|
185
|
-
|
301
|
+
while IO.select([io]) && io_read = io.read_nonblock(1_024)
|
302
|
+
buffer << io_read
|
303
|
+
messages = buffer.split("\n\n")
|
186
304
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
305
|
+
buffer = if buffer.end_with?("\n\n")
|
306
|
+
String.new
|
307
|
+
else
|
308
|
+
messages.pop
|
309
|
+
end
|
192
310
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
311
|
+
messages.each do |message|
|
312
|
+
message = JSON.parse(message)
|
313
|
+
# puts message.inspect
|
314
|
+
ret = case message['method']
|
315
|
+
when 'log'
|
316
|
+
puts message.inspect
|
317
|
+
when 'resolveDynamicImport'
|
318
|
+
importee, importer = message['args']
|
199
319
|
|
200
|
-
|
201
|
-
@entry
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
importee = message['args'].first
|
221
|
-
if importee == @entry
|
222
|
-
{ code: @input[:source], map: @input[:map] }
|
223
|
-
elsif importee.end_with?('*')
|
224
|
-
importees = @environment.resolve(importee, importer ? File.dirname(@entry == importer ? @input[:source_file] : importer) : nil, accept: @input[:content_types].last)
|
225
|
-
code = ""
|
226
|
-
code_imports = [];
|
227
|
-
importees.each_with_index.map do |f, i|
|
228
|
-
if f.has_default_export?
|
229
|
-
code << "import _#{i} from '#{f.source_file}';\n"
|
230
|
-
code_imports << "_#{i}"
|
231
|
-
elsif f.has_exports?
|
232
|
-
code << "import * as _#{i} from '#{f.source_file}';\n"
|
233
|
-
code_imports << "_#{i}"
|
320
|
+
asset = @environment.find(importee, importer ? (@entry == importer ? @input[:source_file] : importer) : nil, accept: @input[:content_types].last, npm: true)
|
321
|
+
asset ||= @environment.find(importee.delete_suffix('.js') + "/index.js", importer ? (@entry == importer ? @input[:source_file] : importer) : nil, accept: @input[:content_types].last, npm: true)
|
322
|
+
asset ||= @environment.find(importee.gsub(/\/[^\/]+$/, '')+ "/dist/index.js", importer ? (@entry == importer ? @input[:source_file] : importer) : nil, accept: @input[:content_types].last, npm: true)
|
323
|
+
|
324
|
+
if asset.source_file == @input[:source_file]
|
325
|
+
{
|
326
|
+
path: File.join("/", *[@prefix, asset.path].compact),
|
327
|
+
# source: File.join(@input_dir, asset.filename),
|
328
|
+
source: @entry,
|
329
|
+
export: false,
|
330
|
+
# filename: asset.filename
|
331
|
+
}
|
332
|
+
else
|
333
|
+
if @dynamic_imports != :inline
|
334
|
+
{
|
335
|
+
path: File.join("/", *[@prefix, asset.path].compact),
|
336
|
+
source: File.join(@input_dir, asset.filename),
|
337
|
+
export: true,
|
338
|
+
filename: asset.filename
|
339
|
+
}
|
234
340
|
else
|
235
|
-
|
341
|
+
{
|
342
|
+
export: false,
|
343
|
+
source: asset.source_file,
|
344
|
+
filename: asset.filename
|
345
|
+
}
|
236
346
|
end
|
237
347
|
end
|
348
|
+
|
349
|
+
when 'resolve'
|
350
|
+
importee, importer = message['args']
|
351
|
+
|
352
|
+
if importer.nil? && importee == @entry
|
353
|
+
@entry
|
354
|
+
elsif importee.start_with?('@babel/runtime') || importee.start_with?('core-js-pure') || importee.start_with?('regenerator-runtime')
|
355
|
+
x = File.join(npm_module_path, importee.gsub(/^\.\//, File.dirname(importer) + '/')).sub('/node_modules/regenerator-runtime', '/node_modules/regenerator-runtime/runtime.js')
|
356
|
+
x = "#{x}.js" if !x.end_with?('.js', '.mjs')
|
357
|
+
File.file?(x) ? x : (x.delete_suffix('.js') + "/index.js")
|
358
|
+
elsif npm_module_path && importee&.start_with?(npm_module_path)
|
359
|
+
x = importee.end_with?('.js', '.mjs') ? importee : "#{importee}.js"
|
360
|
+
x = (x.delete_suffix('.js') + "/index.js") if !File.file?(x)
|
361
|
+
x
|
362
|
+
elsif importee.start_with?('.') && importer.start_with?(npm_module_path)
|
363
|
+
x = File.expand_path(importee, File.dirname(importer))
|
364
|
+
x = "#{x}.js" if !x.end_with?('.js', '.mjs')
|
365
|
+
File.file?(x) ? x : (x.delete_suffix('.js') + "/index.js")
|
366
|
+
elsif importee.end_with?('*')
|
367
|
+
File.join(File.dirname(importee), '*')
|
368
|
+
else
|
369
|
+
asset = @environment.find(importee, importer ? (@entry == importer ? @input[:source_file] : importer) : nil, accept: @input[:content_types].last, npm: true)&.source_file
|
370
|
+
end
|
371
|
+
when 'load'
|
372
|
+
importee = message['args'].first
|
373
|
+
if importee == @entry
|
374
|
+
{ code: @input[:source], map: @input[:map] }
|
375
|
+
elsif importee.end_with?('*')
|
376
|
+
importees = @environment.resolve(importee, importer ? File.dirname(@entry == importer ? @input[:source_file] : importer) : nil, accept: @input[:content_types].last, npm: true)
|
377
|
+
code = String.new
|
378
|
+
code_imports = [];
|
379
|
+
importees.each_with_index.map do |f, i|
|
380
|
+
if f.has_default_export?
|
381
|
+
code << "import _#{i} from '#{f.source_file}';\n"
|
382
|
+
code_imports << "_#{i}"
|
383
|
+
elsif f.has_exports?
|
384
|
+
code << "import * as _#{i} from '#{f.source_file}';\n"
|
385
|
+
code_imports << "_#{i}"
|
386
|
+
else
|
387
|
+
code << "import '#{f.source_file}';\n"
|
388
|
+
end
|
389
|
+
end
|
238
390
|
|
239
|
-
|
391
|
+
code += "export default [#{code_imports.join(', ')}];"
|
240
392
|
|
241
|
-
|
242
|
-
else
|
243
|
-
asset = @environment.find(importee, accept: @input[:content_types].last)
|
244
|
-
if asset
|
245
|
-
{ code: asset.source, map: asset.sourcemap }
|
393
|
+
{ code: code, map: nil }
|
246
394
|
else
|
247
|
-
|
395
|
+
asset = @environment.find(importee, accept: @input[:content_types].last)
|
396
|
+
if asset
|
397
|
+
{ code: asset.source, map: asset.sourcemap }
|
398
|
+
else
|
399
|
+
nil
|
400
|
+
end
|
248
401
|
end
|
249
|
-
|
250
|
-
|
251
|
-
io.write(JSON.generate({rid: message['rid'], return: nil}))
|
402
|
+
when 'error'
|
403
|
+
io.write(JSON.generate({rid: message['rid'], return: nil}))
|
252
404
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
405
|
+
case message['args'][0]
|
406
|
+
when 'AssetNotFound'
|
407
|
+
error_message = "Could not find import \"#{message['args'][1]}\" for \"#{message['args'][2]}\".\n\n"
|
408
|
+
error_message << build_tree(message['args'][3], input, message['args'][2])
|
409
|
+
raise exec_runtime_error(error_message)
|
410
|
+
else
|
411
|
+
raise exec_runtime_error(message['args'][0] + ': ' + message['args'][1])
|
412
|
+
end
|
413
|
+
# when 'set_cache'
|
414
|
+
# @environment.cache.set('rollup', message['args'][0])
|
415
|
+
# io.write(JSON.generate({rid: message['rid'], return: true}))
|
416
|
+
# when 'get_cache'
|
417
|
+
# io.write(JSON.generate({rid: message['rid'], return: [(@environment.cache.get('rollup') || '{}')] }))
|
260
418
|
end
|
261
|
-
|
262
|
-
|
263
|
-
# io.write(JSON.generate({rid: message['rid'], return: true}))
|
264
|
-
# when 'get_cache'
|
265
|
-
# io.write(JSON.generate({rid: message['rid'], return: [(@environment.cache.get('rollup') || '{}')] }))
|
419
|
+
# puts JSON.generate({rid: message['rid'], return: ret})
|
420
|
+
io.write(JSON.generate({rid: message['rid'], return: ret}))
|
266
421
|
end
|
267
|
-
io.write(JSON.generate({rid: message['rid'], return: ret}))
|
268
422
|
end
|
423
|
+
rescue Errno::EPIPE, EOFError
|
269
424
|
end
|
270
|
-
rescue Errno::EPIPE, EOFError
|
271
|
-
end
|
272
425
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
426
|
+
io.close
|
427
|
+
if $?.success?
|
428
|
+
true
|
429
|
+
else
|
430
|
+
raise exec_runtime_error(buffer)
|
431
|
+
end
|
278
432
|
end
|
279
|
-
end
|
280
433
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
434
|
+
def build_tree(renderStack, from, to, visited: nil)
|
435
|
+
visited ||= []
|
436
|
+
return if visited.include?(from)
|
437
|
+
visited << from
|
285
438
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
439
|
+
if renderStack[from].nil? || renderStack[from].empty?
|
440
|
+
nil
|
441
|
+
elsif renderStack[from].include?(to)
|
442
|
+
from
|
443
|
+
else
|
444
|
+
renderStack[from].each do |dep|
|
445
|
+
if tree = build_tree(renderStack, dep, to, visited: visited)
|
446
|
+
return "#{from}\n└ #{tree.lines.each_with_index.map{|l, i| "#{i == 0 ? '' : ' '}#{l}"}.join("")}"
|
447
|
+
end
|
294
448
|
end
|
449
|
+
nil
|
295
450
|
end
|
296
|
-
nil
|
297
451
|
end
|
298
452
|
end
|
299
|
-
|
300
453
|
end
|
data/lib/condenser/resolve.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Condenser
|
2
4
|
module Resolve
|
3
5
|
|
@@ -12,8 +14,14 @@ class Condenser
|
|
12
14
|
@build_cache = BuildCache.new(path, logger: logger)
|
13
15
|
end
|
14
16
|
|
15
|
-
def resolve(filename, base=nil, accept: nil)
|
16
|
-
|
17
|
+
def resolve(filename, base=nil, accept: nil, npm: false)
|
18
|
+
search_path = if npm
|
19
|
+
path + [File.join(npm_path, 'node_modules')]
|
20
|
+
else
|
21
|
+
path
|
22
|
+
end
|
23
|
+
|
24
|
+
filename = filename.delete_prefix("/") if search_path.none? { |p| filename.start_with?(p) }
|
17
25
|
dirname, basename, extensions, mime_types = decompose_path(filename, base)
|
18
26
|
accept ||= mime_types.empty? ? ['*/*'] : mime_types
|
19
27
|
accept = Array(accept)
|
@@ -26,7 +34,7 @@ class Condenser
|
|
26
34
|
results = []
|
27
35
|
|
28
36
|
paths = if dirname&.start_with?('/')
|
29
|
-
if pat =
|
37
|
+
if pat = search_path.find { |pa| dirname.start_with?(pa) }
|
30
38
|
dirname.delete_prefix!(pat)
|
31
39
|
dirname.delete_prefix!('/')
|
32
40
|
[pat]
|
@@ -34,7 +42,7 @@ class Condenser
|
|
34
42
|
[]
|
35
43
|
end
|
36
44
|
else
|
37
|
-
|
45
|
+
search_path
|
38
46
|
end
|
39
47
|
|
40
48
|
paths.each do |path|
|
@@ -48,7 +56,7 @@ class Condenser
|
|
48
56
|
if (basename == '*' || basename == f_basename)
|
49
57
|
if accept == ['*/*'] || mime_type_match_accept?(f_mime_types, accept)
|
50
58
|
asset_dir = f_dirname.delete_prefix(path).delete_prefix('/')
|
51
|
-
asset_basename = f_basename + f_extensions
|
59
|
+
asset_basename = f_basename + f_extensions&.join('').to_s
|
52
60
|
asset_filename = asset_dir.empty? ? asset_basename : File.join(asset_dir, asset_basename)
|
53
61
|
results << build_cache.map("#{asset_filename}@#{f_mime_types.join('')}") do
|
54
62
|
Asset.new(self, {
|
@@ -105,9 +113,9 @@ class Condenser
|
|
105
113
|
end
|
106
114
|
end
|
107
115
|
|
108
|
-
def find(filename, base=nil,
|
116
|
+
def find(filename, base=nil, **kargs)
|
109
117
|
build do
|
110
|
-
resolve(filename, base,
|
118
|
+
resolve(filename, base, **kargs).first
|
111
119
|
end
|
112
120
|
end
|
113
121
|
|
@@ -148,11 +156,34 @@ class Condenser
|
|
148
156
|
end
|
149
157
|
end
|
150
158
|
|
159
|
+
def has_dir?(path)
|
160
|
+
path.count('/') > (path.start_with?('/') ? 1 : 0)
|
161
|
+
end
|
162
|
+
|
163
|
+
def expand_path(path)
|
164
|
+
dir = if path.start_with?('/')
|
165
|
+
File.expand_path(path)
|
166
|
+
else
|
167
|
+
File.expand_path("/#{path}").delete_prefix('/')
|
168
|
+
end
|
169
|
+
dir.empty? ? nil : dir
|
170
|
+
end
|
171
|
+
|
151
172
|
def decompose_path(path, base=nil)
|
152
|
-
dirname = path.
|
153
|
-
|
154
|
-
|
173
|
+
dirname = if base && path.start_with?('.')
|
174
|
+
if has_dir?(base)
|
175
|
+
if has_dir?(path)
|
176
|
+
expand_path(File.join(File.dirname(base), File.dirname(path)))
|
177
|
+
else
|
178
|
+
expand_path(File.dirname(base))
|
179
|
+
end
|
180
|
+
else
|
181
|
+
expand_path(File.dirname(path))
|
182
|
+
end
|
183
|
+
else
|
184
|
+
path.index('/') ? File.dirname(path) : nil
|
155
185
|
end
|
186
|
+
|
156
187
|
|
157
188
|
_, star, basename, extensions = path.match(/(([^\.\/]+)(\.[^\/]+)|\*|[^\/]+)$/).to_a
|
158
189
|
if extensions == '.*'
|