lautis / uglifier

Ruby wrapper for UglifyJS JavaScript compressor.
http://www.rubydoc.info/gems/uglifier
MIT License
613 stars 82 forks source link

Support for processing many input files into one uglified output with map #83

Open cardil opened 9 years ago

cardil commented 9 years ago

Uglifier should support processing of many input files to produce single minified output and source map.

This is original example from latest ugifyjs2 (https://github.com/mishoo/UglifyJS2):

uglifyjs /home/doe/work/foo/src/js/file1.js \
         /home/doe/work/foo/src/js/file2.js \
         -o foo.min.js \
         --source-map foo.min.js.map \
         --source-map-root http://foo.com/src \
         -p 5 -c -m
lautis commented 9 years ago

This would be a nice addition. Let's see what could be done for 3.0.

UglifyJS does not support the use case very well with source maps. Only one input source map is supported (https://github.com/mishoo/UglifyJS2/issues/145), but there is some work towards that in (https://github.com/mishoo/UglifyJS2/pull/706).

One option would be to use the inlined source map comments as suggested in the the UglifyJS issue. I've already done some work to deal with input source maps inlined as data URI comments, but am a bit hesitant to add logic for resolving external source definitions. Then Uglifier also had to deal with potential malicious file access and setting up proxies.

Second option is to use some other utility (like mapcat) to handle the concatenation as an optional preprocessing step. This could even be a separate gem, maybe even implemented in plain Ruby without ExecJS.

And last, we could wait for the support for land to UglifyJS2 master, and figure out an API to give any number of files and source maps as input.

lautis commented 9 years ago

sourcemap allows you to do this quite easily in plain Ruby.

foo = File.read("examples/foo.js")
bar = File.read("examples/bar.js")
foobar = foo + bar

foo_map = SourceMap::Map.from_json File.read("examples/foo.map")
bar_map = SourceMap::Map.from_json File.read("examples/bar.map")
foobar_map = foo_map + bar_map
foobar_map.to_json